TP-Link Archer系列路由器是普联(TP-Link)公司的无线路由产品。TP-Link Archer A7/C7 (AC1750)的MIPS架构、固件版本为190726的路由器,其tdpServer服务存在命令注入漏洞,LAN侧的未授权攻击者可利用漏洞以root权限进行任意代码执行。该漏洞由Flashback团队(Pedro Ribeiro + Radek Domanski)在Pwn2Own Tokyo 2019活动中发现。
在TP-Link官网可下载对应版本固件:c25K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6K6N6r3q4@1K9h3y4Q4x3X3g2@1M7q4)9J5k6r3I4A6L8X3E0Q4x3X3g2U0L8$3#2Q4x3V1j5J5x3o6p5&6i4K6u0r3x3U0l9I4z5e0l9^5i4K6u0r3x3U0l9I4z5e0l9^5x3e0k6Q4x3V1k6m8M7X3y4Z5k6i4u0Q4x3U0f1J5x3p5x3%4i4K6t1^5g2g2y4Q4x3U0W2Q4y4h3k6h3y4g2)9#2k6U0p5&6x3o6M7J5y4W2)9J5k6i4A6A6M7q4!0q4c8W2!0n7b7#2)9^5b7#2!0q4y4g2!0n7x3q4)9&6c8q4!0q4z5q4!0m8c8W2)9&6y4g2!0q4y4q4!0n7c8q4!0n7c8W2!0q4y4#2)9&6y4q4!0m8z5r3k6A6M7X3#2S2k6s2W2F1k6g2!0q4y4g2!0n7y4#2!0m8y4g2!0q4y4g2)9^5y4g2!0n7y4#2!0q4z5q4!0n7c8W2)9&6x3q4!0q4z5q4!0m8x3g2)9^5b7#2!0q4y4g2)9&6b7W2!0n7b7g2!0q4y4q4!0n7b7W2!0n7y4W2!0q4c8W2!0n7b7#2)9&6b7b7`.`.

但发现网络分配步骤失败:

进而运行时报错:

使用Qemu MIPS虚拟机加载固件运行,找到目标文件tdpServer并尝试执行:


发现执行出错。分析固件仿真启动和执行tdpServer失败的原因,估计是因为路由器在启动中,部分调用资源在其他硬件flash中,因而缺少资源导致失败,最好的方式不过为购买一台TP-Link Archer A7进行试验了。
tdpServer守护进程在本地0.0.0.0接口的UPD 20002端口监听,为TP-Link移动应用程序对路由器建立控制提供基础,守护进程与应用程序之间通过使用带有加密payload的UDP数据包通信,逆向分析得到数据包格式如下:

数据包的格式决定了守护进程提供的服务,例如type为0,守护进行将提供tdpd服务,使用特定的TETHER_KEY哈希值的数据包进行回复,但此处与漏洞无关;type为0xf0, 守护进行将提供onemesh服务, onemesh在许多TP-Link新固件中均引入了该项新技术,具体可参考( 900K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2@1M7q4)9J5k6r3I4A6L8X3E0Q4x3X3g2U0L8$3#2Q4x3V1k6#2M7#2)9J5c8X3!0F1k6h3#2W2M7$3S2Q4x3V1k6U0L8$3#2H3j5i4c8A6j5X3W2D9K9i4c8&6i4K6u0r3i4K6t1&6i4@1f1K6i4K6R3H3i4K6R3J5
设备启动后,函数调用顺序为:tdpd_pkt_handler_loop()(地址:0x40d164)->监听端口20002接收到数据传递->tpdp_pkt_parser()(地址:0x40cfe0),tpdp_pkt_parser()函数伪码如下:
undefined4 FUN_0040cfe0(int iParm1,int iParm2,int iParm3,int *piParm4,int param_5)
{
byte bVar1;
uint uVar2;
undefined2 uVar5;
__pid_t _Var3;
int iVar4;
uint uVar6;
char *pcVar7;
char *pcVar8;
int local_c8 [42];
ushort local_20 [2];
int local_1c;
int local_18;
if (iParm1 != 0) {
iVar4 = FUN_0040d600();
if (iParm2 < iVar4) {
FUN_00403734("tdpdServer.c:709","recvbuf length = %d, less than hdr\'s 16",iParm2);
return 0xffffffff;
}
iVar4 = FUN_0040d620(iParm1);
if (iVar4 < 1) {
pcVar7 = "tdpdServer.c:716";
pcVar8 = "tdp pkt is too big";
}
else {
FUN_00403734("tdpdServer.c:719","tdp pkt length is %d",iVar4);
iVar4 = FUN_0040c9d0(iParm1,iVar4);
if (iVar4 < 0) {
return 0xffffffff;
}
if (*(char *)(iParm1 + 1) == 0) {
local_20[0] = 0;
if (iParm1 != 0) {
if (iParm3 == 0) {
return 0xffffffff;
}
if (piParm4 != (int *)0x0) {
bVar1 = *(byte *)(iParm1 + 6);
uVar2 = 1;
if ((bVar1 & 0x10) == 0) {
uVar2 = ((uint)bVar1 << 0x1a) >> 0x1f;
}
uVar6 = (uint)bVar1 & 1;
if (uVar2 == 0) {
uVar6 = 0;
}
if (uVar6 == 0) {
pcVar7 = "tdpdServer.c:837";
pcVar8 = "TDP flag error";
}
else {
if (*(short *)(iParm1 + 2) == 2) {
local_1c = 0;
local_18 = 0;
iVar4 = pipe((int *)&stack0xffffffe4);
if (iVar4 < 0) {
if (0 < local_1c) {
close(local_1c);
}
if (local_18 < 1) {
return 0xffffffff;
}
close(local_18);
return 0xffffffff;
}
_Var3 = fork();
if (_Var3 == -1) {
return 0xffffffff;
}
if (_Var3 == 0) {
close(local_1c);
local_20[0] = FUN_0040b804((void *)(iParm3 + 0x10),param_5);
write(local_18,local_20,2);
write(local_18,(void *)(iParm3 + 0x10),(uint)local_20[0]);
close(local_18);
/* WARNING: Subroutine does not return */
exit(0);
}
close(local_18);
wait((void *)0x0);
read(local_1c,local_20,2);
read(local_1c,(void *)(iParm3 + 0x10),(uint)local_20[0]);
close(local_1c);
uVar5 = *(undefined2 *)(iParm1 + 2);
}
else {
local_20[0] = FUN_0040b7d8(iParm3 + 0x10);
uVar5 = *(undefined2 *)(iParm1 + 2);
}
*(undefined2 *)(iParm3 + 2) = uVar5;
*(byte *)(iParm3 + 6) = *(byte *)(iParm1 + 6) & 0xfe | 2;
*(undefined *)(iParm3 + 7) = 1;
*(ushort *)(iParm3 + 4) = local_20[0];
*(undefined4 *)(iParm3 + 8) = *(undefined4 *)(iParm1 + 8);
iVar4 = FUN_0040cb20(iParm3);
if (-1 < iVar4) {
*piParm4 = iVar4;
return 0;
}
pcVar7 = "tdpdServer.c:844";
pcVar8 = "TDP encode pkt error";
}
FUN_00403734(pcVar7,pcVar8);
}
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课