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程序需要两个终端:
- 第一个终端启动gdb:
gdb-multiarch -q ./pwn
- 第二个终端运行程序并开启调试端口:
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} - 参数控制技巧:
- 使用
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. 参考文章
五、总结
ARM Pwn与x86 Pwn的主要区别在于:
- 寄存器使用和调用约定不同
- 指令集和gadget寻找方式不同
- 栈布局和溢出方式有差异
- 调试环境配置更复杂
掌握ARM Pwn需要熟悉ARM架构特性,并通过实践积累经验。建议从简单栈溢出开始,逐步学习ROP、shellcode等高级技术。