本文首发于xray社区:https://mp.weixin.qq.com/s/VK5CiWa5IIiMMwf–26miA
周末测了一下屋里的几个iot设备,顺便学习了一下对于UPnP的服务如何去挖掘漏洞。这里记录一下UPnP的学习笔记。
UPnP是因特网及LAN中使用的以TCP/IP协议为基础的技术。通过无线网络上网的用户都是处于内网,为了保证一些P2P软件正常工作,开启UPnP是必须的,而目前大多数无线路由器等iot设备都具有此功能。
只要 NAT 设备(路由器)支持 UPnP,并开启。那么,当我们的主机(或主机上的应用程序)向 NAT 设备发出端口映射请求的时候,NAT 设备就可以自动为主机分配端口并进行端口映射。
基于UPnP规范下有一个叫SSDP的协议。
SSDP全称是Simple Service Discover Protocol简单服务发现协议,这个协议是UPnP的核心,在UPnP中定义了一组协议框架,其中有控制点,根设备等概念,UPnP设备通过SSDP协议与根设备(用户设备)进行交互。SSDP是应用层协议,使用HTTPU和HTTPMU规范,基于UDP端口进行通信。
SSDP使用一个固定的组播地址239.255.255.250和UDP端口号1900来监听其他设备的请求。
SSDP 协议的请求消息有两种类型,第一种是服务通知,设备和服务使用此类通知消息声明自己存在;第二种是查询请求,协议客户端用此请求查询某种类型的设备和服务。
如果某个具备UPnP功能的计算机引导成功并连接到网络上,就会立刻向网络发出“广播”,向网络上的UPnP设备通知自己已经准备就绪,在程序设计这一级别上看,该广播内容就是一个M-SEARCH(消息)指示。该广播将被“声音所及”范围之内的所有设备所“听到”。并向该计算机反馈自己的有关信息,以备随后进行控制之用。
典型的设备查询请求消息格式:
M-SEARCH * HTTP/1.1
S:uuid:ijklmnop-7dec-11d0-a765-00a0c91e6bf6
Host:239.255.255.250:1900
Man:"ssdp:discover"ST:ge:fridge
MX:3
UPnP设备为了自身被找到,必须向发送查找请求的多播通道的源IP地址与端口发送响应信息。所以可以从239.255.255.250:1900这个地址接收到响应消息。类似下面的消息。
HTTP/1.1 200 OK
CACHE-CONTROL: max-age=100
DATE: Sun, 15 Jan 2006 06:51:02 GMT
EXT:
LOCATION: http://192.168.14.112:12341/upnpdev.xml
SERVER: TP-LINK Wireless Router WR541G/5, UPnP/1.0
ST: upnp:rootdevice
USN:uuid:upnp-InternetGatewayDevice-192168141678900001::upnp:rootdevice
注意LOCATION中的地址,对应的值会是一个UPnP设备的描述文档。
描述文档中会有设备的介绍、servicelist字段中会有提供的各种接口的信息,以及每个接口的文档地址。根据实际功能进行fuzz、手动测试都可以。
这里推荐一个py实现的UPnP技术利用项目:https://github.com/5kyc0d3r/upnpy
虽然有些bug,但是原理都很简单。只不过把我以上说的内容自动化了一下。
1. 向239.255.255.250:1900发送多播请求
2. 从返回包中LOCATION中获取到UPnP设备的描述文档地址(其实同时也获取到了UPnP设备的地址)
3. 从描述文档中获取每个接口的接口文档地址,在SCPDURL字段中。
4. 访问每个接口的接口文档地址,获取参数。
然后可以用upnpy提供的接口进行fuzz或是手工测试。
UPnP协议中有一个漏洞CVE-2020-12695,可以导致SSRF,问题是由于SUBSCRIBE函数规范中提供允许任何外部攻击者使用回调标头发送HTTP数据包并使用UPnP设备作为代理将请求发送到其他主机。
“订阅”功能在UPnP规范中定义,用于跟踪其他设备和服务中的更改。使用回调HTTP标头,可以定义设备将尝试连接到的任意URL。
大概包是这样子
SUBSCRIBE publisher_path HTTP/1.1
HOST: publisher_host:publisher_port
CALLBACK:
NT: upnp:event
TIMEOUT: Second-requested subscription duration
delivery_URL地址是回连的地址。注意<>
不可少。
推荐一个github项目CallStranger,可以方便于扫描局域网中的UPnP设备是否存在SSRF漏洞,由于集成并魔改了upnpy,所以更加的一键化利用: https://github.com/yunuscadirci/CallStranger
开启了UPnP服务的设备通常是对缓冲区(Buffer)的使用没有进行检查和限制。如果可以提取固件的话可以定位到相应的点去看,对照fuzz结果通常会有收获。
像Netgear R6400、DD-WRT等设备都出过类似的漏洞。通常IDA打开定位ssdp协议接收那边的实现即可。
推荐一个UPnP安全写的还比较全的文章:https://github.com/dhishan/UPnP-Hack
https://nieyong.github.io/wiki_ny/UPNP%E5%8D%8F%E8%AE%AE%E7%BB%86%E8%8A%82.html
https://www.secrss.com/articles/23462
https://www.exploit-db.com/exploits/49730
https://www.trendmicro.com/en_us/research/19/c/upnp-enabled-connected-devices-in-home-unpatched-known-vulnerabilities.html
https://www.helpnetsecurity.com/2020/06/09/cve-2020-12695/
https://ubunlog.com/zh-TW/upnp%E5%8D%94%E8%AD%B0%E4%B8%AD%E7%9A%84%E6%BC%8F%E6%B4%9E%E5%85%81%E8%A8%B1dos%E6%94%BB%E6%93%8A%E5%92%8C%E7%B6%B2%E7%B5%A1%E6%8E%83%E6%8F%8F/
https://www.secrss.com/articles/20131
https://github.com/5kyc0d3r/upnpy
https://zhuanlan.zhihu.com/p/40407669
https://www.nextt.top/luyouqi-upnp-shishenme-yiji-yingyong-fangshi/
https://github.com/SK-CERT/vuln-callstranger/blob/master/callstranger_scan.py
https://github.com/yunuscadirci/CallStranger