mips-pwn环境搭建

mips-pwn环境搭建

在比赛中偶尔也会遇到mips架构的pwn题,要做这些题,首先得把环境搭起来。本篇介绍的是mips架构的pwn环境搭建,主要是要实现两个目标:

  • 运行起来mips架构的程序
  • 方便的对mips程序进行调试

安装qemu及相关软件

mips程序是不能直接在我们的电脑上运行的(架构不一样),为了让mips的程序跑起来,我们得使用qemu模拟器,qemu除了能模拟mips运行环境外,还能模拟其他很多架构。

qemu安装

1
2
3
4
5
sudo apt-get install qemu 
sudo apt-get install qemu-user-static
sudo apt-get install qemu-system
sudo apt-get install uml-utilities
sudo apt-get install bridge-utils

pwndbg安装

安装用于调试的pwndbg,pwndbg对各种架构支持的比peda好,按照官方给的步骤正常安装即可

1
2
3
git clone https://github.com/pwndbg/pwndbg
cd pwndbg
./setup.sh

mipsrop插件

mipsrop是ida的插件,用来寻找mips程序的gadget,直接放到ida的plugins目录下即可

https://github.com/devttys0/ida/tree/master/plugins/mipsrop

qemu使用一般有系统模式和用户模式。系统模式加载指定的镜像,模拟的是整个系统。用户模式则是模拟用户指定的某个程序。

使用qemu系统模式

配置qemu网络

为了和模拟出来的整个系统进行通信,需要先配置qemu的网络。配置网络在网上找到两种方法,另外一种修改/etc/network/interfaces的方法不容易成功,还是推荐下面的方法:

创建网桥:

1
2
sudo brctl addbr virbr0
sudo ifconfig virbr0 192.168.122.1/24 up

创建tap接口,名字为tap0,并添加到网桥:

1
2
3
sudo tunctl -t tap0
sudo ifconfig tap0 192.168.122.11/24 up
sudo brctl addif virbr0 tap0

下载并启动qemu镜像,配置qemu虚拟机中的网络。在这里下载qemu的mips镜像

1
2
# 使用qemu启动下载的镜像
sudo qemu-system-mips -M malta -kernel vmlinux-3.2.0-4-4kc-malta -hda debian_wheezy_mips_standard.qcow2 -append "root=/dev/sda1 console=tty0" -netdev tap,id=tapnet,ifname=tap0,script=no -device rtl8139,netdev=tapnet -nographic

输入root/root进入虚拟机,设置ip:

ifconfig eth0 192.168.122.12/24 up

接着就可以看到qemu虚拟机和外面的网络互通了:

如何调试

通过qemu的系统模式模拟出来了整个系统,我们可以在系统里面运行mips架构的程序,那么该如何对其进行调试呢?

可以在这里下载(原始的项目访问不了了,贴的是自己fork的)各个架构静态编译的gdbserver,使用gdbserver启动要调试的程序或附加到需要调试的进程上。

1
2
3
4
5
6
7
8
9
# 启动要调试的程序
root@debian-mips:~# ./gdbserver 0.0.0.0:12345 embedded_heap
Process embedded_heap created; pid = 2379
Listening on port 12345

# 附加到要调试的进程
root@debian-mips:~# ./gdbserver 0.0.0.0:12345 --attach $(pidof embedded_heap)
Attached; pid = 2790
Listening on port 12345

接着就可以在qemu外使用gdb-mutiarch来连接该端口进行调试了

1
2
3
4
gdb-multiarch embedded_heap
set arch mips
set endian big
target remote 192.168.122.12:12345

使用qemu用户模式

qemu的用户模式可以直接使用,不像系统模式那样还需要下载镜像、配置网络

在查看好程序的架构之后,使用对应架构的qemu运行即可。这里以运行0ctf2019的embedded_heap为例。

查看程序架构,发现是大端mips架构:

1
2
$ file embedded_heap 
embedded_heap: ELF 32-bit MSB shared object, MIPS, MIPS32 rel2 version 1 (SYSV), dynamically linked, interpreter /lib/ld-uClibc.so.0, stripped

尝试使用qemu-mips模拟运行该程序,报出没有ld-uClibc.so.0库:

1
2
$ qemu-mips embedded_heap 
/lib/ld-uClibc.so.0: No such file or directory

缺少相应的库,但是题目给出了我们需要的so库,

1
2
$ ls ./lib/
ld-uClibc-0.9.33.2.so ld-uClibc.so.0 libc.so.0 libuClibc-0.9.33.2.so

所以可以使用chroot,把根目录设置到当前目录下,这样就能加载到题目给的libc库了。不过需要注意的是,如果在这里使用qemu-mips的话还是会报错,因为qemu-mips不是静态编译的,它的运行依赖于本地的其他so库,chroot之后便找不到这些so库了,虽然可以通过ldd查看它所需要的库,并拷贝到相对当前目录下的对应路径下,但是这样太麻烦了,可以直接使用静态编译的版本qemu-mips-static

1
2
3
4
5
6
7
8
9
$ cp $(which qemu-mips-static) ./
$ sudo chroot . ./qemu-mips-static embedded_heap
__ __ _____________ __ __ ___ ____
/ //_// ____/ ____/ | / / / / / | / __ )
/ ,< / __/ / __/ / |/ / / / / /| | / __ |
/ /| |/ /___/ /___/ /| / / /___/ ___ |/ /_/ /
/_/ |_/_____/_____/_/ |_/ /_____/_/ |_/_____/

===== Embedded Heap =====

如何调试

用户模式下可以通过-g选项来指定监听的端口,然后在另一个终端使用gdb-multiarch连接该端口进行调试

$ sudo chroot . ./qemu-mips-static -g 12345 embedded_heap
1
2
3
4
gdb-multiarch embedded_heap
set arch mips
set endian big
target remote 127.0.0.1:12345

注:由于题目在初始化的时候打开了/dev/urandom文件读取随机数,而在用户模式下没有该文件,所以程序启动之后会直接退出,这种情况下可以选择用qemu的系统模式!

解决调试中的数据发送问题

现在已经能够用系统模式和用户模式来模拟运行mips程序了,并且可以使用gdbserver来启动或附加到我们要调试的程序上。但是这里还是存在一个问题,就是不能像做正常pwn题那样方便的往程序中输入数据,虽然可以在qemu中手动的输入,但是输入的数据中难免会有不可见字符。那么该怎么解决这个问题呢?

后来想到了一个方法,针对的是程序运行在qemu系统模式中的情况。

https://github.com/darkerego/mips-binaries下载静态编译的socat程序,因为socat可以用来做数据转发,而且很久之前的pwn题也有用socat部署过。把下载好的socat拷贝到qemu虚拟机中,然后使用如下命令:

./socat tcp-l:9999,fork exec:./embedded_heap

然后使用pwntools连接该端口,发现能够正常的与该程序进行交互:

接着应该如何调试该程序呢?执行socat命令后qemu的终端就被占用了!可以创建一个sh文件,把socat命令写到该文件中,然后以后台方式&运行该sh文件:

socat在收到9999端口的数据请求后,便会启动embedded_heap程序,获取到该程序的进程id,然后使用gdbserver附加到该进程

现在就可以使用gdb-multiarch愉快的调试啦!

参考链接

https://xz.aliyun.com/t/1508

https://xz.aliyun.com/t/4130