最近打算针对一个类型的漏洞进行仔细的分析,希望能通过这个漏洞的分析总结归纳出具有这个漏洞的设备的特点,利于指导之后的漏洞挖掘。
目前的分析思路:
1. 首先分析该漏洞在DIR-859上的形成原因,利用思路。
2. 查看其他受影响的设备漏洞形成原因和利用方式与该DIR-859上有何不同
3. 研究官方补丁,看看官方如何修补该漏洞
4. 研究除了DLINk系列,其他系列的设备处理SSDP的流程是否也存在类似问题
0x01 漏洞概述
主要是在ssdpcgi函数中发现了该漏洞,且因为SSDP协议缘故,该漏洞利用无须通过认证
漏洞起因主要是因为环境变量没有进行字符过滤
漏洞研究版本
1
2
3型号:DIR-859
固件版本:1.06b01 Beta01,1.05
架构:MIPS 32位目前搜集到的受影响的Dlink版本
0x02 漏洞分析
首先分析一下这个ssdpcgi函数的逻辑
首先是a1,也就是参数个数。随后获取了四个环境变量
HTTP_ST这个字段主要是关系到搜索的方式,根据函数逻辑一共有4种发现设备的方式ssdp:all 搜索所有的UPnP设备以及服务
upnp:rootdevice:搜索root设备
uuid: 查询特定uuid的设备
urn: 查询指定类型的设备
以下是四种情况的处理流程,可以看到最终都会执行lxmldbc_system这个函数来执行M-SEARCH.sh这个脚本来查询设备
最后执行的命令基本格式就是两种,xxxx就是可以注入的位置
1 | /etc/scripts/upnp/M-SEARCH.sh ssdpall adddr:port id & |
所以只要将ST字段设置为uuid或者urn就可以在最后拼接自己构造的ST
还有就是其他人的poc都是说只能用urn:构造后利用。但我觉得uuid也是可以的。
现在我先把路由器模拟起来试一下,使用firmadyne进行模拟
尝试如此构造header注入,成功
1 | [+] Preparando Header ... |
果然uuid也可以,header的ST部分也可以如此构造
1 | header += "ST:uuid:1;telnetd\n" |
测试使用的反向连接poc脚本
1 | #!/usr/bin/python |
0x03 针对DIR859上漏洞的总结
经过分析我觉得造成这个UPnp漏洞的原因主要有以下两点
- 环境变量并未进行字符过滤
- 利用SSDP进行查询时,发现根设备和遍历设备两种模式都不需要额外参数,因此不会造成命令执行注入。但是针对于特定类型设备的查询时比如利用uuid和urn来指定时,指定的信息会成为system命令执行参数的一部分,而这部分就可以造成命令执行注入了。而且包括REMOTE_ADDR和REMOTE_PORT是都没有对其进行过滤,因此这两个是也可以注入的
0x04 其他DLink路由器上的ssdpcgi行为分析
1 DIR885L
DIR885LA (1.20b02) 是已经经过了修补的
首先一样的是获取四个环境变量的操作,但是sub_17788对ST进行了一些操作
让我们跟进sub_17788看看其做了什么操作,发现
1 | int __fastcall sub_17788(const char *a1) |
2 DIR-865L
版本1.07b01
漏洞与DIR-859基本没有区别,漏洞点与漏洞代码完全一致
0x05 其他厂商路由器对SSDP的实现
1 ASUS WRT-AC66U
利用下面这个命令找到usr/sbin/miniupnpd,这个二进制文件应该是提供SSDP服务的
看名称感觉华硕使用的是开源的miniupnp模块
1 | grep -rnl "upnp" |
接着逆向分析固件,搜索ssdp相关函数(也可以搜索ST字符串)找到对应的逻辑
同样关注点在选择特定参数或者uuid的查询上,核心逻辑就是下面这个图
可以看到他每次查询都是从一个已经查询好的列表里不停匹配(rootDevice),匹配成功了就返回成功的结果,不存在用户输入被执行了的结果
2 FAST-FER 450
与AC66U一样,同样使用miniupnpd,代码基本一致
3 网剑R6700
自己实现的一个过程,完整过程还需研究
参考
CVE-2019–17621: D-Link DIR-859 未授权命令执行漏洞分析 - 安全客,安全资讯平台 (anquanke.com)