You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

缓冲区溢出覆盖返回地址调用低地址函数(0x57d)时的问题咨询

缓冲区溢出问题的解析与解决方案

让我一步步帮你拆解这两个疑问,并给出可行的解决思路:

1. Bash的null字节警告是否意味着忽略了payload中的\x00\x00?

没错,这个警告直接点明了问题:bash会忽略输入中的null字节(\x00)。

因为bash处理命令行参数时遵循C风格字符串规则——字符串以null字节作为结束标志。当你通过$(...)做命令替换生成payload时,bash遇到第一个\x00就会判定字符串已结束,后面的内容(包括剩余的\x00)都会被直接截断,根本不会传递给目标程序。这就是你的payload里\x00\x00没生效的核心原因。

2. 为什么触发SIGSEGV的地址是0x5600057d,而不是预期的0x0000057d?怎么构造正确的payload?

这个问题和程序的PIE(位置无关执行)特性直接相关:

  • 默认情况下,gcc编译的程序会开启PIE,程序加载到内存时会被分配一个随机的基地址(比如你这里的0x56000000)。
  • 你拿到的0x57d其实是目标函数not_called相对于程序基地址的偏移量,而非绝对内存地址。当你把\x7d\x05\x00\x00写入返回地址时,程序实际计算的绝对地址是「基地址 + 偏移量」,也就是0x56000000 + 0x57d = 0x5600057d,这就是你看到的崩溃地址。
  • 另外,0x0000057d本身是无效的用户空间地址(用户程序的内存地址不会这么低),哪怕你能传递这个地址,程序也会直接崩溃。

正确的payload构造方法:

  1. 获取函数的实际绝对地址:
    在gdb中启动程序后,用命令p &not_called查看not_called的真实绝对地址。比如如果输出是$1 = (void (*)()) 0x5600057d,那这个就是你要写入返回地址的目标值。
  2. 绕过bash的null字节限制:
    既然bash无法传递包含null字节的命令行参数,我们可以换方式传递payload:
    • 方法一:将payload写入二进制文件,通过标准输入传递给程序:
      python -c 'import sys; sys.stdout.write("A"*0x6c + "BBBB" + "\x7d\x05\x00\x00")' > payload.bin
      ./victim < payload.bin
      
    • 方法二:直接通过管道传递payload:
      python -c 'import sys; sys.stdout.write("A"*0x6c + "BBBB" + "\x7d\x05\x00\x00")' | ./victim
      
    这两种方式都能避开bash处理命令行参数时截断null字节的问题。
  3. 临时简化方案(适合实验/作业):
    按照你提到的技巧,用静态链接编译程序:
    gcc -static -o victim victim.c
    
    静态链接后的程序会禁用PIE,函数的绝对地址会是固定的高地址(不会包含null字节),这样你就可以直接用命令行传递payload,无需担心null字节被截断。

内容的提问来源于stack exchange,提问作者Jolly Roger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 15:42:40