Rex: 自动化利用引擎分析
字数 3381 2025-08-24 16:48:07

Rex: 自动化利用引擎分析教程

1. Rex概述

Rex是Shellphish团队开发的自动生成exploit的引擎,是Mechaphish中的一个模块,最初用于CGC竞赛。它基于以下核心技术:

  • 硬件模拟器QEMU
  • 符号执行框架angr
  • 混合执行(Concolic Execution)

主要功能:

  • 通过混合执行复现崩溃路径
  • 根据寄存器及内存信息判定漏洞类型和可利用性
  • 尝试应用多种漏洞利用技术自动生成利用脚本

2. 安装方法

推荐安装方式

使用shellphish/mechaphish docker镜像:

docker pull shellphish/mechaphish
docker run -it shellphish/mechaphish

测试安装

tg = archr.targets.LocalTarget(<path_to_binary>, target_os='cgc')
crash = rex.Crash(tg, <input>)

示例测试代码:

t = archr.targets.LocalTarget(["/home/angr-dev/binaries/tests/defcon24/legit_00003"], target_os='cgc')
crash = rex.Crash(t, b"\x00\x0b 1 \xc1\x00\x0c\xeb...")  # 完整输入见原文

3. 核心接口与使用流程

基本使用步骤

  1. 创建target对象
  2. 使用target和input创建Crash对象
  3. 对Crash进行分析
  4. 调用explore()探索路径
  5. 调用exploit()方法构建exp
  6. 获取exploit相关信息并导出

Crash对象

主要属性

  • crash_types: 返回crash的漏洞类型

主要方法

  • explorable(): 判断是否可用'crash explorer'探索
  • exploitable(): 判断crash是否可利用
  • exploit(): 返回ExploitFactory实例
  • explore(): 探索crash以发现新bug
  • memory_control(): 确定我们控制的符号内存
  • stack_control(): 确定栈上控制的符号内存

ExploitFactory

通过crash的exploit()方法获得,重要属性:

  • arsenal: 字典,存储对应technique的exploit

4. 漏洞类型定义

Rex定义了以下漏洞类型:

IP_OVERWRITE = "ip_overwrite"               # IP完全覆盖
PARTIAL_IP_OVERWRITE = "partial_ip_overwrite" # IP部分覆盖
UNCONTROLLED_IP_OVERWRITE = "uncontrolled_ip_overwrite"
BP_OVERWRITE = "bp_overwrite"               # BP覆盖
PARTIAL_BP_OVERWRITE = "partial_bp_overwrite"
WRITE_WHAT_WHERE = "write_what_where"       # 任意地址写任意数据
WRITE_X_WHERE = "write_x_where"             # 任意地址写固定数据
UNCONTROLLED_WRITE = "uncontrolled_write"   # 目标地址不可控的写
ARBITRARY_READ = "arbitrary_read"           # 任意地址读
NULL_DEREFERENCE = "null_dereference"       # 空指针解引用
ARBITRARY_TRANSMIT = "arbitrary_transmit"   # 完全控制buf参数的传输
ARBITRARY_RECEIVE = "arbitrary_receive"     # 完全控制buf参数的接收

5. 内部实现解析

Rex内部实现主要包含三个模块:

  1. Crash: 重现崩溃路径,包括漏洞类型判定和可利用性判定
  2. Technique: 对可利用的Crash应用相应的利用技术
  3. Exploit: 调用各子模块自动生成Exploit

关系:crash + technique = exploit

5.1 Crash分析流程

路径重现(_trace)

  1. 使用给定输入获得具体trace
  2. 进行符号化trace
  3. 检查是否有crash

获取内存写操作(_filter_memory_writes)

  • 获得所有写内存操作
  • 分成符号内存(symbolic memory bytes)和flag内存(flag memory bytes)

漏洞类型判断(_triage_crash)

判断逻辑:

  1. 检查ip是否符号化(可控)及可控大小 → IP_OVERWRITE/PARTIAL_IP_OVERWRITE
  2. 检查bp是否符号化及可控大小 → BP_OVERWRITE/PARTIAL_BP_OVERWRITE
  3. 检查崩溃前State的recent_actions,筛选内存读写地址可控的操作
    • 内存写且数据可控 → WRITE_WHAT_WHERE
    • 内存写但数据不可控 → WRITE_X_WHERE
    • 内存读 → ARBITRARY_READ

5.2 路径探索(explore)

可explore的漏洞类型:

  • ARBITRARY_READ
  • WRITE_WHAT_WHERE
  • WRITE_X_WHERE

实现方式:

  • _explore_arbitrary_read: 任意读漏洞
  • _explore_arbitrary_write: 任意写漏洞

5.3 可利用性判定

可exploitable的漏洞类型:

exploitables = [
    Vulnerability.IP_OVERWRITE,
    Vulnerability.PARTIAL_IP_OVERWRITE,
    Vulnerability.BP_OVERWRITE,
    Vulnerability.PARTIAL_BP_OVERWRITE,
    Vulnerability.WRITE_WHAT_WHERE,
    Vulnerability.WRITE_X_WHERE
]

6. Technique对象

每个technique都是Technique对象的子类,需要重写:

  • check(): 检查技术是否适用于给定crash
  • apply(): 在崩溃状态点应用该技术

支持的利用技术

技术名称 适用漏洞类型 其他条件 平台
call_jmp_sp_shellcode IP_OVERWRITE/PARTIAL_IP_OVERWRITE 栈可执行 unix
call_shellcode IP_OVERWRITE/PARTIAL_IP_OVERWRITE 栈可执行 unix
circumstantially_set_register IP_OVERWRITE/PARTIAL_IP_OVERWRITE - cgc
rop_leak_memory IP_OVERWRITE/PARTIAL_IP_OVERWRITE - cgc
rop_register_control IP_OVERWRITE/PARTIAL_IP_OVERWRITE - unix
rop_set_register IP_OVERWRITE/PARTIAL_IP_OVERWRITE - cgc
rop_to_accept_system IP_OVERWRITE/PARTIAL_IP_OVERWRITE 存在accept&read函数 unix
rop_to_execl IP_OVERWRITE/PARTIAL_IP_OVERWRITE 存在execl&dup2函数 unix
rop_to_system IP_OVERWRITE/PARTIAL_IP_OVERWRITE 存在system函数 unix
rop_to_system_complicated IP_OVERWRITE/PARTIAL_IP_OVERWRITE libc被加载&system函数&plt unix
shellcode_leak_address IP_OVERWRITE/PARTIAL_IP_OVERWRITE 栈可执行 cgc
shellcode_set_register IP_OVERWRITE/PARTIAL_IP_OVERWRITE 栈可执行 cgc

7. Exploit对象

Exploit对象表示成功将利用技术应用于崩溃状态的结果。

ExploitFactory

用于管理和构建exploit,调用exploit()方法时:

  1. 依次应用每种利用技术
  2. 成功生成的exploit存储在arsenal属性中
  3. 针对CGC有专门的CGCExploitFactory类

构建exp

def exploit(self, blacklist_symbolic_explore=True, **kwargs):
    factory = self._prepare_exploit_factory(blacklist_symbolic_explore, **kwargs)
    factory.initialize()
    return factory

8. 测试示例

CGC测试

def test_legit_00003():
    inp = b"1\n" + b"A"*200
    path = os.path.join(bin_location, "tests/defcon24/legit_00003")
    with archr.targets.LocalTarget([path], target_os='cgc') as target:
        crash = rex.Crash(target, inp, fast_mode=True, 
                         rop_cache_path=os.path.join(cache_location, 'legit_00003'))
        assert crash.explorable()
        assert crash.one_of(Vulnerability.WRITE_WHAT_WHERE)
        crash.explore()
        arsenal = crash.exploit(blacklist_techniques={'rop_set_register', 'rop_leak_memory'})
        assert len(arsenal.register_setters) >= 2
        assert len(arsenal.leakers) >= 1

Linux测试

def test_linux_stacksmash_32():
    inp = b"A"*227
    lib_path = os.path.join(bin_location, "tests/i386")
    ld_path = os.path.join(lib_path, "ld-linux.so.2")
    path = os.path.join(lib_path, "vuln_stacksmash")
    with archr.targets.LocalTarget([ld_path, '--library-path', lib_path, path], 
                                 path, target_arch='i386').build().start() as target:
        crash = rex.Crash(target, inp, fast_mode=True,
                         rop_cache_path=os.path.join(cache_location, 'vuln_stacksmash'))
        exploit = crash.exploit(blacklist_techniques={'rop_leak_memory', 'rop_set_register'})
        assert len(exploit.arsenal) == 3
        assert 'rop_to_system' in exploit.arsenal
        assert 'call_shellcode' in exploit.arsenal
        assert 'call_jmp_sp_shellcode' in exploit.arsenal

9. 相关库 - archr

archr实现了以target为中心的分析模型,核心概念:

Targets

  • DockerImageTarget: docker镜像
  • LocalTarget: 本地系统运行的target

Bows

名称 描述
DataScoutBow 获取进程启动时的内存映射、环境、属性
AngrProjectBow 创建angr Project
AngrStateBow 创建angr State
QEMUTraceBow 执行qemu tracing
GDBServerBow 在gdbserver中启动target
STraceBow strace目标(跟踪系统调用和信号)
CoreBow 启动target并恢复core
InputFDBow 确定用户输入的FD数目

10. 总结

Rex是一个相对简单的自动化利用引擎,特点包括:

  • 基于angr和QEMU实现
  • 支持多种基本漏洞类型的检测和利用
  • 提供了一套完整的从crash到exploit的自动化流程
  • 支持CGC和Linux平台

虽然技术实现较为基础,但其架构和思路值得学习,可以作为自动化漏洞利用研究的起点。

Rex: 自动化利用引擎分析教程 1. Rex概述 Rex是Shellphish团队开发的自动生成exploit的引擎,是Mechaphish中的一个模块,最初用于CGC竞赛。它基于以下核心技术: 硬件模拟器QEMU 符号执行框架angr 混合执行(Concolic Execution) 主要功能: 通过混合执行复现崩溃路径 根据寄存器及内存信息判定漏洞类型和可利用性 尝试应用多种漏洞利用技术自动生成利用脚本 2. 安装方法 推荐安装方式 使用shellphish/mechaphish docker镜像: 测试安装 示例测试代码: 3. 核心接口与使用流程 基本使用步骤 创建target对象 使用target和input创建Crash对象 对Crash进行分析 调用explore()探索路径 调用exploit()方法构建exp 获取exploit相关信息并导出 Crash对象 主要属性 crash_types : 返回crash的漏洞类型 主要方法 explorable() : 判断是否可用'crash explorer'探索 exploitable() : 判断crash是否可利用 exploit() : 返回ExploitFactory实例 explore() : 探索crash以发现新bug memory_control() : 确定我们控制的符号内存 stack_control() : 确定栈上控制的符号内存 ExploitFactory 通过crash的exploit()方法获得,重要属性: arsenal : 字典,存储对应technique的exploit 4. 漏洞类型定义 Rex定义了以下漏洞类型: 5. 内部实现解析 Rex内部实现主要包含三个模块: Crash: 重现崩溃路径,包括漏洞类型判定和可利用性判定 Technique: 对可利用的Crash应用相应的利用技术 Exploit: 调用各子模块自动生成Exploit 关系: crash + technique = exploit 5.1 Crash分析流程 路径重现(_ trace) 使用给定输入获得具体trace 进行符号化trace 检查是否有crash 获取内存写操作(_ filter_ memory_ writes) 获得所有写内存操作 分成符号内存(symbolic memory bytes)和flag内存(flag memory bytes) 漏洞类型判断(_ triage_ crash) 判断逻辑: 检查ip是否符号化(可控)及可控大小 → IP_ OVERWRITE/PARTIAL_ IP_ OVERWRITE 检查bp是否符号化及可控大小 → BP_ OVERWRITE/PARTIAL_ BP_ OVERWRITE 检查崩溃前State的recent_ actions,筛选内存读写地址可控的操作 内存写且数据可控 → WRITE_ WHAT_ WHERE 内存写但数据不可控 → WRITE_ X_ WHERE 内存读 → ARBITRARY_ READ 5.2 路径探索(explore) 可explore的漏洞类型: ARBITRARY_ READ WRITE_ WHAT_ WHERE WRITE_ X_ WHERE 实现方式: _explore_arbitrary_read : 任意读漏洞 _explore_arbitrary_write : 任意写漏洞 5.3 可利用性判定 可exploitable的漏洞类型: 6. Technique对象 每个technique都是Technique对象的子类,需要重写: check() : 检查技术是否适用于给定crash apply() : 在崩溃状态点应用该技术 支持的利用技术 | 技术名称 | 适用漏洞类型 | 其他条件 | 平台 | |---------|------------|---------|-----| | call_ jmp_ sp_ shellcode | IP_ OVERWRITE/PARTIAL_ IP_ OVERWRITE | 栈可执行 | unix | | call_ shellcode | IP_ OVERWRITE/PARTIAL_ IP_ OVERWRITE | 栈可执行 | unix | | circumstantially_ set_ register | IP_ OVERWRITE/PARTIAL_ IP_ OVERWRITE | - | cgc | | rop_ leak_ memory | IP_ OVERWRITE/PARTIAL_ IP_ OVERWRITE | - | cgc | | rop_ register_ control | IP_ OVERWRITE/PARTIAL_ IP_ OVERWRITE | - | unix | | rop_ set_ register | IP_ OVERWRITE/PARTIAL_ IP_ OVERWRITE | - | cgc | | rop_ to_ accept_ system | IP_ OVERWRITE/PARTIAL_ IP_ OVERWRITE | 存在accept&read函数 | unix | | rop_ to_ execl | IP_ OVERWRITE/PARTIAL_ IP_ OVERWRITE | 存在execl&dup2函数 | unix | | rop_ to_ system | IP_ OVERWRITE/PARTIAL_ IP_ OVERWRITE | 存在system函数 | unix | | rop_ to_ system_ complicated | IP_ OVERWRITE/PARTIAL_ IP_ OVERWRITE | libc被加载&system函数&plt | unix | | shellcode_ leak_ address | IP_ OVERWRITE/PARTIAL_ IP_ OVERWRITE | 栈可执行 | cgc | | shellcode_ set_ register | IP_ OVERWRITE/PARTIAL_ IP_ OVERWRITE | 栈可执行 | cgc | 7. Exploit对象 Exploit对象表示成功将利用技术应用于崩溃状态的结果。 ExploitFactory 用于管理和构建exploit,调用exploit()方法时: 依次应用每种利用技术 成功生成的exploit存储在arsenal属性中 针对CGC有专门的CGCExploitFactory类 构建exp 8. 测试示例 CGC测试 Linux测试 9. 相关库 - archr archr实现了以target为中心的分析模型,核心概念: Targets DockerImageTarget: docker镜像 LocalTarget: 本地系统运行的target Bows | 名称 | 描述 | |------|------| | DataScoutBow | 获取进程启动时的内存映射、环境、属性 | | AngrProjectBow | 创建angr Project | | AngrStateBow | 创建angr State | | QEMUTraceBow | 执行qemu tracing | | GDBServerBow | 在gdbserver中启动target | | STraceBow | strace目标(跟踪系统调用和信号) | | CoreBow | 启动target并恢复core | | InputFDBow | 确定用户输入的FD数目 | 10. 总结 Rex是一个相对简单的自动化利用引擎,特点包括: 基于angr和QEMU实现 支持多种基本漏洞类型的检测和利用 提供了一套完整的从crash到exploit的自动化流程 支持CGC和Linux平台 虽然技术实现较为基础,但其架构和思路值得学习,可以作为自动化漏洞利用研究的起点。