
羊城杯 2025 初赛 - stack

听说你很喜欢栈溢出?
文件属性
属性 | 值 |
---|---|
Arch | amd64 |
RELRO | Full |
Canary | off |
NX | on |
PIE | on |
strip | yes |
libc | 2.35-0ubuntu3.11 |
seccomp rules

解题思路
程序有两个stage,第一个stage会设置seccomp限制,紧接着在第二个stage让用户输入内容到堆上, 随后控制rsp到堆上。观察读入位置和rsp,我们是可以操作栈溢出的。
查找程序内的其他未使用的函数,发现有一个函数能泄露stage 1存放的main
函数的地址。
原先将其乘以了3或4,猜测一下就可以。打印完地址后会继续执行stage 2。
这个函数的开始地址与stage 2返回时的地址(main
函数)只有最后一个字节不同,
第一次输入我们可以使用Partial Write去泄露。
由于printf
内会使用xmm寄存器,因此要求栈对齐,我们可以跳过sub rsp, 8
来保持栈对齐。
为了继续泄露libc,需要寻找一些gadget,然而程序中只有设置rdx的函数,以及pop rax
,
仍然不好泄露。并且在stage 2返回时,rdi还是0,不好调用puts
。我们知道调用函数时,
rdi是可变的,可能某个函数能帮我们设置rdi呢?试试plt中参数不影响运行的函数,
正好rand
函数会设置rdi,然后可以使用puts
来泄露libc。接着再rewind回stage 2。

那么已知libc以后,根据沙箱限制,只要做 openat(AT_FDCWD, "/flag", 0, 0)
和
sendfile(1, 3, NULL, 0x50)
就可以把flag打印出来了。
这道题的环境怪得很,必须要国内网络才能访问,否则无法发送任何内容过去, 其他题都没有这个问题
EXPLOIT
1 | from pwn import * |
- 标题: 羊城杯 2025 初赛 - stack
- 作者: RocketDev
- 创建于 : 2025-10-13 16:24:00
- 更新于 : 2025-10-13 16:24:00
- 链接: https://rocketma.dev/2025/10/13/stack/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论