Tp-Link CPE-510/520 "new" Config.bin structure: Decryption, modify, re-encryption

So far, seems nobody has yet relased a tool to decrypt such kind of config structure.
By doing only static analysis we’ll take a look how to figure out the new TP-Link CPE-510/520  (probably also TP-Link CPE-210/2200 and others) config.bin structure by using Ghidra.
I neither have the CPE :slight_smile:

0 - Hardware overview and firmware extracting
1 - uclited ELF static analysis with Ghidra
  1.1 - config.bin file structure
  1.2 - Extracting decryption key
  1.3 - TP-Link MD5 config signature tricky calculation
2 - config.bin decryption script
3 - Re-creation of a new modified config.bin
4 - Login md5 trick

0 - Hardware overview and firmware extracting

OpenWrt wiki provide us many hardware details:
CPE-510 is based on tipically mips_24kc instruction set, the bootloader is not the well known Uboot, because TP-Link has used their SafeLoader. This will be important later.

Let’s download the TP-Link CPE-510 rev 3.0 firmware and examine it with binwalk:

We’re interested in the squashfs partition, so let’s quickly extract the image by using -e paramenter on binwalk and take a look on what the router once turned on by looking at the rcS script:
Before the httpd, a lower software surface, uclited , is executed.

1 - uclited ELF static analysis with Ghidra

I’m not a Ghidra big fan, but sometimes it’s powerfull, expecially when I have a missing decompiler on IDA Pro. lol.
So, load the ELF on Ghidra and start having fun!

1.1 - config.bin file structure
Before proceeding and examining in ghidra we have to take a look on how the encrypted config.bin looks like:
In the file header there are just a few words in plaintext and at 0x94 (keep it in mind) we have undeadable informations. From my experience, this may be where the encrypted stuff starts.

1.2 - Extracting decryption key

There are several approaches to finding the routine we are interested in.
I’ll skip how to find the routine (it’s too long to write here), so go straight at the routine labled as usrconf_load @ 0x004272d0 which is the decryption config.bin routine.

The routine is almost self explanatory, anyway let’s go over the highlights copared to the config.bin hex:

In the image above:
From 0x0 to 0x3 bytes are the file size. (4 bytes)
Next 0x10 bytes are the MD5 file hash. (0x10 bytes)
From 0x4 to 0x94 are the file header (device info, rev info, and other things). (0x90 bytes)
From 0x94 to EOF is the DES Encrypted data

The DES - ECB  routine  des_min_do(__src + 0x90,size - 0x90,__ptr,0x20000,(const_DES_cblock *)desConfigKey,0); act an encrytion with last paramenter as int 1 or decryption if set 0.

desConfigKey is the pointer to the key: 47 8d a5 0b f9 e3 d2 cf 
We can assume__src + 0x90”  as our file pointer which is moved 4 bytes forward (the bytes of the file size at the beginning of the file)

We have now all the informations we need to decrypt the file.

1.3 - TP-Link MD5 config signature tricky calculation 

In the previous paragraph I deliberately highlighted the MD5 in blue for a specific reason, I do not understand why, but TP-Link do a particular thing in the calculation of the MD5 which will be:
Understanding those steps are esential to recreate the modified file:
1 step: the routine saves the 0x10 bytes readen from file offset 0x4 to 0x14. This is the final md5 that will be compared
2 step: the routine replaces 0x10 bytes with "47 8d a5 0b f9 e3 d2 cf 88 19 83 9d 4c 06 14 45"
3rd step: the routine calculates the md5 from 0x4 to EOF with the first 0x10 bytes shortly before replaced
4 step: the md5 result is compared to the one readen in the original file (saved during the step 1)

2 - config.bin decryption script

dd bs=1 skip=148 if=config.bin of=config_cut.bin 
openssl enc -d -des-ecb -nopad -K 478DA50BF9E3D2CF -in config_cut.bin >compressed.bin
zlib-flate -uncompress config.json
where 148=0x94 do you remember?.. 
the config.json contains all the router informations including the login ones.

3 - Re-creation of a new modified config.bin

You can do it by yourself. Having all the informations you need, you can just recompress the modified .json, encrypt it again with openss, calculate back the new md5 as seen in the 1.3 paragraph and add the current file size + 0x4 and replace the first 4 bytes with the calculated value.

4 - Login md5 trick 
 If you forgot your router login password, in the config you’ll have no plaintext password but the md5(password).
Do you need to brute the plaintext password which generates the corresponding MD5?
Considering that the browser, in local javascript, calculates and send the MD5 to the router, you dont need to waste your time. A firefox Web console is enough to inject the md5 and get the login.


Article Link: