SUCTF 2026
SU_evbuffer


服务器???
开了8888和8889两个监听端口

socket(2->ipv4,2->UDP,0)

UDP监听,8889


TCP监听,8888
tcp由于稳定大多用于核心业务,udp则是发个小数据包看看服务器在不在之类的
总之udp要的是快,tcp要稳(我在说什么废话)
无论数据从哪个端口进入,最终都会汇聚到 sub_13A4 函数进行处理

sub_12E5开了个seccomp
ban了59和322系统调用


exe是不行了,但是可以orw或者mprotect,sendfile

回调函数sub_1630
我们先看看UDP的callback function

看看sub_1344

看看sub_1318

free(ptr)

malloc(0x50)


leak一下




get libc_base
刚才的不行,我们改一下主机名再看看其它leak的指针
不太得劲,我得换个想法
Obviously, the challenge is fixed with utilization of heap and web server
we also need to learn the structure of libevent

In remote, the hostname is ‘pwn’

难道这leak的addr是完全随机的???

s只有0x70

UDP的回调函数
| sub_1630 参数 | 来源 (从 event_new 传入) | 具体含义 |
|---|---|---|
**<font style="color:rgb(68, 71, 70);">fd</font>** |
<font style="color:rgb(68, 71, 70);">fd</font> |
触发事件的文件描述符(即 8889 端口的 UDP Socket)。 |
**<font style="color:rgb(68, 71, 70);">a2</font>** |
<font style="color:rgb(68, 71, 70);">18LL</font>(0x12) |
触发的事件类型。<font style="color:rgb(68, 71, 70);">18</font>是 `EV_READ (0x02) |
**<font style="color:rgb(68, 71, 70);">dest_1</font>** |
**<font style="color:rgb(68, 71, 70);">&s_</font>** |
用户自定义参数。在 <font style="color:rgb(68, 71, 70);">main</font>中传入的是全局变量 <font style="color:rgb(68, 71, 70);">s_</font>的地址。 |

可以接收0x3ff=1023到buf,但buf有1032字节,没有overflow
addr_len = 16是地址长度,ipv4正好是16
看看sub_13a4


dest ->s
s = 0x70
n_max = 1023
也就是说,我们可以覆盖s开始的1023数据

**dest + 32**:对应结构体中的某个标志位。**dest + 40**:对应一个bufferevent指针
可以通过memcpy set dest+32 ==1 and dest+40-> pointer

看看tcp



unk_4078在s_高地址

从 TCP 连接(bufferevent)中读取最多 1023 字节到栈缓冲区 src
dest 传入的是 **&unk_4078**

| 地址 (BSS) | 角色 | 状态 |
|---|---|---|
**<font style="color:rgb(68, 71, 70);">0x4040</font>** |
<font style="color:rgb(68, 71, 70);">s_</font> |
最佳的 Fake Object 放置点(可以通过 UDP 提前布置)。 |
**<font style="color:rgb(68, 71, 70);">0x4078</font>** |
<font style="color:rgb(68, 71, 70);">unk_4078</font> |
TCP 状态结构体。 |
**<font style="color:rgb(68, 71, 70);">0x4098</font>** |
<font style="color:rgb(68, 71, 70);">unk_4078 + 32</font> |
必须为 <font style="color:rgb(68, 71, 70);">1</font>才能进入漏洞分支。 |
**<font style="color:rgb(68, 71, 70);">0x40A0</font>** |
<font style="color:rgb(68, 71, 70);">unk_4078 + 40</font> |
劫持目标(指向伪造对象的指针)。 |
| 绝对地址 | 相对 0x4040 偏移 | 变量含义 | 攻击侧重点 |
|---|---|---|---|
<font style="color:rgb(68, 71, 70);">0x4040</font> |
<font style="color:rgb(68, 71, 70);">+0x00</font> |
UDP 结构 <font style="color:rgb(68, 71, 70);">s_</font>首地址 |
Payload 起点,也是放置 Fake Object 的好地方。 |
<font style="color:rgb(68, 71, 70);">0x4070</font> |
<font style="color:rgb(68, 71, 70);">+0x30</font> |
UDP 监听 <font style="color:rgb(68, 71, 70);">fd</font> |
覆盖时需注意,如果填入无效值会导致后续 UDP 发送失败。 |
<font style="color:rgb(68, 71, 70);">0x4078</font> |
<font style="color:rgb(68, 71, 70);">+0x38</font> |
TCP 结构 <font style="color:rgb(68, 71, 70);">unk_4078</font> |
被溢出淹没的目标结构体。 |
<font style="color:rgb(68, 71, 70);">0x4098</font> |
<font style="color:rgb(68, 71, 70);">+0x58</font>(即 <font style="color:rgb(68, 71, 70);">+32</font>) |
Flag 位 | 必须被覆盖为 **<font style="color:rgb(68, 71, 70);">1</font>**,以通过 <font style="color:rgb(68, 71, 70);">sub_13A4</font>的条件检查。 |
<font style="color:rgb(68, 71, 70);">0x40A0</font> |
<font style="color:rgb(68, 71, 70);">+0x60</font>(即 <font style="color:rgb(68, 71, 70);">+40</font>) |
<font style="color:rgb(68, 71, 70);">bufferevent</font>指针 |
核心劫持点。需要将其覆盖为你伪造的结构体地址(例如 <font style="color:rgb(68, 71, 70);">0x4040</font>)。 |
after hijeck the 0x40a0,

- 获取 output 缓冲区 (解引用你伪造的指针)
output = bufferevent_get_output(*(_QWORD *)(dest + 40));
- 将新分配的堆块 s 挂载到 output 上
evbuffer_add_reference(output, (__int64)s, 80LL, (_int64)free, 0LL);
我们再看看evbuffer_add_reference()函数是干什么的

ok,分析得差不多了
总结一下思路
通过UDP memcpy payload into 0x4040(s_),伪造结构体放ROP(orw),fd,\x90,dest+32=1,*bufferevent->we need pointer
先连 TCP8888。触发 sub_16EA,在 BSS 的 0x4078 生成一个合法的状态结构体
然后用UDP发payload
大致如此

主机名不能太长,不然会出现奇怪的问题
sudo hostnamectl set-hostname shark
用这个改

wc ,拉个docker更稳定

环境问题还是太神奇了

这才对吗,没想到系统版本还会影响数据泄露(今天是跟evbuffer瞪眼的第5天)

我们看看udp和tcp都泄露了什么

we get pie in udp

the libevent_base in tcp

ok
我们看看libevent有什么用


给题目给的libe改一下名,再patchelf,当然直接用本机的libe也是可以的

libe里面还真有gadgets


pwndbg太好用了你知道吗




我还发现了一个问题

多了0x4

ok
1 | |

wc,终于成了