马住
前言
学了一段时间的固件漏洞挖掘和复现,发现搭建环境还是一个很大的坑,在运行不同的固件时老是会出现各种各种的错误,这里再补充一下关于 qemu 环境搭建的过程中的一些细节和出现的问题。希望对入门的朋友有所帮助。
qemu 版本
- qemu 版本最好选择的是 2.4.0 的。
版本过低,在用户模式下会出现 Invalid ELF image for this architecture
的问题(大小端正确的前提下);
版本过高,在使用 firmadyne 模拟固件时,会出现 Invalid parameter 'vlan'
的问题。
这个就需要自己去官网下载一个,然后放在本地进行编译。
下载地址:https://download.qemu.org/
编译方法:
./configure
sudo make -j8
sudo make install
查看版本号:
qemu-system 模式下虚拟网卡的设置
之前在这里 讲到说用编译 /etc/network/interfaces
文件的方法搭建一个网桥的方法来建立网卡,但是这里会出现各种各种莫名其妙的问题。
最简单的办法就是直接使用 tunctl 命令来建立一个虚拟网卡,与模拟的 mips 虚拟机进行通信。
- 这里是参考了这篇文章:https://paper.seebug.org/879/
在本地执行:
$ sudo tunctl -t tap0 -u `whoami` # 为了与 QEMU 虚拟机通信,添加一个虚拟网卡
$ sudo ifconfig tap0 10.0.0.2/24 # 为添加的虚拟网卡配置 IP 地址
模拟起来虚拟机之后,在虚拟机中执行:
sudo ifconfig eth0 10.0.0.1/24
可以互相 ping 通的话就说明成功建立了链接。
在虚拟机和宿主机之间建立网桥
目的:使得虚拟机也可以连接外网
在宿主机执行下面的命令:
sudo brctl addbr virbr0 // brctl 命令添加网桥
sudo brctl addif virbr0 eth0 // 在网桥上添加 eth0 网口,也就是网桥的一端是 eth0 接口
tunctl -t br0 -u `whoami` // 和上面一样,设置虚拟网卡
ifconfig br0 10.0.0.1 // 配置虚拟网卡的地址
sudo brctl addif virbr0 br0 // 把 br0 作为 virbr0 网桥的另一端
2 . 在 /etc/network/interfaces
配置文件中添加:
auto lo
iface lo inet loopback
auto virbr0
iface virbr0 inet dhcp
bridge_ports eth0 // 将网桥的对外出口设置为 eth0 ,这样就可以连接外网了
3 . 在虚拟机中执行:
ifconfig eth0 10.0.0.2
简单画一个图,应该就可以理解了
使用用户模式模拟 cgi 部分函数的问题
根据《揭秘家用路由器 0day 漏洞挖掘》 书中,复现 DIR-815 漏洞时的 sh 脚本,这里可能会遇到两个小问题:
echo "$INPUT" | chroot . ./qemu -E CONTENT_LENGTH=$LEN -E CONTENT_TYPE="application/x-www-form-urlencoded" -E REQUEST_METHOD="POST" -E HTTP_COOKIE=$TEST -E REQUEST_URI="/hedwig.cgi" -E REMOTE_ADDR="192.168.1.1" -g $PORT /htdocs/web/hedwig.cgi 2>/dev/null
- 找不到
/htdocs/web/hedwig.cgi
文件
这是因为在使用 binwalk 进行固件解压时,将文件系统解压到了只读文件目录/文件系统,导致符号软链接无法建立(手动也不行),解决方法是换一个目录(如 /home 目录下) - qemu 运行的文件只能为 xxx.cgi 的原因
因为在调用 cgi 时,main 函数中根据传入的 argv[1] 的值来判断需要交给哪一个 cgi 函数来处理。如果是调用qemu -L ./ ./htdocs/cgibin
的话就会出问题,此时的 argv[1] 就为 cgibin ,会报错。
若使用的是符号链接的话,argv1 就为符号名本身,可以正常通过 main 函数的判断,还可以直接根据符号链接到 cgibin 来直接调用他。
在 IDA 中看模块的调用会比较清晰:
firmdyne 使用过程中出现的问题
- 无网卡 IP
可能是因为虚拟的网卡设备出现了冲突或者模拟过程中系统出现了一些其他一些不可预知的问题。解决方法就是放在 qemu 的系统模式下跑。 - 模拟起来 IP 地址是 169.254 开头的地址,这是一个特殊的地址,网上的解释是使用 DHCP 分派 IP 地址失败后获取的一个 IP。反正就是从外部无法访问这个 IP 地址。
ubuntu@VM-0-3-ubuntu:~/iot/firmware-analysis-toolkit/firmadyne$ Querying database for architecture... Password for user firmadyne: mipseb Running firmware 9: terminating after 60 secs... qemu: terminating on signal 2 from pid 10796 Inferring network... Interfaces: [('br0', '169.254.221.93')] Done!
解决方法还是放在 qemu-system 下运行,以 DlINK 某型号路由器为例,遇到了丢到系统模式下也跑不起来的问题(运行 /etc/init.d/rcS),扫描端口发现 80 端口也没起来。
使用 ssh 连上,ps -aux 发现 http 服务起来了,但是外部访问不了。
这边看到有一个 /var/run/httpd.conf
配置文件,于是打开他,看到了问题的所在。这里配置文件中原来绑定的是 lo 网卡,但是我们设置的虚拟机是共享网卡(按照上面说的那种使用 tunctl 共享网卡的方法),所以需要把网卡接口(Interface)设置成于宿主机 tap0 网卡共享的 eth0 网卡。
也就是按图上改,改完之后在虚拟机中再运行命令:httpd -f /var/run/httpd.conf
即可。
开启之后发现 80 端口也起来了。
编译静态 GDB 问题
官网下载源码:http://ftp.gnu.org/gnu/gdb/
编译、安装命令:
./configure --target=mipsel-linux --host=mipsel-linux --program-prefix=mipsel-linux --prefix=`echo $PWD`/bin CC=/home/nick/iot/tools/buildroot/output/host/bin/mipsel-linux-gcc CXX=/home/nick/iot/tools/buildroot/output/host/bin/mipsel-linux-g++ AR=/home/nick/iot/tools/buildroot/output/host/bin/mipsel-linux-ar LD=/home/nick/iot/tools/buildroot/output/host/bin/mipsel-linux-ld RANLIB=/home/nick/iot/tools/buildroot/output/host/bin/mipsel-linux-ranlib STRIP=/home/nick/iot/tools/buildroot/output/host/bin/mipsel-linux-strip CFLAGS="-w -static" CXXFLAGS="-w -static" LDFLAGS="-static"
sudo make -j8
make install
CC、CXX、AR... 都是交叉编译工具的绝对路径。
问题 1:
解决方法就是在执行 ./configure
时加上 AR=...(交叉编译的绝对路径)。
- 问题 2:
这里推荐安装 7.10 版本的,版本太高的会出现configure: error: ***A compiler with support for c++11 language features is required.
的问题,版本太低会出现下面的问题:
解决方法应该来说是下面这样的,但是发现本地试了还是不行。。所以还是自己编译一个合适的版本。
https://blog.csdn.net/ai2000ai/article/details/50441845
- 问题 3:
编译完之后还是运行不起来,那就用 github 上的吧。
- 问题 4:
提示下面的错误:
把 ./configure 文件在这个错误上面中, != 强行改成 == 即可。
其他错误
- 使用 chroot 命令来设置运行环境的根目录时,会提示
No such file or directory
的问题,暂时不知道是什么原因,可以先使用其他相关命令的替代来解决:
qemu-mips --> qemu-mips-static
qemu-mipsel --> qemu-mipsel-static
- 这应该是《揭秘家用路由器 0day 漏洞挖掘》 那本书上一个坑,不知道是书中的错误还是本地环境的差异。
另外一些摸不着头脑的错误:
- 关于 firmdyne 的使用过程中的错误
先在 github 上找找有没有类似的错误:https://github.com/firmadyne/firmadyne/issues,如果没有的话再 google ,再不行就问问其他人。