漏洞背景
Doyensec安全团队在一次公司活动中,选择了Tenda AC15路由器中的缓冲区溢出漏洞作为挑战目标。该漏洞被标识为CVE-2024-2850(在分析过程中发现实为CVE-2020-13393),最初描述为/goform/saveParentControlInfo端点urls参数的堆溢出。然而,初步分析揭示了文档中的矛盾之处:截图显示数据被复制到malloc分配的堆缓冲区,但文本描述为栈溢出;概念验证(PoC)中使用的参数名称为u而非描述的urls。
环境搭建
由于活动期间网络连接不稳定,团队选择使用EMUX项目来模拟漏洞环境。EMUX是一个基于Docker和QEMU的漏洞利用练习框架,已预置了包括Tenda AC15在内的多个易受攻击的ARM/MIPS固件,并集成了GDB等工具,极大简化了环境配置。
登录路由器管理界面(127.0.0.1:20080,密码ringzer0)后,确认漏洞触发点位于“家长控制”功能。通过Burp Suite捕获到如下请求:
|
|
漏洞定位与分析
通过进程列表和网络连接分析,确认HTTP服务由httpd进程(PID 7382)提供。使用EMUX内置的emuxgdb命令附加调试器。
检查httpd二进制文件的安全属性:
|
|
关键发现:
- NX(不可执行)是唯一启用的防护措施
- 无栈保护(canary)
- 无地址空间布局随机化(ASLR)——通过
/proc/sys/kernel/randomize_va_space确认
使用Ghidra对saveParentControlInfo函数进行反编译分析,发现漏洞实际位于time参数的处理代码段:
|
|
time_from缓冲区位于栈上,大小为32字节,但sscanf的%[^-]格式说明符会持续读取输入直到遇到连字符(-)或空字节,存在明显的栈溢出风险。
漏洞利用开发
1. 控制程序计数器
初始PoC使用大量A字符填充time参数,导致在strcpy调用时因覆盖了其他参数指针而提前崩溃。解决方案是使用有效的指针(指向栈上time_to字符串的地址0xbefff510)填充被覆盖的区域,确保程序能执行到返回指令。
|
|
成功覆盖返回地址后,程序计数器(pc)指向0x42424242(BBBB),证明获得了代码执行控制权。
2. 构建ROP链
目标是执行system()函数运行任意命令。ARM架构下,函数参数通过寄存器传递(r0存放命令字符串指针)。需要解决两个问题:
- 将命令字符串地址加载到
r0 - 跳转到
system()函数地址
使用ropper工具在libc.so中找到了无空字节地址的pop {r0, pc} gadget(0x4023fb80),可一次性完成两个任务。
3. 命令执行
选择通过添加后门用户到/etc/passwd文件来建立持久化访问:
|
|
最终利用负载结构:
|
|
4. 完整利用脚本
|
|
利用CVE-2021-44971认证绕过漏洞,无需有效会话即可发送恶意请求。
攻击验证
执行利用脚本后,成功在目标系统添加后门用户:
|
|
总结与启示
本次漏洞利用过程揭示了多个关键点:
- 文档准确性:原始漏洞公告存在不准确信息,实际漏洞位置与描述不符
- 工具链选择:EMUX等集成化工具极大加速了IoT漏洞研究环境搭建
- 架构特性:ARM架构的
pop {r0, pc}gadget简化了ROP链构建 - 防护绕过:结合认证绕过漏洞(CVE-2021-44971)实现了无需凭证的远程攻击
尽管CVE-2020-13393已有公开记录,但本次开发的PoC可能是首个针对该特定端点的完整利用。这项工作不仅提供了具体的ARM架构利用技术细节,也展示了从漏洞分析到武器化利用的完整方法论。