# A Firmware Modification Vulnerability During Firmware Update in TP-Link TL-WR741ND and TL-WR740N Wireless Routers
## Affected Products:
We have tested on the following devices:
- TL-WR740N V1 and V2 (firmware version: 3.12.4 and earlier)
- TL-WR741ND V1 and V2 (firmware version: 3.12.4 and earlier)
Also, we suspect it may also work on other models of TL-WR741ND and TL-WR740N series devices.
## Overview:
An exploitable firmware modification vulnerability was discovered on the TP-Link TL-WR741ND and TL-WR740N 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.
## 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 firmware update web interface is shown below.
![](https://i.imgur.com/RIWj4Ku.png)
*Fig. 1. The web interface for firmware update.*
The structure of the 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_100027d0 != 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 a TL-WR741ND V2 (firmware version: 3.12.4) device as an example. In this case, we modified the 4 bytes (offset range: 0xF02 to 0xF05) with value 0xD4813CF9 to 0x00000000. Then we modified the checksum fields in the firmware header, the firmware headers before and after modification are listed below.
![](https://i.imgur.com/ddCGEDJ.png)
*Fig. 2. The original MD5 checksum field in the firmware header.*
*The original firmware header information:*
```
Filename : wr741nv1_en_3_12_4_up(100910).bin
Filesize : 0x003c0000 / 3932160
Image Vendor : TP-LINK Technologies
Image Version : ver. 1.0
Image Size : 0x003c0000 / 3932160
Image Checksum : fc c3 39 58 82 34 69 ce 7b 40 c1 5c e6 c2 f8 08 (Valid)
Product Id : 0x07410001
Product Version : 0x00000001
Firmware Version : 0.0.0
Kernel Offset : 0x00000200 / 512
Kernel Length : 0x000c7c6c / 818284
Kernel Load Address: 0x80002000
Kernel Entry Point : 0x801a4000
Kernel Checksum : 4d 8e b2 8e b2 23 8d d0 c6 66 53 53 81 8e ce db (Not Verified)
Rootfs Offset : 0x00100000 / 1048576
Rootfs Length : 0x002c0000 / 2883584
```
![](https://i.imgur.com/9IFqrk6.png)
*Fig. 3. The modified MD5 checksum field in the firmware header.*
*The modified firmware header information:*
```
Filename : wr741nv1_en_3_12_4_up(100910).bin
Filesize : 0x003c0000 / 3932160
Image Vendor : TP-LINK Technologies
Image Version : ver. 1.0
Image Size : 0x003c0000 / 3932160
Image Checksum : 93 18 89 48 a8 56 9a 37 28 4c 19 2e 40 e1 1c 05 (Valid)
Product Id : 0x07410001
Product Version : 0x00000001
Firmware Version : 0.0.0
Kernel Offset : 0x00000200 / 512
Kernel Length : 0x000c7c6c / 818284
Kernel Load Address: 0x80002000
Kernel Entry Point : 0x801a4000
Kernel Checksum : 4d 8e b2 8e b2 23 8d d0 c6 66 53 53 81 8e ce db (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.