2025CISCN&长城杯半决赛 PWN typo详细题解
字数 1167 2025-08-30 06:50:35
2025CISCN&长城杯半决赛 PWN typo 详细题解
漏洞分析
程序功能
程序提供了三个主要功能:
add- 分配堆块free- 释放堆块edit- 编辑堆块内容
漏洞位置
漏洞存在于edit功能中:
- 可以读入0x100个字节到栈上
- 使用
snprintf函数将栈上的数据复制到堆块中 - 存在堆溢出漏洞,但
snprintf会被\x00截断
关键绕过技术
为了绕过\x00截断问题,可以使用格式化字符串技巧:
- 将payload中的
\x00替换为%n$p(例如%39$c) - 寻找偏移为n且数据为0的位置
snprintf解析时会输出0到原来\x00的位置,从而绕过截断
def replace(payload):
return payload.replace(b'\x00',b'%39$c')+b'\x00'
利用思路
1. 泄露libc地址
由于程序保护全开且没有show功能,需要:
- 利用堆溢出合并一个可以进入unsorted bins的堆块
- 在合并前保留一个小堆块在tcache bins中
- 修改main_arena的libc地址最后两位为stdout地址(远程需要爆破)
- 获取libc基址
2. getshell
- 将合并的堆块恢复回去
- 通过修改其中一个堆块的fd的size
- 利用两次修改:
- 第一次修改后面堆块的fd为
free_hook - 第二次修改为
/bin/sh
- 第一次修改后面堆块的fd为
- 最终执行
free触发free_hook执行system("/bin/sh")
详细利用步骤
堆块合并
- 创建特定大小的堆块布局
- 利用堆溢出修改关键size字段
- 触发合并操作使特定堆块进入unsorted bins
泄露libc地址
- 使2号堆块同时位于tcache bins和unsorted bins中
- 修改为
stdout-8(因为edit的读入在bk位) - 通过特定操作泄露libc基址
修改tcache bins
- 修改一个size字段为特定值
- 修改tcache bins中堆块的fd为
free_hook-8 - 分配并写入
/bin/sh字符串 - 修改
free_hook为system地址
EXP编写要点
- 使用格式化字符串绕过
\x00截断 - 精心构造堆布局
- 处理远程爆破情况(stdout地址最后几位)
- 分阶段完成libc泄露和最终利用
调试技巧
- 使用gdb观察堆块合并过程
- 检查unsorted bins和tcache bins状态
- 验证libc地址泄露是否正确
- 确认
free_hook覆盖成功
总结
这道题结合了堆溢出和格式化字符串的技巧,关键点在于:
- 利用
snprintf的特性绕过\x00截断 - 通过堆布局控制实现libc地址泄露
- 利用tcache poisoning修改
free_hook - 需要精确控制堆块的大小和位置关系
通过这种多阶段利用方式,可以在保护全开且没有直接信息泄露功能的情况下完成利用。