格式化字符串漏洞改写arg2失败求助:触发SIGSEGV错误
问题分析与解决
你的段错误大概率是因为**%15$n对应的参数不是arg2的地址,而是arg2的值**,导致printf尝试向非法地址0x88888888写入数据,触发内存访问错误。
具体验证方法
运行程序时输入%15$x,查看输出结果:
- 如果输出是
88888888,说明偏移15对应的是arg2的值(0x88888888),而非arg2的地址(0xffffcf58),此时%15$n会尝试写入0x88888888,这个地址不属于可写的栈空间,直接触发段错误。 - 如果输出是
ffffcf58,再用gdb查看该地址的可写性:执行x/wx 0xffffcf58,确认是否显示arg2的初始值0x88888888,再执行p &arg2验证地址是否匹配。
修正后的payload构造思路
要正确改写arg2为0x20(32),需要满足两个条件:
- %k$n中的k必须对应栈上存储
&arg2(0xffffcf58)的位置。 - 处理到%k$n时,printf累计打印的字节数恰好为32。
举个正确的构造示例(假设正确偏移是k):
python2 -c 'print("\x58\xcf\xff\xff%28x%k$n")' > text
\x58\xcf\xff\xff是arg2地址的小端序字节(0xffffcf58),占4字节。%28x会输出28字节的填充内容,加上前面的4字节,总打印字节数刚好是32(0x20)。- 替换k为你确认的正确偏移(即%k$x会输出0xffffcf58的偏移)。
额外调试建议
用gdb跟踪栈布局:
- 在main函数的printf处打断点:
b main:printf - 运行程序并输入payload,程序停在断点后,查看栈上的参数:
x/20wx $ebp+12 # 查看从$1开始的20个可变参数
找到值为0xffffcf58的位置,对应的偏移就是你需要的k值(比如第m个参数就是%m$n)。
内容的提问来源于stack exchange,提问作者cctrl
相关产品推荐
相关产品推荐

