羊城杯 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 进行许可。
评论