如何构造Pwntools Payload绕过strcmp检测实现二进制缓冲区溢出
缓冲区溢出篡改判断条件的解决思路
核心目标
把栈上local_j的内容从初始的perd(小端字节0x70 0x65 0x72 0x64)改成gagne(带字符串终止符\0),让strcmp返回0,触发win函数。
关键步骤
计算缓冲区到
local_j的偏移量- 直接看Ghidra栈布局:找到输入缓冲区(比如
char buf[N])和local_j在栈上的地址差,比如缓冲区起始地址是ebp-0x48,local_j是ebp-0x8,偏移量就是0x48 - 0x8 = 0x40(即64字节)。 - 用cyclic pattern测试:生成一串唯一字符串(比如
cyclic(200)),输入后触发崩溃,用cyclic_find找到覆盖local_j位置的偏移值。比如在GDB中看到local_j被覆盖为0x61616170,就用cyclic_find(0x61616170)得到偏移。
- 直接看Ghidra栈布局:找到输入缓冲区(比如
构造正确的Payload
- 先填充偏移量长度的垃圾数据(比如
b'A' * offset),填满输入缓冲区和中间的栈空间。 - 接着写入目标字符串
b'gagne\0':strcmp按字符串比较,必须加终止符\0,否则会继续读取栈中后续数据,导致比较不匹配。 - 字节顺序无需转换:字符串按ASCII顺序直接写入即可,
gagne的字节是0x67 0x61 0x67 0x6E 0x65 0x00,直接按这个顺序覆盖local_j所在的栈地址。
- 先填充偏移量长度的垃圾数据(比如
调试验证偏移
用GDB附加程序,输入测试Payload(比如b'A'*offset + b'AAAA\0'),查看local_j的内存地址是否被覆盖为AAAA,确认偏移正确后再替换成gagne\0。修正Pwntools脚本
示例修正后的脚本(替换实际偏移量):from pwn import * # 启动目标程序,远程连接替换成remote('ip', port) p = process('./your_binary') # 替换成计算出的实际偏移量 offset = 64 # 构造Payload:垃圾数据 + 目标字符串 payload = b'A' * offset + b'gagne\0' # 发送Payload(根据程序提示调整sendlineafter的参数) p.sendlineafter('Enter your name:', payload) # 交互获取shell或输出 p.interactive()
常见问题排查
- Payload无效先查偏移量:这是最容易出错的点。
- 检查程序栈保护:如果开启金丝雀,需要先泄露金丝雀值再覆盖;如果开启PIE,需要泄露基址后计算偏移。
- 确认
strcmp逻辑:必须完整覆盖gagne及终止符,避免因缺少\0导致比较失败。
内容的提问来源于stack exchange,提问作者Julien
相关产品推荐
相关产品推荐

