N1CTF 2026 PWN题解析:多阶段Shellcode构造技术

1. 题目背景与挑战解析

这道来自N1CTF 2026的PWN题"Old_5he1lc0de"是一个典型的shellcode限制挑战。题目通过两个关键文件构建了独特的解题环境:

  • chal.py:作为交互入口,实现了三重防御机制:

    1. 字节黑名单(ByteCodeAlreadyUsed):禁止重复使用相同字节
    2. 字节类型限制(ByteCodeTypesOverLimited):总字节类型不超过16种
    3. 结果验证(FlagNotFound):要求输出必须包含flag内容
  • chal:ELF二进制程序,核心逻辑是:

    1. 通过mmap分配可执行内存区域(0x8000大小)
    2. 使用read读取用户输入到该区域
    3. 清空寄存器后跳转到用户输入位置执行

关键限制:需要分两次提交shellcode,且两次使用的字节类型总数≤16,每次shellcode必须能独立输出flag内容。

需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。

2. 逆向分析与突破口定位

2.1 二进制程序行为验证

使用GDB调试chal程序时,在read返回后的关键寄存器状态:

code复制RAX: 0x0 
RDX: 0x7ffff7ff7000 --> 用户输入起始地址
RIP: 0x5555555552a1 <main+165>

程序最终通过jmp rdx跳转到用户输入位置,且注意到:

  • RDX是唯一未被清零的寄存器
  • 内存页具有RWX权限(通过mmap的prot=7参数设置)

2.2 字节限制的数学约束

假设常规shellcode需要N个不同字节,则:

  • 第一次提交消耗N个字节类型
  • 第二次提交最多使用(16-N)个新字节类型
  • 两次shellcode必须使用完全不同的字节集

通过objdump -d chal分析,发现程序本身已使用约120种不同字节,这意味着无法直接复用程序已有的字节。

3. 多阶段Shellcode构造技术

3.1 第一阶段:RDX指针绘画法

核心思路:利用未被清零的RDX作为"画笔",通过算术指令动态构造真实shellcode。

技术实现:

  1. 初始化阶段:
    nasm复制add dx, 0xe      ; 操作码: 66 83 c2 0e
    

内容推荐

已经到底了哦
已经到底了哦