本文通过调试 test_rex.py 中的 test_linux_stacksmash() 函数,以加深对 Rex 的理解。测试函数 test_linux_stacksmash() 是 Rex 开发团队给出的测试代码,用以展示 Rex 对栈溢出漏洞的自动利用能力。官方提供的测试样例 vuln_stacksmash 为 elf 格式的可执行文件,其中存在栈溢出漏洞,Rex 通过 rop2system、rop2text、jmpesp 三种方式实现了对该漏洞的自动化利用。下文为学习笔记,若存在理解有误的地方,请各位师傅批评指正。

0x00 vuln_stacksmash 栈溢出漏洞

通过 r2 查看 vuln_stacksmash。sym.vuln 函数中,系统所分配的空闲空间为 0x58,使用 read(int fd, void * buf, size_t count) 函数读入数据时,count 设置为 0x100,超出系统所分配的空闲空间 0x58,导致栈溢出。

使用 GDB 调试 vuln_stacksmash,分析溢出点状态。调试时需注意,main() 函数中调用 sym.imp.system 时创建了新进程,因此需要在 GDB 中设置 set follow-fork-mode parent,使 GDB 始终附加在父进程中。

否则在调试过程 GDB 会跟踪至子进程并自动退出。

首先查看 vuln_stacksmash 保护机制开启情况,由下图可知未开启任何保护机制。

使用 GDB 加载 vuln_stacksmash,运行至溢出点,程序状态如下:

计算偏移为 0x44,构造 PoC 并输入。检查栈上的数据情况,可见 EBP 已被 “\x41\x41\x41\x41” 覆盖,后续四个字节为 EIP 值,也已被覆盖为“\x42\x42\x42\x42”

跟踪至 ret 指令,触发异常,EIP 被劫持为“\x42\x42\x42\x42”

由于 vuln_stacksmash 存在典型栈溢出漏洞,且未开启安全机制,因此存在多种利用方式。下文概要分析如何使用 Rex 自动生成 Exploit。

0x01 test_linux_stacksmash()

由于 Rex 封装的原因,整体代码看起来较为简洁,从漏洞复现、漏洞类型判定、Exploit 生成到漏洞验证,共计 10 行代码。其中,Crash 类用以复现漏洞并返回漏洞类型,Exploit类用以判定漏洞的可利用性,并生成 exploit。171 ~ 174 行代码用以验证 Exploit 的有效性。

0x02 漏洞复现

采用 concolic-execution 复现 Crash 状态,相关功能在 Crash 类中实现。在本例中,初始化 rex.Crash()时,共传入以下参数:

  • :param binary: vuln_stacksmash 全路径
  • :param crash: PoC
  • :param fast_mode: 传入 True,代表将 Angrop 设置为快速查找模式
  • :param rop_cache_path: 从该文件中查找 gadgets
  • :param tracer_args

1、Concrete Execution
通过 QEMU 加载二进制程序,以 PoC 为输入运行,复现 crash_state,运行结果如下:

2、Concolic Execution
在获取到 Crash state 之后,基于 Angr 实现 Concolic Execution。首先设置程序初始状态。

使用 ‘posix’、’preconstrainer’ 插件辅助分析:

使用 ‘Tracer’、’Oppologist’ 两种 Exploration_techniques:

设置 simulation_manager :

执行结果:

0x03 漏洞类型判定

_triage_crash() 函数依据原理对漏洞类型进行判定。

执行结果为 IP_OVERWRITE

0x04 可利用性判定

仅对以下十二类漏洞能够生成 Exploit。

0x05 ExploitFactory

代码中设置了 rop_leak_memory、rop_set_register、 explore_for_exploit 三种利用方式。读过源码后发现, rop_leak_memory、rop_set_register 均是针对 CGC 格式文件的利用技术。 在已有的九种 exploit_technique 中,仅有 call_jmp_sp_shellcode、call_shellcode、rop_to_system 用以针对 elf 文件。执行结果如下:

0x06 Verified

对三种生成结果进行确认。

0x07 小结

通过阅读并调试 test_linux_stacksmash(),直观感受了 Rex 对栈溢出漏洞的利用过程,加深了对 Rex 的理解,特别是采用 concolic-execution 复现 Crash 部分。但目前对其中的 Explore_technique、Exploit_technique 等内容理解并不深入,在后续学习过程中逐步完善。