# A Firmware Modification Vulnerability During Firmware Update in TP-Link TL-WR841N / TL-WR841N Wireless Routers ## Affected Products: We have tested on the following devices: - TP-LINK TL-WR841N / TL-WA841ND V7 (firmware version: 3.13.9 and earlier) Also, we suspect it may also work on other models of TL-WR841N / TL-WA841ND series devices. ## Overview: An exploitable firmware modification vulnerability was discovered on the TP-Link TL-WR841N / TL-WA841ND wireless routers. A specially crafted firmware update image can allow an attacker to bypass the firmware verification in the firmware update process and install a malicious firmware image, thus resulting in either denial-of-service (DoS) or malware or backdoor planting. This vulnerability could be triggered during a user performing a firmware update with a self-uploaded firmware image. During the firmware delivery, the attacker can replace the user-uploaded firmware image with the malicious firmware image. <!-- ![](https://i.imgur.com/SWc6ulB.png) *Fig. 1. The web interface for firmware update.* --> ## Details: When performing a firmware update, users can download a new firmware image from the vendor server and upload it via the web interface of the device. The structure of the uploaded firmware image is [header, bootloader, header, kernel, rootfs]. It is worth noting that each header contains an **MD5 checksum**, which is used to verify the data integrity of the firmware. When a firmware image is uploaded, the web server will calculate the image checksums and compare them with the checksum values in the headers. The decompiled function that is used to verify the firmware image is shown below. ``` undefined4 upgradeFirmware(int param_1,int param_2) { ... if (param_2 - 0x30000U < 0x7d0001) { iVar8 = check_filesize(param_2); if (iVar8 != 0) { iVar8 = isSysUpgradeNeedChecksum(); if (iVar8 != 0) { local_30 = *(undefined4 *)(param_1 + 0x4c); local_2c = *(undefined4 *)(param_1 + 0x50); local_28 = *(undefined4 *)(param_1 + 0x54); local_24 = *(undefined4 *)(param_1 + 0x58); pcVar11 = getMd5Key; if (*(int *)(param_1 + 0x94) != 0) { pcVar11 = getMd5Key_bootloader; } ... iVar8 = md5_verify_digest(&local_30,param_1,param_2); if (iVar8 == 0) { printf("image md5 checksum is not correct!\n\r"); *(undefined4 *)(param_1 + 0x58) = local_24; *(undefined4 *)(param_1 + 0x4c) = local_30; *(undefined4 *)(param_1 + 0x50) = local_2c; *(undefined4 *)(param_1 + 0x54) = local_28; return 0x4655; } *(undefined4 *)(param_1 + 0x50) = local_2c; *(undefined4 *)(param_1 + 0x4c) = local_30; *(undefined4 *)(param_1 + 0x54) = local_28; *(undefined4 *)(param_1 + 0x58) = local_24; } if (((DAT_10002810 != 0) && (iVar8 = isFreeUpdate(), iVar8 == 0)) && ((iVar8 = getProductId(), *(int *)(param_1 + 0x40) != iVar8 || (iVar8 = getProductVer(), *(int *)(param_1 + 0x44) != iVar8)))) { printf("Firmware version check failed"); return 0x4655; } ... } ``` However, the communication during firmware delivery uses the plain HTTP protocol, which does not provide any cryptographic protection of the uploaded contents. Also, there is no signature verification for the update firmware image. Therefore, an attacker with a privileged network position (which could be obtained via ARP spoofing, DNS spoofing, or other approaches) can exploit this issue in order to provide customized malicious firmware updates. Specifically, the attack could replace several bytes in the kernel with arbitrary bytes and replace the checksums in the header after calculating the checksums of the modified firmware image. In this way, a customized malicious firmware image is crafted. During the firmware update process, the attacker can replace the user-uploaded firmware with the crafted firmware, which then causes the device to no longer work or planted with backdoors or malware. The vulnerability has been successfully exploited by creating a proof-of-concept. Take TL-WA841ND V7 (firmware version: 3.13.9) as an example. In this our case, we modified the 4 bytes (address range: 0x700 to 0x703) with value 0xC8E95241 to 0x00000000. Then we modified the checksum fields in the firmware header, the firmware headers before and after modification are listed below. 0F708107 ![](https://i.imgur.com/cb9nbIm.png) *Fig. 2. The original MD5 checksum field in the firmware header.* *The original firmware header information:* ``` Filename : wr841nv7_en_3_13_9_up(120201).bin Filesize : 0x003c0000 / 3932160 Image Vendor : TP-LINK Technologies Image Version : ver. 1.0 Image Size : 0x003c0000 / 3932160 Image Checksum : 73 85 2f 49 b3 bb e2 b3 38 64 be 16 34 14 71 9b (Valid) Product Id : 0x08410007 Product Version : 0x00000001 Firmware Version : 3.13.9 Kernel Offset : 0x00000200 / 512 Kernel Length : 0x000d261c / 861724 Kernel Load Address: 0x80002000 Kernel Entry Point : 0x801bd000 Kernel Checksum : 6d 34 29 84 31 6c 35 9e b1 78 af b5 dc 10 8d 37 (Not Verified) Rootfs Offset : 0x00100000 / 1048576 Rootfs Length : 0x002c0000 / 2883584 ``` --- ![](https://i.imgur.com/ocuhG23.png) *Fig. 3. The modified MD5 checksum field in the firmware header.* *The modified firmware header information:* ``` Filename : wr841nv7_en_3_13_9_up(120201).bin-new Filesize : 0x003c0000 / 3932160 Image Vendor : TP-LINK Technologies Image Version : ver. 1.0 Image Size : 0x003c0000 / 3932160 Image Checksum : 83 50 2e e8 b0 04 ed a7 fd bb cc bf 21 7c 41 77 (Valid) Product Id : 0x08410007 Product Version : 0x00000001 Firmware Version : 3.13.9 Kernel Offset : 0x00000200 / 512 Kernel Length : 0x000d261c / 861724 Kernel Load Address: 0x80002000 Kernel Entry Point : 0x801bd000 Kernel Checksum : 6d 34 29 84 31 6c 35 9e b1 78 af b5 dc 10 8d 37 (Not Verified) Rootfs Offset : 0x00100000 / 1048576 Rootfs Length : 0x002c0000 / 2883584 ``` After replacing the original firmware image with the crafted firmware image during the firmware update procedure, the firmware verification is passed and then the malicious firmware is flashed into the device. Until now, the firmware modification attack is launched successfully.