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

Linux x86_64下objdump输出解读及sprintf漏洞利用问题咨询

解决sprintf漏洞利用中的NULL字符传递与指针解读问题

嘿,我来帮你梳理下sprintf漏洞利用到这一步该怎么突破——你遇到的NULL字符传递问题和指针解读困惑,都是x86_64平台上利用这类漏洞的常见卡点,咱们一步步拆解:

一、搞定NULL字符无法正常传递的问题

sprintf本身遇到\x00就会截断输出,而且如果是通过命令行传递payload,shell也会把\x00当成参数分隔符,导致后面的内容丢失。这里有两个靠谱的解决思路:

  • 利用格式化字符串的写操作间接写入0:不用直接在payload里塞\x00,而是用%hhn(写1字节)来构造0值。比如你需要往某个内存位置写入0,先计算当前payload已经输出的字符数,然后用%Xc%hhn,其中X = (0 - 当前输出字符数) % 256,这样当printf执行到这个格式符时,就会把0写入指定的字节位置。
  • 通过二进制方式传递payload:如果是命令行参数的问题,别直接在shell里输入,用Python的subprocess模块来传递包含\x00的二进制payload,比如:
    import subprocess
    payload = b'A'*20 + b'\x00' + b'your_remaining_payload_here'
    subprocess.run(['./your_vulnerable_program', payload])
    
    这样就能绕过shell对\x00的解析,让完整payload传递到程序里。

二、验证指针解读是否正确

不确定指针解读错了?可以通过格式化字符串漏洞的泄露功能来验证:

  • 泄露栈上的指针对比objdump结果:用%1$p、%2$p……逐个打印栈上的指针值,把这些值和objdump输出的地址(比如程序的GOT表、PLT表地址)对比。比如objdump显示printf的GOT项地址是0x404018,你可以在payload里加入多个%p,找到栈上对应位置打印出的地址是否和这个值一致,同时注意x86_64的小端字节序——内存中存储地址是逆序的,比如0x12345678会被存成\x78\x56\x34\x12。
  • 验证GOT表泄露:如果能通过%x$s(x是GOT地址在栈上的偏移)泄露GOT表项的内容,对比libc中对应函数的偏移,也能确认你解读的地址是否正确。

三、后续推进的具体步骤

当解决了NULL问题、确认指针解读没问题后,可以按这几步走:

  1. 泄露libc基地址:利用格式化字符串漏洞泄露某个已解析的GOT表项(比如printf的GOT地址内容),然后减去该函数在libc中的偏移(可以通过objdump -d /lib/x86_64-linux-gnu/libc.so.6 | grep printf得到),就能算出libc的基地址。
  2. 构造目标地址:通过libc基地址算出system函数和/bin/sh字符串的地址(同样查libc的偏移)。
  3. 控制程序执行流:如果是格式化字符串漏洞,用%n系列格式符把system的地址写入返回地址或者函数指针位置;如果是sprintf导致的栈溢出,就构造ROP链,把system("/bin/sh")的调用链写到栈上,覆盖返回地址。
  4. 调试验证:用gdb断点在sprintf调用后,查看内存中的payload是否正确写入,比如用x/32gx $rsp查看栈内容,或者用x/1gx <target_address>查看是否成功覆盖目标位置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:53:10