吾爱师傅发了一篇关于mips程序的逆向,刚接触逆向遇到过但都跳过了,这次遇到正好趁此学习一下。
qemu的了解与ghidra
以该师傅发的iot逆向题目来学习。下载后有3个文件,其中一个是提示:
题目运行命令如下:
sudo qemu-system-mipsel -M malta -hda openwrt-malta-le-root.ext4 -kernel openwrt-malta-le-vmlinux.elf -nographic -append “root=/dev/sda console=tty50”需要分析的程序为 ./bin/maze
了解下qemu:
Qemu 是纯软件实现的虚拟化模拟器,几乎可以模拟任何硬件设备,我们最熟悉的就是能够模拟一台能够独立运行操作系统的虚拟机,虚拟机认为自己和硬件打交道,但其实是和 Qemu 模拟出来的硬件打交道,Qemu 将这些指令转译给真正的硬件。
其实就是qemu可以模拟一些对应程序需要环境来让执行对应的程序。
经过一番理解后,其实就是使用qemu利用所给的2个文件来模拟openwrt系统来运行,我们知道linux的每个命令都是一个二进制文件,而我们要分析的maze文件也在该命令文件夹中(bin)。
由于.ext4文件是可以直接解压的,首先将其解压后得到要分析的maze文件。
查看一下文件信息:32为小端mips的动态链接程序。
执行一下看,发现不能执行,因为这个mips框架的,查资料才知道可以使用qemu来模拟mips环境来执行mips程序。
题目有提示的,在上面告诉了我们题目运行命令:
所以首先我们是要安装qemu的:
1 | sudo apt-get install qemu-user |
然后进入该模拟的openwrt系统,简单执行一下maze程序,可以看见,还可以进行gdb调试。
由于ida7.5以下且不使用retdec
插件是不能反编译mips框架程序的,知道可以使用ghidra。下载后,找了一个教程学习了下,Ghidra使用,其实和ida也总体差不多,上手会很快,但没有ida那么方便。
由于以前学习java安装过jdk且配置了环境变量,下载该程序后可以直接使用很方便。载入程序:
文件名都是maze(迷宫),且通过伪代码可以很快看清程序流程,这道题也是maze的老套路了,首先生成一个表,然后通过指定字符(U D L R)控制走向,到达一个目的地。
这里可以通过伪代码计算出该表,但可以直接通过模拟的openwrt系统gdb调试,就调试好了。
然后dump出数据:dump binary memroy dump.txt 0x4110d0 0x411147
C语言按15*8打印一下:
最后走一下得结果:DDRDDLDDRRRRRDRDDDDDLLDDLLLUUULU
mips程序的ida动调与gdb调试
当然到这里肯定是不够的,万一程序没有给能能让该mips程序运行的文件系统,那我们还是自己想办法让程序运行起来进而动调。
在上面为了模拟openwrt系统运行,已经安装了qemu-user。这时候静态链接的mips程序我们是可以直接执行了,但一般的程序的程序都是动态链接的,我们只要安装好对应的架构程序的共享库就好了。学习安装的文章
首先搜索相关库:
1 | apt-cache search "libc6" | grep mips |
这里我们安装程序需要的就行。我为了以后方便将64位与32位的大小端mips程序的共享库都装了:
然后运行动态链接的程序要使用完整的命令且指明共享库路径:-L 指明共享库路径
1 | qemu-mipsel -L /usr/mipsel-linux-gnu/ ./maze |
但这道题的maze却运行不了,提示:
可以看到,他提示/bin/ld-musl-mipsel-sf.so.1不存在。而这是一个绝对路径,而题目给了文件系统的。所以找到之前解压的.ext4文件,果然才/bin/目录下发现ld-musl-mips-sf.so.1。所以这个的mips的程序应该是指定了共享库的路径了,我们安装32位小端共享库自然不行。
所以本题的程序要利用所给的共享库,接下来把lib文件夹放在与maze同一级的目录下,然后执行下面的命令:
1 | qemu-mipsel -L ./ ./maze |
还是报错。。但这次是共享库存在了。。
最后在看发这个题的师傅的帖子里看到一个方法:也就是我上面执行失败的解决办法。
找到/lib/下的2个文件:
我的理解是像链表一样通过一个文件找到一个文件。这样会导致我们在所给系统外执行该程序,解析失败。解决办法:
直接删除原文件,将所指的2个文件,重命名为指向他们文件的名称。也就是ld-musl-mipsel-sf.so.1删除,libc.so重名为ld-musl-mipsel-sf.so.1,另外一个文件同然的操作。
然后执行成功。当然对于直接给的一个mips程序,我们用指定的qemu命令并指明共享库就可以执行的了。要是其他架构的程序使用相应的命令即可
为了调试,我们指定某一个端口开一个GDB调试(-g port)。
因为以前ida动调端口号都是23946,这里为了ida动调方便也用这个。
现在我们就可以开始调试了,使用gdb与ida都可以。
首先gdb:
- 安装apt-get install gdb-multiarch
- gdb-multiarch -q ./bin/maze
- set architecture mips(设置好调试程序的架构)
- set endian little(设置程序的大小端)
- 远程连接调试端口 target remote :23946(本地可以不写ip,127.0.0.1)
ida:与之前的ida的Remote linux debugger类似。