Decrypting TP-Link Smart Switch firmware
I recently acquired a TL-SG2008P and was hoping to do some research on the stock firmware for various reasons (mostly curiosity). Unfortunately, the firmware images made available by TP-Link on their website seemed to be encrypted, so it wasn’t a trivial matter of running binwalk
on the image.
The simpler, but somewhat tedious solution would be to desolder the flash chip from the board and read the unencrypted firmware image from there. However, I didn’t have access to the tooling to do so at the time. Thus, I looked to see if there were other ways to get the unencrypted firmware image.
I figured that whatever encryption mechanism was being used, the key material was likely embedded inside the firmware image itself since the device would need to somehow decrypt the image before flashing it. This presents an issue, since we would need access to the unencrypted firmware image in order to find the decryption key.
The good news is that TP-Link used GPL’d code, and thus has published the source code for their firmware. It looks to be using an extremely old version of Linux (2.6.32!!), and a buildroot root filesystem (overlayed with a custom init script, and TP-Link’s proprietary system binaries). Some of the READMEs suggests that the source code is sufficient to build a full firmware image (albeit unencrypted).
I popped a few of the TP-Link binaries into Ghidra and was able to quickly find that the firmware image was being encrypted using DES-CBC with a hard-coded key + IV.
Incidentally, I found the choice of algorithm interesting. From the fact that an old and known-insecure encryption algorithm was being used with a hard-coded key and IV, I can only conclude that this is merely an obfuscation mechanism intended to prevent casual reverse-engineering of firmware images rather than a serious attempt to protect the contents of the image. Even if the source code wasn’t available, the key and IV can always be dumped from a physical device.
Nonetheless, I will follow the lead of other similar projects, and not directly publish the keying material. Instead, I have included a shell one-liner below to extract the key material from the source code available on TP-Link’s website.
tar -xzf rtk-maple_gpl.tar.gz -O omada_switch/20161108_WebUI_upgrade/tplink/buildroot-realtek/board/realtek/common/skeleton/tplink/lib/libservice.so.0 |\
tee /dev/null |\
od -j 907888 -N 16 -t x1 -A n |\
tr -d '[:space:]' |\
sed -r 's/^([a-f0-9]{16})([a-f0-9]{16})$/Key: \1 IV: \2\n/'
Note: the above is only tested with a rtk-maple_gpl.tar.gz
having the following SHA256 hash: 6941bc1e4b979ecd7bd5c1a4d17f933f525a87e08004cd3efdec218ba581d34e
The firmware can be decrypted using the following OpenSSL command:
openssl des-cbc \
-provider legacy \
-d -nopad \
-K "${KEY?}" -iv "${IV?}" \
-in encrypted.bin \
-out decrypted.bin
It’s also worth noting that knowing the encryption key does not appear to be sufficient for crafting a valid firmware image. I did not confirm this, but the code does appear to perform an RSA signature check before proceeding with flashing a firmware image. It’s also not-yet-clear where this signature is located in the firmware image (likely at the end), but the signature does appear to be 128 bytes in size, suggesting a 1024-bit RSA signing key.
I hope this is useful for anyone hoping to conduct research on these firmware images.