arm pwn 入门
字数 1628 2025-08-30 06:50:35

ARM Pwn 入门教程

一、ARM架构基础

1. ARM架构简介

ARM架构是一种精简指令集(RISC)处理器架构,广泛应用于移动设备、嵌入式系统等领域。在安全研究中,ARM架构的二进制漏洞利用与x86架构有显著不同。

2. 运行环境搭建

在Ubuntu中运行ARM架构文件需要通过qemu模拟器:

# 安装qemu
sudo apt-get install qemu-user

# 运行ARM程序
qemu-arm -L /usr/arm-linux-gnueabi ./pwnexp

3. 调试环境配置

使用gdb调试ARM程序需要两个终端:

  1. 第一个终端启动gdb:
gdb-multiarch -q ./pwn
  1. 第二个终端运行程序并开启调试端口:
qemu-arm -L /usr/arm-linux-gnueabi -g 1234 ./pwn

然后在gdb中连接:

target remote localhost:1234

二、ARM32架构详解

1. 寄存器与调用约定

  • BL指令:跳转到目标地址执行代码,同时将下一条指令地址保存到LR寄存器(R14)
  • 参数传递:前四个参数通过r0~r3寄存器传递
  • 特殊寄存器
    • r7:存储系统调用号
    • r11(fp):相当于ebp
    • r13(sp):栈顶指针
    • r15(pc):程序计数器(相当于eip)

2. 关键指令

  • pop {pc}:直接设置PC寄存器实现跳转(相当于ret)
  • mov r0, r3:寄存器间数据传递
  • pop {r3, pc}:从栈中弹出数据到r3和pc

3. 例题分析

例题1:ctfshow pwn346 - 栈溢出到后门

  • 特点:ARM32栈溢出中buf与返回地址之间没有rbp指针
  • 覆盖距离:0x18字节
  • 利用方式:直接覆盖返回地址到后门函数

例题2:ctfshow pwn347 - 栈溢出ROP

  • 关键gadget:
    0x00010548 : pop {fp, pc}
    0x000103a4 : pop {r3, pc}
    0x00010500 : pop {r4, pc}
    0x000106bc : pop {r4, r5, r6, r7, r8, sb, sl, pc}
    
  • 参数控制技巧:
    1. 使用pop {r3, pc}控制r3
    2. 使用mov r0, r3将r3值转移到r0
    3. 调用bl puts而非直接调用plt表,避免崩溃
  • 完整利用链:
    1. 泄露libc地址
    2. 计算system和/bin/sh地址
    3. 执行system("/bin/sh")

例题3:ctfshow pwn348 - ret2shellcode

  • 特点:ARM32下bss段可执行shellcode
  • 利用方式:
    1. 栈迁移到bss段
    2. 执行28字节的ARM32 shellcode
  • 关键gadget:控制r11(fp)实现栈迁移

三、AArch64架构详解

1. 寄存器与调用约定

  • 寄存器命名从Rn变为Xn
  • 特殊寄存器
    • X31(SP):栈顶指针
    • X29(FP):栈帧指针
    • X0~X7:依次传递参数
    • X0:函数返回值
    • X8:系统调用号或函数返回结果
    • X30:函数返回地址(RET指令返回X30中的地址)

2. 例题分析

例题1:pwn349 - 栈溢出到后门

  • 特点:溢出距离为0x88
  • 利用方式:直接覆盖返回地址到后门函数

例题2:ctfshow pwn350 - ret2shellcode

  • 预期解法:
    1. 栈溢出跳转到mprotect修改bss权限
    2. 跳转到bss执行shellcode
  • 实际发现:bss段可直接执行shellcode

例题3:[MTCTF 2022]aarch64_ret2libc

  • 特点:libc地址中间有\x00会被截断
  • 解决方案:添加0x5500000000偏移
  • 关键gadget:ldr x0, [sp]从栈中加载x0值

四、实用技巧与资源

1. 调试技巧

  • 使用gdb-multiarch调试ARM程序
  • 结合qemu的-g参数进行远程调试
  • 注意ARM架构下的栈布局与x86差异

2. Shellcode编写

3. 参考文章

  1. CTF中ARM & AArch64架构下的Pwn
  2. 异构pwn运行与调试 | starrysky

五、总结

ARM Pwn与x86 Pwn的主要区别在于:

  1. 寄存器使用和调用约定不同
  2. 指令集和gadget寻找方式不同
  3. 栈布局和溢出方式有差异
  4. 调试环境配置更复杂

掌握ARM Pwn需要熟悉ARM架构特性,并通过实践积累经验。建议从简单栈溢出开始,逐步学习ROP、shellcode等高级技术。

ARM Pwn 入门教程 一、ARM架构基础 1. ARM架构简介 ARM架构是一种精简指令集(RISC)处理器架构,广泛应用于移动设备、嵌入式系统等领域。在安全研究中,ARM架构的二进制漏洞利用与x86架构有显著不同。 2. 运行环境搭建 在Ubuntu中运行ARM架构文件需要通过qemu模拟器: 3. 调试环境配置 使用gdb调试ARM程序需要两个终端: 第一个终端启动gdb: 第二个终端运行程序并开启调试端口: 然后在gdb中连接: 二、ARM32架构详解 1. 寄存器与调用约定 BL指令 :跳转到目标地址执行代码,同时将下一条指令地址保存到LR寄存器(R14) 参数传递 :前四个参数通过r0~r3寄存器传递 特殊寄存器 : r7:存储系统调用号 r11(fp):相当于ebp r13(sp):栈顶指针 r15(pc):程序计数器(相当于eip) 2. 关键指令 pop {pc} :直接设置PC寄存器实现跳转(相当于ret) mov r0, r3 :寄存器间数据传递 pop {r3, pc} :从栈中弹出数据到r3和pc 3. 例题分析 例题1:ctfshow pwn346 - 栈溢出到后门 特点:ARM32栈溢出中buf与返回地址之间没有rbp指针 覆盖距离:0x18字节 利用方式:直接覆盖返回地址到后门函数 例题2:ctfshow pwn347 - 栈溢出ROP 关键gadget: 参数控制技巧: 使用 pop {r3, pc} 控制r3 使用 mov r0, r3 将r3值转移到r0 调用 bl puts 而非直接调用plt表,避免崩溃 完整利用链: 泄露libc地址 计算system和/bin/sh地址 执行system("/bin/sh") 例题3:ctfshow pwn348 - ret2shellcode 特点:ARM32下bss段可执行shellcode 利用方式: 栈迁移到bss段 执行28字节的ARM32 shellcode 关键gadget:控制r11(fp)实现栈迁移 三、AArch64架构详解 1. 寄存器与调用约定 寄存器命名从Rn变为Xn 特殊寄存器 : X31(SP):栈顶指针 X29(FP):栈帧指针 X0~X7:依次传递参数 X0:函数返回值 X8:系统调用号或函数返回结果 X30:函数返回地址(RET指令返回X30中的地址) 2. 例题分析 例题1:pwn349 - 栈溢出到后门 特点:溢出距离为0x88 利用方式:直接覆盖返回地址到后门函数 例题2:ctfshow pwn350 - ret2shellcode 预期解法: 栈溢出跳转到mprotect修改bss权限 跳转到bss执行shellcode 实际发现:bss段可直接执行shellcode 例题3:[ MTCTF 2022]aarch64_ ret2libc 特点:libc地址中间有\x00会被截断 解决方案:添加0x5500000000偏移 关键gadget: ldr x0, [sp] 从栈中加载x0值 四、实用技巧与资源 1. 调试技巧 使用 gdb-multiarch 调试ARM程序 结合qemu的 -g 参数进行远程调试 注意ARM架构下的栈布局与x86差异 2. Shellcode编写 ARM32 shellcode通常为28字节 参考资源: 用ARM编写shellcode - 先知社区 3. 参考文章 CTF中ARM & AArch64架构下的Pwn 异构pwn运行与调试 | starrysky 五、总结 ARM Pwn与x86 Pwn的主要区别在于: 寄存器使用和调用约定不同 指令集和gadget寻找方式不同 栈布局和溢出方式有差异 调试环境配置更复杂 掌握ARM Pwn需要熟悉ARM架构特性,并通过实践积累经验。建议从简单栈溢出开始,逐步学习ROP、shellcode等高级技术。