介绍
华为 HG532 系列路由器是一款为家庭和小型办公用户打造的高速无线路由器产品。
该漏洞被用来作为病毒 Mirai 的升级版变种 OKIRU/SATORI,payload 由蜜罐所捕获而被发现的,首次披露是由 checkpoint 所披露,漏洞利用的是 upnp 服务存在的注入漏洞实现任意命令执行。
固件分析
首先下载固件,我也保存了一份固件。
使用 binwalk 解压固件:
看一下二进制:
$ file bin/busybox
bin/busybox: ELF 32-bit MSB executable, MIPS, MIPS32 rel2 version 1 (SYSV), dynamically linked, interpreter /lib/ld-uClibc.so.0, no section header
$ readelf -h bin/busybox
ELF Header:
Magic: 7f 45 4c 46 01 02 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, big endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: MIPS R3000
Version: 0x1
Entry point address: 0x403f50
Start of program headers: 52 (bytes into file)
Start of section headers: 0 (bytes into file)
Flags: 0x70001007, noreorder, pic, cpic, o32, mips32r2
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 8
Size of section headers: 0 (bytes)
Number of section headers: 0
Section header string table index: 0
可以看出是 MIPS 大端的架构。
环境搭建
Qemu 网络配置
Init.D
auto br0
iface br0 inet dhcp # 网桥使用DHCP模式,从DHCP服务器获取IP
bridge_ports enp3s0 # 网卡名称,网桥创建前连接外部的网卡,可通过ifconfig命令查看,有IP地址的就是
bridge_stp on # 避免数据链路出现死循环
bridge_fd 0 # 将转发延迟设置为0
netplan
在 Ubuntu 22.04 中是使用 netplan → NetworkManager 管理网络的,参考这篇文章搭建 br0 网桥。之后直接按照下面的方法运行 qemu 虚拟机即可。
Linux 镜像下载
到 https://people.debian.org/~aurel32/qemu/mips/ 下载 debian-mips-qemu 镜像文件,这里下载 debian_squeeze_mips_standard.qcow2 和 vmlinux-2.6.32-5-4kc-malta 这两个文件。
启动镜像
此时网络仍然不通,因为这个虚拟机使用的网卡是 eth0,我们需要将其修改为 eth1。在虚拟机中:
将所有的 eth0 改为 eth1,保存,然后:
接下来就可以用 ssh 连接上了。连接时可能会出现报错:
Unable to negotiate with 192.168.202.141 port 22: no matching host key type found. Their offer: ssh-rsa,ssh-dss
这是因为 OpenSSH 7.0 以后的版本不再支持 ssh-dss (DSA)算法,解决方法是增加选项-oHostKeyAlgorithms=+ssh-dss, 即可成功解决。
接下来将我们解压出来的文件系统拷贝到 qemu:
漏洞复现
公开的漏洞 Poc 为:
看一下 PoC:
关键字为 ctrl
和 DeviceUpgrade
,端口号为 37215,搜索一下关键字:
直接运行会出问题,我们切换根目录到拷贝进来的系统文件中
先后运行 upnp 和 mic,使用 lsof -i:37215
可以查看端口是否运行,通过
查看 mic 是否启动成功
之后就可以运行 exp 了,这里我修改了两处:
在运行 PoC 之后,mic 界面可以看到运行结果:
原理分析
首先进入处理 NewStatusURL 的逻辑。用 IDA 打开 upnp,然后搜索 NewStatusURL 字符串。之后查看这个字符串的交叉引用,进入代码段,我们可以在这里创造一个函数,然后反编译:
在这个函数中,获取 NewStatusURL
这个 Node 之后直接用 snprintf(v6, 1024, "upg -g -U %s -t '1 Firmware Upgrade Image' -c upnp -r %s -d -b", v4);
拼接起来了,拼接之后就执行 system()
函数,这样我们就可以直接利用这个漏洞了。