TP-Link configuration file decrypt
Some routers allow you to save and restore the configuration from a file locally.
This is nice because by saving the configuration, altering the file and uploading it again,
you can change settings not exposed in the interface.
For example, on my D-Link DSL-2640B
I could disable a broken QoS which was slowing down the download speed just by setting X_BROADCOM_COM_ATMEnbQos to FALSE.
When I got a TP-Link wireless access point, I tried the same trick but I’ve found that they started encrypting the configuration file, making it impossible to edit manually.
So I decided to reverse engineer it.
First of all I needed a dump of the filesystem to get the binaries, so I soldered a serial port on the router to access the bootloader.
The bootloader doesn’t allow you to interrupt the boot process but luckily I knew that on those devices you can get a prompt by typing the secret word tpltpltpl.
AP93 (ar7240) U-boot
DRAM:
sri
#### TAP VALUE 1 = 9, 2 = 9
32 MB
id read 0x100000ff
flash size 4194304, sector count = 64
Flash: 4 MB
Using default environment
In: serial
Out: serial
Err: serial
Net: ag7240_enet_initialize...
No valid address in Flash. Using fixed address
: cfg1 0xf cfg2 0x7014
eth0: 00:03:7f:09:0b:ad
eth0 up
No valid address in Flash. Using fixed address
: cfg1 0xf cfg2 0x7214
eth1: 00:03:7f:09:0b:ad
ATHRS26: resetting s26
ATHRS26: s26 reset done
eth1 up
eth0, eth1
Autobooting in 1 seconds
ar7240>
I’ve compiled an OpenWrt initramfs image and loaded it via tftp:
ar7240> tftp 0x81000000 openwrt-ar71xx-generic-tl-wr841n-v8-initramfs-uImage.bin
ar7240> bootm
Booting an initramfs firmware gives you a running Linux system with root access,
but without altering anything on the flash.
At this point it’s possible to dump the root partition and then get it via SSH:
# cat /dev/block/mtd2 >/tmp/rootfs
# scp /tmp/rootfs matteo@192.168.1.2:
The filesystem is an ancient squashfs version, unsupported by modern squashfs tools, so I had to compile an old release to extract it with unsquashfs.
In the extracted filesystem, I located the directory containing the web interface pages.
Looking at the web page which handles the configuration,
I noticed some custom tags that refer to some sort of embedded functions.
Most likely they are handled server-side by the webserver.
The webserver is an “httpd” binary which has many symlinks pointing to it, so it can provide many utilities.
This is a common practice in limited constrained systems, most notably in the BusyBox project.
I started IDA to look at this binary, clearly httpConfUpload was the function to start hacking from.

Given a reference to des_min_do and some strings starting with DES_, I suspected that DES is the cipher used to encrypt the file.
Furthermore, it has a lot of bitwise operators and loops, common for cryptographic functions:

Before calling this function, a pointer to a constant null-terminated string is pushed onto the stack. It could be some salt or key passed to the encryption function as an argument so I noted this string which was 478DA50BF9E3D2CF.

I tried to decrypt it with mdecrypt using that string as key but without success:
$ mdecrypt -b -a des -f key <config.bin
I looked again at the binary and, searching for the _des string, I found md5_des which led me to use the md5 hash function:
$ mdecrypt -b -a des -f key -o mcrypt-md5 <config.bin
Again no luck, so I tried all the block modes available until I found that the correct one was ecb:
$ mdecrypt -b -a des -m ecb -f key -o mcrypt-md5 <config.bin
????????????????lan_ip 192.168.1.254
lan_msk 255.255.255.0
lan_gateway 0.0.0.0
The file is decrypted! The garbage before the plain text is the md5 of the file, if I calculate it with my hex editor it matches:

The same can be done with openssl:
$ openssl enc -d -des-ecb -nopad -K 478DA50BF9E3D2CF -in config.bin
I succeeded in decrypting the TP-Link configuration file, now it’s possible to edit it manually.
Have fun!