A case of analysing encrypted firmware

    munawwar
    16-April-2020


Introduction

Security analysis of the device firmware is a very crucial part of IoT Security Auditing. Obtaining firmware is amongst the many challenges of the analysis and there are tons of techniques by which you can do that. Once you have the firmware you dissect it for more extensive analysis. But the easiest method of acquiring the firmware of the device is to download it from vendor update server(usually FTP server) where they store the different version of the firmware and the technique to get the next version is coded in the firmware. To defend against this, vendors have started storing the firmware in encrypted form on the server so even if you acquire the firmware you still need to decrypt it before doing any further analysis.

Recently, I came across a very interesting article on ZDI blog where the author shares different techniques to decrypt the firmware, I highly encourage you the read the article. In this post I will walk you through a detailed analysis of firmware decryption of DLINK router DIR-822 US variant, we will use the techniques presented in that ZDI blog and look into the details of how the decryption is handled by the device and reverse engineer the decryption algorithm. So, let get started.

Firmware Diffing technique

In this section, I will summarize the ZDI post for those of you who are lazy enough to not read, and but if you have read it you can skip this section.

Lets, consider a situation where you have the version of the firmware which is encrypted and the algorithm to decrypt the update firmware is in the device firmware. When you upload the firmware it decrypts and it starts the normal update process. But let’s say that this decryption routine was not part of firmware initial factory release and at some later point in time vendor thought of introducing this security mechanism so they coded the new encrypt/decrypt API into the new firmware version. This version can be called as a transition version. Since the transition version is unencrypted we can reverse engineer the decryption algorithm and decrypt the firmware manually. This is precisely what we are going to do in this post.

Binary diffing is the technique where you take two binaries of different version of the same software and use diffing tool to understand the new functionality introduced in the new version of the program. We will use kdiff3 for file-system diffing between transition version and the version before it because in the transition version will have the encryption/decryption routine and the previous version won’t.

Product Details

Before we dive in, let’s look at some of the details of the device.

Product ID DIR-822-US
CPU Architecture MIPS R3000
Description Wireless AC1200 Dual Band Router with High-Gain Antennas
Support Link Link
Download Link

Release History

A brief look at the release history of the router firmware. The table below shows the release date along with the version id and file name on the FTP server.

Release Date Version Code File name
08/02/2020 3.15B02 DIR-822_REVC_FIRMWARE_v3.11B01_ICJG_WW_BETA.zip
03/12/2019 3.15B02 DIR-822_REVC_FIRMWARE_v3.15B02.zip
11/07/2019 3.13B01 DIR-822_REVC_FIRMWARE_v3.13B01.zip
10/05/2019 3.12B04 DIR-822_REVC_FIRMWARE_v3.12B04.zip
22/04/2019 3.11B01 DIR-822_REVC_FIRMWARE_v3.11B01.zip
17/09/2018 FW303WWb04_i4sa_middle DIR822C1_FW303WWb04_i4sa_middle.zip
17/09/2018 3.10B06 DIR-822_REVC_FIRMWARE_v3.10B06.zip
14/09/2017 3.01B02 DIR-822-US_REVC_FIRMWARE_v3.01B02.zip
08/06/2018 3.02B05 DIR-822_REVC_FIRMWARE_v3.02B05.zip

Something seems to be odd about firmware released on 17/09/2018 about firmware FW303WWb04_i4sa_middle. Doing drudgery of unzipping the file and executing binwalk on each of firmware binary file and observing the results for each one of them I made an interesting observation which is all the firmware on and before version FW303WWb04_i4sa_middle binwalk always gave a match for at least couple of lzma compression and squashfs file system. There was no signature match for any firmware after version FW303WWb04_i4sa_middle. On further investigating the release notes pdf found in the zip file DIR822C1_FW303WWb04_i4sa_middle.zip as shown below confirms my suspicions.

DLINK Release Notes

This firmware update is a transition version in which the encryption/decryption was introduced as you can see there was two firmware update for the same date and also in the release note it is mentioned that _The firmware v3.10 must be upgraded from the transitional version of firmware v303WWb04middle. Seems like we have a good lead.

Visualization method

If in some case firmware protection was not mentioned in the release notes you could use the method of entropy calculation to find if the firmware is encrypted or not. In simple terms, entropy is a measure of randomness, it has a value between 0 and 1, higher the value indicates more randomness. A value near one is considered to be high entropy and vice-versa. The data which is compressed or encrypted has high entropy value.

Entropy distribution of the binary image will give us the entropy value of incremental offset of the binary file. This information will help up to guess which part of binary is encrypted/compressed and which is code. Lets look at entropy distribution of two different the binary version, a transition encrypted FW303WWb04_i4sa_middle and encrypted version 3.15B02. Let’s see how are they different from each other.

Encrypted Firmware file

Unencrypted Firmware file

If you have noticed the difference in the graph, Figure B has a nearly constant entropy of above 0.9 which means it is highly likely that it’s encrypted throughout different parts of the firmware. In figure C initial section has low entropy then it is constantly high and then it drops again and rises again this fluctuation suggest that it a mix of code and encrypted/compressed data.

You will often see this pattern for unencrypted firmware which has fluctuating entropy initially and high entropy data in the later section. This could mean that there is code in the initial section of the binary which dynamically decompresses the code(from the later section) during device boots up.

NOTE: Encryption and Compression are both blamed equally here for high entropy as there is no exact way of telling which one of them is responsible for randomness based on entropy value.

Next, we should try to figure out what changes have been made in the new release and try to reverse the algorithm.

File System Analysis

Now that we know the transition version, lets to figure out what changes were introduced in the new version by doing file system diffing between the versions 3.02B05 and FW303WWb04_i4sa_middle. We will use kdiff3 for this purpose. We should be looking for an update in file names which has keywords like “firmware”, “update”, “upgrade”, “download” or combination of these keywords.

Dynamic Analysis of Encryption Binary

Durning the file-diff search you will can across many interesting files related to firmware update functionality but the meat of the matter was residing in file /etc/templates/hnap/StartFirmwareDownload.php on line 111 you will come across the following snippet of code.

// fw encimg
setattr("/runtime/tmpdevdata/image_sign" ,"get","cat /etc/config/image_sign");
$image_sign = query("/runtime/tmpdevdata/image_sign");
fwrite("a", $ShellPath, "encimg -d -i ".$fw_path." -s ".$image_sign." > /dev/console \n");
del("/runtime/tmpdevdata");

From the above code we can deduce that binary called encimg is executed with command encimg -d -i <fw_path> -s <image_sign>. Next, I search for the location of encimg binary in the file system, it was located on path /usr/sbin/encimg other unknown variables are fw_path which I am assuming to be firmware path and another variable is image_sign we can trace back the value of this variable been read from /etc/config/image_sign and there is one more parameter -d which is not clear.

Encryption routine

Let’s do some dynamic analysis to further decipher this command. Running a simple file command revealed that it is an ELF 32-bit MIPS MSB executable. We can now use qemu user-space emulator for MIPS architecture to run this binary. Go to the squashfs-root directory of the firmware and run the following command.

$ qemu-mips -L <rooth path of file system> ./usr/sbin/encimg

Usage: encimg {OPTIONS}
   -h                      : show this message.
   -v                      : Verbose mode.
   -i {input image file}   : input image file.
   -o {output image file}  : output image file.
   -e                      : encode file.
   -d                      : decode file.
   -s                      : signature.

Note: in the above command we provide -L parameter to qemu-mips which specify the path of the root directory to use to load the dependencies. Another method often used is Linux chroot.

From the above help usage message, it is clear that this is the binary used to decrypt the firmware, -s parameter is called signature but I think it is used to take decryption key as a parameter which is read from file /etc/config/image_sign. The file contained string value _wrgac43s_dlink.2015dir822c1, I assume it is the decryption key. Another parameter is -i which is the input file which will be the new received encrypted firmware file. Now let’s try to decrypt the firmware using qemu emulator.

qemu-mips -L . ./usr/sbin/encimg -d -i <path to encrypted firmware> -s wrgac43s_dlink.2015_dir822c1

Qemu user-space emulator also has another interesting and very important functionality from reversing stand-point called strace which does system-call logging made by the binary. You can enable it by providing -starce parameter to qemu it will print all the system call made by the binary, I tried it on the above binary and picked up some interesting logs as shown below.

# Aahh.... a crypto library been loaded by the binary, it
# hints that it is using some sort of encryption algorithm possiblity AES
# or some symentic encryption algorithm as we have seen there already
# a password we provide to the binary.
open("/lib/libcrypto.so.0.9.8", O_RDONLY) = 3
...
...
...
# opening the file (return fd 3)
open("/home/payatu/test_1.bin", O_RDWR) = 3
stat("/home/payatu/test_1.bin", 0x7fffea90) = 0
write(1,0x7f689298,99)The file length of /project/dlink/AC1200/test_1.bin is 6865072
 = 99
read(3,0x7fffeb50,4) = 4
# mmap fd 3
mmap(NULL,6865072,PROT_WRITE,MAP_SHARED,3,0) = 0x7ef51000
munmap(0x7ef51000,6865072) = 0
# again truncate operation on fd 3
ftruncate(3,6865044,0,0,0,0) = 0
# good bye fd 3
close(3) = 0

Reversing Encryption method

You can load encimg binary in your favourite disassembler/decompiler tool to do more in-depth analysis. Wandering around the function section I stumbled upon an interesting function main(0x401244), this method parses the parameter and then calls build(0x400d24) which has all the core functionality of encryption/decryption. Also, there were come crypto relate import done by the binary, some of these functions are _AES_set_encryptkey, _AES_set_decryptkey and _AES_cbcencrypt this confirms that binary is using the AES encryption algorithm which means the same key for encrypting and decrypting the files. Doing some basic research you can manage to understand the function prototype. Here is a short description of those function.

// Same prototype for AES_set_encrypt_key
AES_set_decrypt_key (
   // user input key
   const unsigned char *userKey,
   // size of key
   const int bits,
   // encryption key struct which will be used by
   // encryption function
   AES_KEY *key
)

AES_cbc_encrypt (
   // input buffer
   const unsigned char *in,
   // output buffer
   unsigned char *out,
   // buffer length
   size_t length,
   // key struct return by previous function
   const AES_KEY *key,
   // initializatin vector
   unsigned char *ivec,
   // is encryption or decryption
   const int enc
)

Let’s look at the decompilation code of the build function.

Encryption routine

From the above code, we can say that binary file is mapped into memory with mmap function. It then setups AES_KEY data struct by either calling AES_set_encrypt_key/AES_set_decrypt_key based on parameter and uses that struct to encrypt/decrypt the payload using AES_cbc_encrypt then it writes the data back to the file using munmap function call. Nothing fancy!

Results

Once we have decrypted the firmware. Lets again have look at the entropy of the decrypted firmware.

Entropy of Decrypted Firmware image

It looks very similar to the unencrypted firmware which we saw earlier.

Enumerating Attack Surface

  1. Since we are uploading a binary file to an operating system service(firmware update service) to process the file. We can find bugs in file parsing for used decryption algorithm and compromise the service process through some sort of memory corruption issue which can give us access to the system.
  2. We can use the firmware patching tools like firmware mod-kit to change the firmware file and repackage it and use the same encryption binary to encrypt it and upload the file for update. If there is no method of integrity check, a patched firmware will update without any problem. Despite the use of encryption malicious firmware update remains a problem. The firmware signing mechanism is used to defeat this kind of attack.

Note: I have not tested the above-mentioned attacks, dude to the limitation of time and scope of the project. but this some I would be looking for if I were an attacker.

Firmware Auditor

Doing analysis using ten different tools can be time-consuming and error-prone, reflecting on our daily workflow we have created a tool to automate lots of chores for firmware analysis and the product is called Firmware Auditor and the community edition is free for anyone to use. As you have already seen I use Firmware Auditor for most of the analysis which we did above. you can find more details features about this product on this link and send us your feedback on the same. Firmware Auditor can be used for:

  1. Entropy Graph
  2. Explore the Linux file system and download any contents (enimg binary, PHP file in our case)
  3. Decompiled code of build function
  4. and much more

Conclusion

We saw different methods to find if the firmware is encrypted or not and saw how we can use the method of firmware diffing to find the decryption method be used and how it is used and replicated that method another firmware. We also discussed some of the attack surfaces which decryption methods open up. One needs to be aware of this when using such protection schemes.

EXPLIoT.io

At EXPLIoT.io, we build tools for security testing of Internet of Things (IoT) infrastructure and products.

  1. EXPLIoT: IoT security testing and exploitation framework
  2. Firmware Auditor: a pre-emptive firmware security analysis tool
  3. DIVA [Damn Insecure and Vulnerable Application] Board
  4. NANO: a compact hacker-friendly multi-purpose, multi-protocol hardware tool
  5. ZigBee Auditor

These are products of our years of experience and expertise in the field of IoT security. We are here to help you better your security posture. For more information, visit https://expliot.io or drop us an email at [email protected]!

Reference

  1. MINDSHARE: Dealing With Encrypted Router Firmware
  2. Qemu Userspace Emulation

Research Powered Cybersecurity Services and Training

Close the overlay

I am looking for
Please click one!

Latest news See all news

21-May-2020
Webinar, Online

Visit

Arun Magesh will be delivering a webinar on <em>Introduction to IoT Reversing Firmware</em> and discussing how to get started with IoT pentesting with hands-on.

25-April-2020
Workshop, Online

Visit

Ashfaq Ansari is conducting a workshop to get you started with kernel vulnerability analysis and exploitation in the Android platform.

15-April-2020
Virtual Conference, Online

Visit

Aseem Jakhar will be delivering the talk - “Busting the IoT Security Assessment Blues with Super Powers” at IoXt Alliance Spring Virtual Conference.