7

mips-pwn环境搭建

 3 years ago
source link: https://e3pem.github.io/2019/08/23/mips-pwn/mips-pwn%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

mips-pwn环境搭建

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

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

安装qemu及相关软件

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

qemu安装

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好,按照官方给的步骤正常安装即可

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的方法不容易成功,还是推荐下面的方法:

创建网桥:

sudo brctl addbr virbr0
sudo ifconfig virbr0 192.168.122.1/24 up

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

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

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

# 使用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启动要调试的程序或附加到需要调试的进程上。

# 启动要调试的程序
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来连接该端口进行调试了

gdb-multiarch embedded_heap
set arch mips
set endian big
target remote 192.168.122.12:12345

使用qemu用户模式

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

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

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

$ 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库:

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

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

$ 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

$ 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
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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK