最近在学习 IOT 安全这方面的知识,相信入门学这块都是从路由器的漏洞挖掘开始起步的。为了测试路由器漏洞必定要搭建环境,一般都是使用模拟的仿真环境而不是使用真机。固件仿真可以用于许多不通的目的,比如提供一个更好的方法来分析固件,测试利用,完成远程调试等。
一般模拟环境会使用 qemu 或者 AttifyOS VM搭建,两者算是各有优势吧。这里我选择了 qemu。笔者在搭建环境的时候遇到了很多问题,踩了不少坑,对照这《揭秘家用路由器 0day 漏洞挖掘技术》和网上的资料。但是网上的解决方案大多都是不太全或者讲的含糊不清。这里较详细地总结记录一下自己在搭建整个环境中遇到的一些问题,希望能给有需要的读者一些帮助和启发。
QEMU 是一个面向完整 PC 系统的开源仿真器。除了仿真处理器外,QEMU 还允许仿真所有必要的子系统,如连网硬件和视频硬件。它还允许实现高级概念上的仿真(如对称多处理系统(多达 255 个 CPU)和其他处理器架构(如 ARM 和 PowerPC)。
这里的 qemu 虚拟机的搭建就是在 Vm Ubuntu 虚拟机下再使用 qemu 来搭建一个 mips 系统的虚拟机,将路由器系统固件放在里面运行。
这两个工具的安装比较简单,也没啥问题,就安装书上的步骤来了。
sudo apt-get install binwalk
或者
sudo git clone https://github.com/devttys0/binwalk.git
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
这个网上的安装教程很多,安装过程中也不会出现什么太多的问题
sudo apt-get install qemu
正常的安装步骤是按照《揭秘家用路由器 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
在 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
在编写共享库的时候,经常需要根据路由器是大端程序或者是小端程序来选择编译,否则会报下面的错,不是一个 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
在模拟路由器 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
按照安装教程下载好内核驱动之后,使用下面的命令打开,发现整个就黑屏了
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 反汇编工具,支持伪代码的反编译
直接在下面的网站下载,直接打开就可以使用,缺点是试用版的不能将里面的代码复制出来。
https://www.pnfsoftware.com/jeb2/mips
在反编译窗口右键 -> 解析,就能看到相应的伪代码
这个是 IDA 中的插件,用着很方便。但是这个安装比较麻烦,需要编译一大堆东西,笔者太菜了搞了好次没出来
这里还是贴出 sw 师傅的安装教程,大佬们可以研究一下:
https://bbs.pediy.com/thread-230290.htm
关于两个工具的使用可以看看 ctf 的题目:
https://blog.csdn.net/qq_33438733/article/details/80233448
编译本地网卡配置
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