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

32位x86缓冲区溢出CTF挑战:绕过字符限制读取文件

缓冲区溢出绕过字符限制的技术提示

你的核心思路没问题:通过缓冲区溢出控制返回地址执行自定义代码是正确的利用路径,当前的卡点是绕过0x00、0x80、0x89、0xe1这些禁止字符(注意代码里的forbidden数组重复了0x89,实际禁止的是四个唯一值)。下面是具体的绕过方案:

核心绕过方向

1. 替换被禁的系统调用触发指令

Linux 32位环境中,除了int 0x80(Opcode含0x80被禁),还可以用sysenter指令(Opcode为0x0f 0x34)触发系统调用,这两个字节不在禁止列表内。需要注意sysenter的调用约定和int 0x80不同:

  • eax存储系统调用号
  • edx存储返回地址
  • ecx存储第一个参数
  • 后续参数按顺序压入栈中

你可以基于这个指令重新编写读取文件的shellcode,比如依次调用open->read->write系统调用,全程避免使用任何被禁字节。

2. 编码shellcode并在运行时解码

如果原始功能必须用到被禁字符,可先对shellcode进行编码(例如XOR、加法/减法编码),注入时只传入编码后的字节,在shellcode开头添加解码逻辑,将编码后的字节还原为可执行的原始shellcode。解码逻辑必须确保不含被禁字符:

  • 示例XOR解码:选择一个不在禁止列表里的密钥(如0x11),对原始shellcode逐字节XOR;解码时用lodsb(Opcode 0xac)读取编码字节,xor al, 0x11还原,再用stosb(Opcode 0xaa)写入目标地址,循环处理所有字节。
  • 示例加法编码:将原始shellcode每个字节加0x01,解码时用dec al(Opcode 0x48)还原,同样避免被禁指令。

3. 构造ROP链替代shellcode

完全避免注入shellcode,利用程序或libc中的现有代码片段(gadgets)构造ROP链,调用libc函数实现读取文件:

  • 第一步:利用程序中的printf函数泄露libc基地址(例如打印puts的GOT表项),通过泄露的地址计算system函数和/bin/sh字符串的地址。
  • 第二步:查找可用的gadgets(用ROPgadget工具),比如pop ebx; ret、pop ecx; pop edx; ret等,确保这些gadget的指令字节不含被禁字符。
  • 第三步:拼接ROP链:pop ebx; ret + /bin/sh地址 + system地址,执行后即可触发shell,进而读取目标文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 21:01:02