You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何用\x00覆盖内存地址?缓冲区溢出NULL字节写入问题咨询

解决缓冲区溢出中写入NULL字节(\x00)的问题

你碰到的这个问题太典型了——核心原因就是程序用了依赖NULL终止的字符串处理函数(比如strcpygetsscanf("%s")),这类函数一读到\x00就会认为字符串结束,直接停止写入后续内容,所以你payload里的\x00\x00\x00根本没被写到目标内存,栈里原本的0x7fff加上你写入的\x77\x05\x40\x00就拼成了奇怪的0x7fff00400577

下面给你几个可行的解决思路,按可靠性排序:

1. 优先用原始字节输入方式发送payload

如果漏洞程序是通过read()fread()recv()这类不依赖NULL终止的函数读取输入的(这类函数会按指定长度读取所有字节,不管有没有\x00),那直接生成包含\x00的payload就行。比如用Python生成并通过管道发送:

python -c 'print("A"*n + "\x77\x05\x40\x00\x00\x00\x00\x00")' | ./your_vuln_program

这里要注意64位地址是8字节,你之前只写了6个字节,得补全成8个(\x77\x05\x40\x00\x00\x00\x00\x00对应0x000000400577的小端序)。

2. 绕过字符串函数的NULL截断限制

如果程序只能用字符串类函数读取输入,试试这些技巧:

  • 利用栈的原有默认值:如果栈里目标地址的高位原本就是0x00000000(很多时候栈初始化会填充0),那你只需要覆盖低4字节\x77\x05\x40\x00,高位让它保持原有0就行,这样最终地址就是0x000000400577。你可以先调试看看栈里的原始值是不是符合这个情况。
  • 用环境变量传递带NULL的payload:环境变量在内存中允许包含NULL字节,你可以把payload放到环境变量里,然后通过溢出跳转到环境变量的地址:
    # 生成包含NULL的payload并放到环境变量
    export EXPLOIT_PAYLOAD=$(python -c 'print("A"*n + "\x77\x05\x40\x00\x00\x00\x00\x00")')
    # 运行漏洞程序
    ./your_vuln_program
    
    然后通过调试(比如gdb)找到环境变量EXPLOIT_PAYLOAD在内存中的地址,把这个地址作为溢出的目标即可。
  • 检查程序是否支持输入转义:有些程序会对输入的转义字符做解析(比如把\\x00转换成实际的\x00字节),如果是这种情况,你可以输入\\x00代替直接的\x00,让程序帮你转换成NULL字节。不过这个要看程序的输入处理逻辑,不是通用解法。

3. 额外注意:确认地址的字节序

最后再提醒一句,64位系统是小端序,所以0x000000400577对应的字节序列是\x77\x05\x40\x00\x00\x00\x00\x00,别搞反了顺序,这也是溢出时容易踩的坑。

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

火山引擎 最新活动