Decrypting An Encrypted Firmware (DIR842)

To download the firmware copy the firmware version shown below from the D-Link FTP SERVER

image.png

unzip the file DIR-842_REVC_FIRMWARE_v3.13B05.zip and run binwalk on the extracted file

┌──(kali㉿kali)-[~/DIR842]
└─$ binwalk DIR842C1_FW313WWb05.bin
 
DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
 

As we can see that our file firmware DIR842C1_FW313WWb05.bin is encrypted.

Now lets Unzip the file DIR-842_REVC_FIRMWARE_v3.10B05.zip and extract the filesystem of DIR842C1_FW302b03_middle.bin using binwalk

┌──(kali㉿kali)-[~/DIR842]                                                                                                                                                                                                        
└─$ sudo binwalk -e --preserve-symlinks --run-as=root DIR842C1_FW302b03_middle.bin
[sudo] password for kali:                                                                                                                                                                                                                  
                                                                                                                                                                                                                                           
DECIMAL       HEXADECIMAL     DESCRIPTION                                                                                                                                                                                                  
--------------------------------------------------------------------------------                                                                                                                                                           
0             0x0             DLOB firmware header, boot partition: "dev=/dev/mtdblock/5"                                                                                                                                                  
112           0x70            uImage header, header size: 64 bytes, header CRC: 0xA33A0532, created: 2018-07-02 07:26:57, image size: 1234680 bytes, Data Address: 0x80060000, Entry Point: 0x80060000, data CRC: 0xE2D6A8D0, OS: Linux, CPU: MIPS, image type: Multi-File Image, compression type: lzma, image name: "MIPS Seattle Linux-3.3.8"                                                                                                                                      
184           0xB8            LZMA compressed data, properties: 0x6D, dictionary size: 8388608 bytes, uncompressed size: 3641936 bytes                                                                                                     
1245296       0x130070        PackImg section delimiter tag, little endian size: 11572736 bytes; big endian size: 9875456 bytes                                                                                                            
1245328       0x130090        Squashfs filesystem, little endian, version 4.0, compression:xz, size: 9872196 bytes, 2533 inodes, blocksize: 131072 bytes, created: 2018-07-02 07:27:09

Go to extracted file system and identify the architecture by using file of it’s busybox binary

┌──(kali㉿kali)-[~/DIR842/_DIR842C1_FW302b03_middle.bin.extracted/squashfs-root]
└─$ file bin/busybox 
bin/busybox: ELF 32-bit MSB executable, MIPS, MIPS32 rel2 version 1 (SYSV), statically linked, stripped

As we can see that the architecture is mips32 . Lets try to run the busybox using qemu-mips-static

 
┌──(kali㉿kali)-[~/DIR842/_DIR842C1_FW302b03_middle.bin.extracted/squashfs-root]
└─$ qemu-mips-static -L . ./bin/busybox 
BusyBox v1.22.1 (2018-07-02 15:18:10 CST) multi-call binary.
BusyBox is copyrighted by many authors between 1998-2012.
Licensed under GPLv2. See source distribution for detailed
copyright notices.
 
Usage: busybox [function [arguments]...]
   or: busybox --list
   or: function [arguments]...
 
        BusyBox is a multi-call binary that combines many common Unix
        utilities into a single executable.  Most people will create a
        link to busybox for each function they wish to use and BusyBox
        will act like whatever it was invoked as.
 
Currently defined functions:
        [, [[, addgroup, adduser, arp, ash, awk, base64, basename, bunzip2, bzcat, bzip2, cat, chmod, chpasswd, cmp, cp, cryptpw, cut, date, dd, delgroup, deluser, dnsdomainname, echo, egrep, expr, false, fgrep, free, grep, gunzip,
        gzip, halt, hostname, ifconfig, ifplugd, init, insmod, ip, ipaddr, iplink, iproute, iprule, iptunnel, kill, killall, killall5, ln, ls, lsmod, mkdir, mknod, mkpasswd, modinfo, modprobe, mount, mv, netstat, passwd, ping, ping6,
        poweroff, ps, pwd, reboot, rm, rmmod, route, sed, sh, sleep, sync, sysctl, tar, test, top, touch, tr, true, tunctl, umount, uname, uptime, vconfig, wc, wget, wget, xargs, yes, zcat
 

Now lets try to find the string decrypt in the squashfs-root using grep

┌──(kali㉿kali)-[~/DIR842/_DIR842C1_FW302b03_middle.bin.extracted/squashfs-root]
└─$ grep -r decrypt
......
grep: usr/sbin/encimg: binary file matches
etc/scripts/decrypt_config.sh:echo "[$filename] decrypt!" > /dev/console

There are many out of which the interesting match is encimg file. lets try to run with qemu-mips-static

┌──(kali㉿kali)-[~/DIR842/_DIR842C1_FW302b03_middle.bin.extracted/squashfs-root]
└─$ qemu-mips-static -L . ./usr/sbin/encimg 
./usr/sbin/encimg: cache '/etc/ld.so.cache' is corrupt
no signature specified!
Usage: encimg {OPTIONS}
   -h                      : show this message.
   -v                      : Verbose mode.
   -i {input image file}   : input image file.
   -e                      : encode file.
   -d                      : decode file.
   -s                      : signature.
 

Copy the the firmware file to squashfs-root directory

┌──(kali㉿kali)-[~/DIR842/_DIR842C1_FW302b03_middle.bin.extracted/squashfs-root]
└─$ sudo cp  ../../DIR842C1_FW313WWb05.bin ./  

Now if we try to run with qemu-mips-static we get an error

┌──(kali㉿kali)-[~/DIR842/_DIR842C1_FW302b03_middle.bin.extracted/squashfs-root]
└─$ sudo qemu-mips-static -L . ./usr/sbin/encimg -d  -i ./DIR842C1_FW313WWb05.bin                                                                                                                                                       
[sudo] password for kali: 
./usr/sbin/encimg: cache '/etc/ld.so.cache' is corrupt
no signature specified!
Usage: encimg {OPTIONS}
   -h                      : show this message.
   -v                      : Verbose mode.
   -i {input image file}   : input image file.
   -e                      : encode file.
   -d                      : decode file.
   -s                      : signature.
 

Now copy the qemu-mips-static to the squashfs-root , use chroot to open up a shell

┌──(kali㉿kali)-[~/DIR842/_DIR842C1_FW302b03_middle.bin.extracted/squashfs-root]
└─$ sudo chroot . ./qemu-mips-static ./bin/sh                                                                                                                                                                                               
 
BusyBox v1.22.1 (2018-07-02 15:18:10 CST) built-in shell (ash)
Enter 'help' for a list of built-in commands.
 
# ls
mnt   home   bin   usr   www   sbin   dev   lib   etc   qemu-mips-static   tmp   DIR842C1_FW313WWb05.bin   sys   htdocs   proc   var
 
# encimg -d -i DIR842C1_FW313WWb05.bin 
no signature specified!
Usage: encimg {OPTIONS}
   -h                      : show this message.
   -v                      : Verbose mode.
   -i {input image file}   : input image file.
   -e                      : encode file.
   -d                      : decode file.
   -s                      : signature.
 

As we can see that when trying to decrypt it says that no signature specified! which means we need the signature in order to decrypt the firmware. Lets try to find the signature. lets search for decrypt string once again.

┌──(kali㉿kali)-[~/DIR842/_DIR842C1_FW302b03_middle.bin.extracted/squashfs-root]
└─$ grep -r decrypt
......
etc/scripts/decrypt_config.sh:echo "[$filename] decrypt!" > /dev/console

Lets try to open up the bash file, as we can see from below image_sign looks interesting

┌──(kali㉿kali)-[~/DIR842/_DIR842C1_FW302b03_middle.bin.extracted/squashfs-root]
└─$ cat etc/scripts/decrypt_config.sh
#!/bin/bash 
sign=`xmldbc -g /runtime/device/image_sign`
tpyrcrsu 4
key=`cat /tmp/imagesign`
for filename in "$@"
do
openssl enc -aes-256-cbc -in $filename -out /var/config_.xml.gz -d -k $key
echo "[$filename] decrypt!" > /dev/console
done

Now if we once again search for string image_sign using grep.

┌──(kali㉿kali)-[~/DIR842/_DIR842C1_FW302b03_middle.bin.extracted/squashfs-root]
└─$ grep -r image_sign
grep: htdocs/cgibin: binary file matches
grep: usr/sbin/rgbin: binary file matches
etc/scripts/dlcfg_hlper.sh:sign=`xmldbc -g /runtime/device/image_sign`
etc/scripts/decrypt_config.sh:sign=`xmldbc -g /runtime/device/image_sign`
etc/defnodes/S20device.xml:                     <image_sign get="cat /etc/config/image_sign" />
etc/defnodes/default_wifi.php:$image_sign = fread("", "/etc/config/image_sign");
etc/defnodes/default_wifi.php:$image_sign = strip($image_sign);
etc/defnodes/default_wifi.php:<<?=$image_sign?>>
etc/defnodes/default_wifi.php:</<?=$image_sign?>> 
etc/init.d/S20init.sh:image_sign=`cat /etc/config/image_sign`
etc/init.d/S20init.sh:xmldb -d -n $image_sign -t > /dev/console 
etc/init0.d/S80mfcd.sh:         image_sign=`cat /etc/config/image_sign`
etc/init0.d/S80mfcd.sh:         mfcd -l /usr/sbin/login -u Alphanetworks:$image_sign -i br0 &
etc/templates/hnap/GetFirmwareValidation.php:   setattr("/runtime/tmpdevdata/image_sign" ,"get","cat /etc/config/image_sign");
etc/templates/hnap/GetFirmwareValidation.php:   $image_sign = query("/runtime/tmpdevdata/image_sign");
etc/templates/hnap/GetFirmwareValidation.php:   setattr("/runtime/tmpdevdata/encimg" ,"get","encimg -d -i ".$fw_path." -s ".$image_sign." > /dev/console \n");
 

We can see an interesting file /etc/config/image_sign , Now if open the file we can see a string wrgac65_dlink.2015_dir842

┌──(kali㉿kali)-[~/DIR842/_DIR842C1_FW302b03_middle.bin.extracted/squashfs-root]
└─$ cat etc/config/image_sign                                                                                                                                                                                                          
wrgac65_dlink.2015_dir842

Now lets input string as signature to decrypt the firmware file.

┌──(kali㉿kali)-[~/DIR842/_DIR842C1_FW302b03_middle.bin.extracted/squashfs-root]
└─$ sudo chroot . ./qemu-mips-static ./bin/sh                                                                                                                                                                                               
 
BusyBox v1.22.1 (2018-07-02 15:18:10 CST) built-in shell (ash)
Enter 'help' for a list of built-in commands.
 
# encimg -s wrgac65_dlink.2015_dir842 -v -d -i ./DIR842C1_FW313WWb05.bin 
The file length of ./DIR842C1_FW313WWb05.bin is 11280544

If we run binwalk we can see various information which means our firmware is decrypted

┌──(kali㉿kali)-[~/DIR842/_DIR842C1_FW302b03_middle.bin.extracted/squashfs-root]
└─$ binwalk DIR842C1_FW313WWb05.bin                                                                                                                                                                                                         
 
DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             DLOB firmware header, boot partition: "dev=/dev/mtdblock/5"
112           0x70            uImage header, header size: 64 bytes, header CRC: 0xA5A9FEC, created: 2019-09-10 02:41:50, image size: 1234827 bytes, Data Address: 0x80060000, Entry Point: 0x80060000, data CRC: 0xAAFF08AD, OS: Linux, CPU: MIPS, image type: Multi-File Image, compression type: lzma, image name: "MIPS Seattle Linux-3.3.8"
184           0xB8            LZMA compressed data, properties: 0x6D, dictionary size: 8388608 bytes, uncompressed size: 3641936 bytes
1245296       0x130070        PackImg section delimiter tag, little endian size: 2136320 bytes; big endian size: 10035200 bytes
1245328       0x130090        Squashfs filesystem, little endian, version 4.0, compression:xz, size: 10032180 bytes, 2560 inodes, blocksize: 131072 bytes, created: 2019-09-10 02:41:56