ARM EXP 开发 - 绕过 DEP 执行 mprotect()
字数 1613 2025-08-24 20:49:22

ARM 漏洞开发:绕过 DEP 执行 mprotect() 教学文档

1. 环境准备与基础知识

1.1 实验环境

  • 目标系统:ARM架构设备
  • 易受攻击程序:myhttpd HTTP服务器(运行在8080端口)
  • 漏洞类型:URL参数中的堆栈溢出
  • 调试工具:radare2、gdbserver、ropper

1.2 关键概念

  • DEP (Data Execution Prevention):防止在数据区域执行代码的安全机制
  • ROP (Return-Oriented Programming):利用现有代码片段(gadgets)构建攻击链的技术
  • mprotect():系统调用,用于修改内存区域的访问权限

2. 漏洞分析

2.1 内存映射查看

使用radare2查看进程内存映射:

dmm
0x00400000 /usr/bin/myhttpd
0xb6e5a000 /usr/lib/libc-2.28.so  # 选择此库构建ROP链

2.2 溢出验证

发送超长URL导致崩溃:

GET /AAAAAAAAAAAAAAAAAAAAAAAA... HTTP/1.1

观察到PC被覆盖为0x41414140,证明存在溢出漏洞。

3. 漏洞利用准备

3.1 确定偏移量

使用ragg2生成和查询Bruijin模式:

BRUIJN=`ragg2 -r -P 250| tr -d '\n'`
echo -e "GET $BRUIJN HTTP/1.1\n" | nc 127.0.0.1 8080
ragg2 -q 0x...  # 查询偏移量

本例中偏移量为144字节。

3.2 线程堆栈分析

  • 线程堆栈通过mmap2()和mprotect()创建
  • 初始无权限区域作为保护页
  • 堆栈向下增长,SP指向可读写区域

4. ROP链构建

4.1 目标

构建ROP链实现:

  1. 设置mprotect()参数(R0、R1、R2)
  2. 调用mprotect()使堆栈可执行
  3. 跳转到堆栈执行shellcode

4.2 关键gadgets查找

使用ropper工具查找gadgets:

ropper --file libc-2.28.so --console

常用gadget类型:

  • 寄存器控制:pop {r0, r4, pc}
  • 计算操作:and r0, r0, r1; bx lr
  • 链接控制:pop {lr}; bx r3

4.3 BX LR处理策略

  1. 初始设置LR指向pop {pc} gadget
  2. 每个BX LR gadget后跟下一个gadget地址
  3. 形成链式执行流程

5. 完整ROP链设计

5.1 mprotect()参数准备

  • R0:对齐的堆栈地址(SP+4与0xFFFFF001进行AND操作)
  • R1:足够大的长度值(0x01010101)
  • R2:权限标志(PROT_READ|PROT_WRITE|PROT_EXEC = 0x7)

5.2 关键gadgets序列

  1. 初始化BX LR滑动指针
  2. 准备R0值(对齐堆栈地址)
  3. 准备R1值(长度)
  4. 准备R2值(权限标志)
  5. 调用mprotect()
  6. 跳转到shellcode

5.3 shellcode选择

使用ARM架构的反向TCP shellcode,连接到192.168.250.1:4444。

6. 利用脚本分析

关键脚本变量:

fmt='<I'  # 小端格式
base=0xb6e5a000  # libc基地址
shift=144  # 偏移量
shellcode = b'\x01\x30...'  # ARM反向shellcode

ROP链构建函数:

def data(data, cmt=''): return [struct.pack(fmt,data),cmt]
def lib(offset, cmt=''): return [struct.pack(fmt,base+offset),cmt]

7. 开发与调试技巧

7.1 增量开发流程

  1. 一次添加一个gadget
  2. 每次发送payload前附加调试器
  3. 检查寄存器是否符合预期
  4. 使用--human选项查看可读格式

7.2 寄存器使用策略

  • 优先使用易控制的寄存器(R0有88个mov gadget)
  • 避免使用难以操作的寄存器(R12没有mov gadget)
  • 注意"栈绑定"寄存器在线程环境中的可用性

8. 完整利用步骤

  1. 确定偏移量(144字节)
  2. 选择libc作为gadget源(基址0xb6e5a000)
  3. 构建ROP链准备mprotect()参数
  4. 添加mprotect()调用
  5. 附加shellcode
  6. 发送精心构造的HTTP请求

9. 防御措施

  1. 启用ASLR(地址空间布局随机化)
  2. 使用栈保护机制(如Stack Canary)
  3. 限制库的可执行权限
  4. 对输入进行严格验证

10. 总结

本教学详细介绍了在ARM架构上绕过DEP保护的完整流程,重点包括:

  • 通过ROP链控制执行流
  • 精心设计gadget链准备系统调用参数
  • 使用mprotect()修改内存权限
  • 增量开发和调试ROP链的技巧
  • 实际利用中的注意事项和最佳实践
ARM 漏洞开发:绕过 DEP 执行 mprotect() 教学文档 1. 环境准备与基础知识 1.1 实验环境 目标系统:ARM架构设备 易受攻击程序:myhttpd HTTP服务器(运行在8080端口) 漏洞类型:URL参数中的堆栈溢出 调试工具:radare2、gdbserver、ropper 1.2 关键概念 DEP (Data Execution Prevention) :防止在数据区域执行代码的安全机制 ROP (Return-Oriented Programming) :利用现有代码片段(gadgets)构建攻击链的技术 mprotect() :系统调用,用于修改内存区域的访问权限 2. 漏洞分析 2.1 内存映射查看 使用radare2查看进程内存映射: 2.2 溢出验证 发送超长URL导致崩溃: 观察到PC被覆盖为0x41414140,证明存在溢出漏洞。 3. 漏洞利用准备 3.1 确定偏移量 使用ragg2生成和查询Bruijin模式: 本例中偏移量为144字节。 3.2 线程堆栈分析 线程堆栈通过mmap2()和mprotect()创建 初始无权限区域作为保护页 堆栈向下增长,SP指向可读写区域 4. ROP链构建 4.1 目标 构建ROP链实现: 设置mprotect()参数(R0、R1、R2) 调用mprotect()使堆栈可执行 跳转到堆栈执行shellcode 4.2 关键gadgets查找 使用ropper工具查找gadgets: 常用gadget类型: 寄存器控制: pop {r0, r4, pc} 计算操作: and r0, r0, r1; bx lr 链接控制: pop {lr}; bx r3 4.3 BX LR处理策略 初始设置LR指向 pop {pc} gadget 每个BX LR gadget后跟下一个gadget地址 形成链式执行流程 5. 完整ROP链设计 5.1 mprotect()参数准备 R0 :对齐的堆栈地址(SP+4与0xFFFFF001进行AND操作) R1 :足够大的长度值(0x01010101) R2 :权限标志(PROT_ READ|PROT_ WRITE|PROT_ EXEC = 0x7) 5.2 关键gadgets序列 初始化BX LR滑动指针 准备R0值(对齐堆栈地址) 准备R1值(长度) 准备R2值(权限标志) 调用mprotect() 跳转到shellcode 5.3 shellcode选择 使用ARM架构的反向TCP shellcode,连接到192.168.250.1:4444。 6. 利用脚本分析 关键脚本变量: ROP链构建函数: 7. 开发与调试技巧 7.1 增量开发流程 一次添加一个gadget 每次发送payload前附加调试器 检查寄存器是否符合预期 使用 --human 选项查看可读格式 7.2 寄存器使用策略 优先使用易控制的寄存器(R0有88个mov gadget) 避免使用难以操作的寄存器(R12没有mov gadget) 注意"栈绑定"寄存器在线程环境中的可用性 8. 完整利用步骤 确定偏移量(144字节) 选择libc作为gadget源(基址0xb6e5a000) 构建ROP链准备mprotect()参数 添加mprotect()调用 附加shellcode 发送精心构造的HTTP请求 9. 防御措施 启用ASLR(地址空间布局随机化) 使用栈保护机制(如Stack Canary) 限制库的可执行权限 对输入进行严格验证 10. 总结 本教学详细介绍了在ARM架构上绕过DEP保护的完整流程,重点包括: 通过ROP链控制执行流 精心设计gadget链准备系统调用参数 使用mprotect()修改内存权限 增量开发和调试ROP链的技巧 实际利用中的注意事项和最佳实践