如何用\x00覆盖内存地址?缓冲区溢出NULL字节写入问题咨询
解决缓冲区溢出中写入NULL字节(\x00)的问题
你碰到的这个问题太典型了——核心原因就是程序用了依赖NULL终止的字符串处理函数(比如strcpy、gets、scanf("%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放到环境变量里,然后通过溢出跳转到环境变量的地址:
然后通过调试(比如gdb)找到环境变量# 生成包含NULL的payload并放到环境变量 export EXPLOIT_PAYLOAD=$(python -c 'print("A"*n + "\x77\x05\x40\x00\x00\x00\x00\x00")') # 运行漏洞程序 ./your_vuln_programEXPLOIT_PAYLOAD在内存中的地址,把这个地址作为溢出的目标即可。 - 检查程序是否支持输入转义:有些程序会对输入的转义字符做解析(比如把
\\x00转换成实际的\x00字节),如果是这种情况,你可以输入\\x00代替直接的\x00,让程序帮你转换成NULL字节。不过这个要看程序的输入处理逻辑,不是通用解法。
3. 额外注意:确认地址的字节序
最后再提醒一句,64位系统是小端序,所以0x000000400577对应的字节序列是\x77\x05\x40\x00\x00\x00\x00\x00,别搞反了顺序,这也是溢出时容易踩的坑。
内容的提问来源于stack exchange,提问作者yoon




