前言

最近在学习 IOT 安全这方面的知识,相信入门学这块都是从路由器的漏洞挖掘开始起步的。为了测试路由器漏洞必定要搭建环境,一般都是使用模拟的仿真环境而不是使用真机。固件仿真可以用于许多不通的目的,比如提供一个更好的方法来分析固件,测试利用,完成远程调试等。

一般模拟环境会使用 qemu 或者 AttifyOS VM搭建,两者算是各有优势吧。这里我选择了 qemu。笔者在搭建环境的时候遇到了很多问题,踩了不少坑,对照这《揭秘家用路由器 0day 漏洞挖掘技术》和网上的资料。但是网上的解决方案大多都是不太全或者讲的含糊不清。这里较详细地总结记录一下自己在搭建整个环境中遇到的一些问题,希望能给有需要的读者一些帮助和启发。

qemu 的介绍

QEMU 是一个面向完整 PC 系统的开源仿真器。除了仿真处理器外,QEMU 还允许仿真所有必要的子系统,如连网硬件和视频硬件。它还允许实现高级概念上的仿真(如对称多处理系统(多达 255 个 CPU)和其他处理器架构(如 ARM 和 PowerPC)。

这里的 qemu 虚拟机的搭建就是在 Vm Ubuntu 虚拟机下再使用 qemu 来搭建一个 mips 系统的虚拟机,将路由器系统固件放在里面运行。

binwalk、sasquatch 的安装

这两个工具的安装比较简单,也没啥问题,就安装书上的步骤来了。

binwalk 安装

sudo apt-get install binwalk
或者
sudo git clone https://github.com/devttys0/binwalk.git

sasquatch SquashFS 安装

sudo apt-get install zlib1g-dev liblzma-dev liblzo2-dev
sudo git clone https://github.com/devttys0/sasquatch
cd sasquatch && sudo make && sudo make install

qemu 的安装

这个网上的安装教程很多,安装过程中也不会出现什么太多的问题

sudo apt-get install qemu

交叉编译环境 buildroot 的安装

正常的安装步骤是按照《揭秘家用路由器 0day 漏洞挖掘技术》的书上的操作来的,但是在安装的过程中会出现很多问题:

sudo apt-get install libncurses5-dev patch
wget http://buildroot.uclibc.org/downloads/snapshots/buildroot-snapshots.tar.bz2
tar -jxvf buildroot-snapshots.tar.bz2
cd buildroot/
make clean
make menuconfig
sudo make

ncurses 库缺失错误

在 make menuconfig 时,可能会出现以下的错误,因为缺少了 Configuration 界面的图形字符支持

*** Unable to find the ncurses libraries or the
 *** required header files.
 *** 'make menuconfig' requires the ncurses libraries.
 *** 
 *** Install ncurses (ncurses-devel) and try again.

在接着安装这两个库

sudo apt-get install libncurses-dev curses-devel

然而又报了莫名其妙的错

正在读取软件包列表... 完成
正在分析软件包的依赖关系树       
正在读取状态信息... 完成       
注意,选中 'libncurses5-dev' 而非 'libncurses-dev'
libncurses5-dev 已经是最新版 (6.0+20160213-1ubuntu1)。
升级了 0 个软件包,新安装了 0 个软件包,要卸载 0 个软件包,有 478 个软件包未被升级。

这里最直接的方法就是安装所有的 libncurses 支持库,即

sudo apt-get install libncurs*

安装完成后重新输入 make menuconfig,就正常了。

接着按照教程的步骤配置好编译选项就行了,这里的 Target Architecture Varient 选为 Mips 32,至于编译大端或者小端程序的问题,后面会出现。

编译好后输入 mipsel ,tab 键补全,可以看到都是 mipsel 开头的程序(路径在 buildroot/output/host/bin,建议直接配置好环境变量),也就是说用 mipsel-linux-gcc 编译出来的程序默认是小端程序。有些人编译出的是 mips-linux-gcc 也就是说编译出来的默认是大端的程序。(为什么会有这种差异还是不太清楚...可能是在上面的配置选项的不同)

但是这并不影响大小端的互相编译,接着看后面的问题。

参考:
https://blog.csdn.net/ldl22847/article/details/8612993
https://www.cnblogs.com/evisie/archive/2012/12/05/2802363.html

mipsel-linux-gcc 编译大端程序

在编写共享库的时候,经常需要根据路由器是大端程序或者是小端程序来选择编译,否则会报下面的错,不是一个 ELF 文件。原因就是目标系统支持的是大端的程序,而编译出来的是小端的程序,作为共享库加载时就会产生这种不匹配的问题

nick@nick-machine:~/iot/firmware/dir-605l/_dir605L_FW_113.bin.extracted/squashfs-root-0$ ./qemu-mips -L ./ -E LD_PRELOAD="./lib.so" ./bin/boa

./bin/boa: './lib.so' is not an ELF executable for MIPS
./bin/boa: can't load library './lib.so'

例如我这边默认编译出来的是小端程序:

demo.c

#include <stdlib.h>
#include <malloc.h>


int main(){

        int *a;
        a = malloc(0x10);

        puts("demo");
        return 0;
}
~

gcc 编译,看到是个 LSB(小端程序)

nick@nick-machine:~/iot/program$ mipsel-linux-gcc demo1.c -static -o demo
nick@nick-machine:~/iot/program$ file demo
demo1: ELF 32-bit LSB  executable, MIPS, MIPS32 version 1 (SYSV), statically linked, not stripped

使用 man gcc 可知如果要编译成大端程序的话,需要加上 -EB 参数

但是加上 -EB 之后,还是报错了,原因是在 ld 链接时默认是没有加上这个参数的,所以这里需要手动加上,也就是将编译和链接分两步

正确的用法:
即编译和链接分开

mipsel-linux-gcc demo.c -EB -c -static -o demo1    编译
mipsel-linux-ld demo1 -EB -o demo                  链接

最后成功编译成大端的程序:

nick@nick-machine:~/iot/program$ file demo
demo: ELF 32-bit MSB  executable, MIPS, MIPS32 version 1 (SYSV), statically linked, not stripped

chroot 命令问题

在模拟路由器 web 界面时,需要使用 chroot 来定义路由器固件的根目录,以便程序运行能加载到相应的 lib 库,但是在使用 qemu-mips 的时候会报错:

nick@nick-machine:~/iot/firmware/dir-605l/_dir605L_FW_113.bin.extracted/squashfs-root-0$ sudo chroot . ./qemu-mips -E LD_PRELOAD="./test" ./bin/boa
chroot: failed to run command './qemu-mips': No such file or directory

解决方法

需要安装使用 qemu-mips-static 才可以

apt-get install qemu binfmt-support qemu-user-static

sudo chroot . ./qemu-mips-static -E LD_PRELOAD="./test" ./bin/boa

qemu-system-mode 黑屏问题

按照安装教程下载好内核驱动之后,使用下面的命令打开,发现整个就黑屏了

sudo qemu-system-mips64 -M malta -kernel vmlinux-2.6.32-5-5kc-malta -hda debian_squeeze_mips_standard.qcow2 -append "root=/dev/sda1 console=tty0" -net nic,macaddr=00:0c:29:ee:39:39 -net tap -nographic

解决方法

安装 qemu-kvm

sudo apt-get install qemu-kvm libvirt virt-install virt-manager

并且最好在官网上下载使用 32 位的 mips 系统的内核镜像,即使用 qemu-system-mips 代替 qemu-system-mips64

反编译插件的安装

jeb-mips

jeb 版本的 mips 反汇编工具,支持伪代码的反编译

直接在下面的网站下载,直接打开就可以使用,缺点是试用版的不能将里面的代码复制出来。
https://www.pnfsoftware.com/jeb2/mips

在反编译窗口右键 -> 解析,就能看到相应的伪代码

Retdec

这个是 IDA 中的插件,用着很方便。但是这个安装比较麻烦,需要编译一大堆东西,笔者太菜了搞了好次没出来

这里还是贴出 sw 师傅的安装教程,大佬们可以研究一下:
https://bbs.pediy.com/thread-230290.htm

关于两个工具的使用可以看看 ctf 的题目:
https://blog.csdn.net/qq_33438733/article/details/80233448

qemu-system-mode 的网络配置

编译本地网卡配置

sudo vi /etc/network/interfaces

写入下面的内容

auto lo
iface lo inet loopback
auto eth0
iface eth0 inet manual
up ifconfig eth0 0.0.0.0 up
auto br0
iface br0 inet dhcp
  bridge_ports eth0
  bridge_stp off
  bridge_maxwait 1

配置 qemu 虚拟机的网卡信息:

sudo vi /etc/qemu-ifup

将原来的内容注释,换成下面的内容:

echo "Executing /etc/qemu-ifup"
echo "bridge networking"
echo "Bringing up $1 for bridge mode"
sudo /sbin/ifconfig $1 0.0.0.0 promisc up
echo "Adding $1 to br0"
sudo /sbin/brctl addif br0 $1
sleep 3

之后开启 br0 网卡,并重启网卡生效

sudo ifup br0

sudo /etc/init.d/networking restart

输入下面的的命令,进入之后系统是这样的

sudo qemu-system-mips -M malta -kernel vmlinux-2.6.32-5-4kc-malta -hda debian_squeeze_mipsel_standard.qcow2 -append "root=/dev/sda1 console=tty0" -net nic, -net tap -nographic

进去虚拟机之后,如果发现只有网卡的其他信息、没有 IP 地址,可以手动配置一下 eth0 网卡的 IP

ifconfig eth0 192.168.123.150/24

这边的网段需要和 ubuntu 上的 br0 网卡位于同一网段上。

参考资料

https://xz.aliyun.com/t/462
https://bbs.pediy.com/thread-212369.htm
https://blog.csdn.net/ldl22847/article/details/8612993

源链接

Hacking more

...