MENU

UPnP安全(二):UPnP协议具体流程

January 9, 2019 • 安全技术,编程开发

在第一篇中对UPnP协议体系做了简单介绍,并没有涉及到具体的协议技术细节。

在本篇中将会对UPnP的整个流程进行仔细的梳理,并且结合实际的例子,对每个步骤进行讲解。

UPnP工作流程

整个工作过程需要处理六个方面的内容,即地址分配、发现设备、对设备的描述、设备控制、设备事件、设备展示。

下面的图片对过程描述的很清楚。

UPnP工作流程

1.寻址(Addressing)

地址是整个UPnP系统工作的基础条件,每个设备都应当是DHCP的客户。

当设备首次与网络建立连接后,利用DHCP服务,使设备得到一个IP地址。这个IP地址可以是DHCP系统指定的,也可以是由设备选择的。

2. 发现(Discovery)

可分成两种情况:

  • 在有控制请求之后,在当前的网络中查找有无对应的可用设备
  • 某一设备接入网络、取得IP地址之后,就开始向网络“广播”自己已经进入网络,即寻找控制请求

UPnP使用简单发现协议(SSDP)来完成发现,这是一个工作在UDP上的HTTP协议。

当一个设备加入网络,它将向组播发送类似如下的消息:

NOTIFY * HTTP/1.1
Host:239.255.255.250:1900
Cache-control:max-age=1800
Location:http://192.168.0.1:49152/des.xml
Nt:upnp:rootdevice
Nts:ssdp:alive
Usn:uuid:de5d6118-bfcb-918e-0000-00001eccef34::upnp:rootdevice
  • Host:这里必须使用IANA(InternetAssigned Numbers Authority)为SSDP预留的组播地址:239.255.255.250:1900
  • Cache-control:max-age的数值表明设备将在这段时间(单位为秒)后失效
  • Location:设备描述文件的URL
  • Nt:Notification Type,这里的值upnp:rootdevice)表明这是一个“根设备”。每个设备可以有自己的子设备。
  • Nts:Notification Sub Type,标准规定必须是ssdp:alive。
  • Usn:Unique Service Name,是一个设备实例的标识符。

通过这样的消息,控制点便可以知道网络中的设备。

控制点加入网络时,它也将组播一个消息,用来发现设备:

M-SEARCH* HTTP/1.1
Host:239.255.255.250:1900
Man:"ssdp:discover"
Mx:5
ST:ssdp:rootdevice
  • Host:同上。
  • Man:必须是“ssdp:discover”。
  • Mx:1到5之间的一个值,表示最大的等待应答的秒数。
  • ST:Seatch Targer,表示搜索的节点类型。

设备可以根据这样的搜索产生应答

HTTP/1.1200 OK
Cache-control:max-age=1800
Ext:
Location:http://192.168.0.1:2345/xx.xml
Server:Microsoft-Windows-NT/5.1UPnP/1.0 UPnP-Device-Host/1.0
ST:ST:urn:schemas-upnp-org:service:ContentDirectory:1
USN:uuid:60b2e186-b084-44af-ac09-1c64ea1bb364::urn:schemas-upnp-org:service:ContentDirectory:1

3. 描述(Description)

简单说,这是声明“自己”是什么样的设备,例如名称、制造厂商、序列号码等等。

刚开始“发现”设备后,控制点对这个设备的“了解”还很少,需要依据URL找到该设备的描述文件,从这些文件中读取更多的描述信息。

描述信息的范围很广,一般都是由设备的制造厂商提供的。主要的描述项目有:控制的模式名称和模式号码、设备序列号、制造厂商名称、厂商的WEB的URL等等。这些一般都存放在特定的XML文件中。这个XML文件在SSDP的响应数据包中有告知:Location:http://192.168.0.1:2345/xx.xml

该XML中的描述就可以抽象成如下图片:

upnp_description.png

设备的描述通过HTTP协议来完成。例如下面就是一个真实设备返回的XML信息:

Description.png

  • 对于每一个设备:
  • deviceType:设备类型,格式为:“urn:schemas-upnp-org:device:deviceType:v”

    • 这里deviceType和v是由设备定义的
  • friendlyName:一个更加友好的设备名
  • Manufacturer:制造商
  • modeName:型号
  • UDN:Unique Device Name,设备的UUID
  • serviceList:服务列表。
  • 对于每一个服务:(注意:这里的三个URL很重要

    • serviceType:与deviceType类似,这里的后两段由服务定义
    • serviceId:服务ID,通常于serviceType对应
    • controlURL:用于控制的URL
    • eventSubURL:用于订阅事件的URL
    • SCPDURL:服务描述的URL

一个服务描述(即SCPD地址中的XML)的示例如下:

SCPD.png

可以看出,Service Control Protocol Document的XML最外层主要由两个部分构成:

actionList定义了“行为”

  • 每个action由name和argumentList组成
  • 每个argument都由一个名称(name)、传递方向(direction,取值in或者out)、关联状态变数(relatedStateVariable)组成。
  • 状态变数用来标明UPnP设备或程序的一些状态。一个程序可以订阅(subscribe)状态的变化,从而得到通知。而一个参数之所以必须关联一个状态变数,是因为状态变数的类型决定了参数的类型。

serviceStateTable定义了“状态变数”

4. 控制(Control)

控制点找到设备描述之后,会从描述中(即XML文件)“提炼”出要进行的操作并获悉所有的服务。

对每个UPnP设备来说,这些描述必须是很确切、很详细的,描述中可能包含有命令或行为列表、服务响应信息、用到的参数等等。

对于服务的每个行为,也伴有描述信息:主要是整个服务进行期间的变量、变量的数据类型、可用的取值范围和事件的特征。

要控制某个设备,控制点必须先发送一个控制行为请求,要求设备开始服务,然后再按设备的URL发送相应的控制消息,控制消息就是放置在SCPDXML文件中的那些SOAP格式的信息。最后,服务会返回响应信息,指出服务是成功或是失败。

UPnP使用SOAP完成控制。SOAP工作在HTTP上,使用XML来描述远程调用并返回结果。这个SOAP的格式可以参见这里的官方PPT

upnp_soap_req.png

actionName和argumentName就是在协议描述(SCPDXML)中定义的行为名称和参数名称。

而调用的结果同样以XML方式返回,对应格式为:

upnp_soap_res.png

这里给出一个具体的例子,获取设备外网IP:

upnp_service_control.png

POST /ctl/IPConn HTTP/1.1
Host: 161.18.56.134:54395
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
Connection: close
Content-Type: text/xml; charset=utf-8
SOAPACTION: urn:schemas-upnp-org:service:WANIPConnection:1
Content-Length: 283

<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Body>
        <u:GetExternalIPAddress xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1#GetExternalIPAddress">
        </u:GetExternalIPAddress>
    </s:Body>
</s:Envelope>

5. 事件(Eveting)

在服务进行的整个时间内,只要变量值发生了变化或者模式的状态发生了改变,就产生了一个事件,系统将修改上述提到的事件列表的内容。

随之,事件服务器把事件向整个网络进行广播。另一方面,控制点也可以事先向事件服务器预约事件信息,保证将该控制点感兴趣的事件及时准确地传送过来。

广播或预约事件,传送的都是事件消息,事件消息也放在XML文件中,使用的格式是GENA。

设备投入工作之前的准备―――初始化过程,也是一个事件,初始化需要的各种信息也是用事件消息传送的。包括的内容主要是:变量初始值,模式的初始状态等等。

订阅的URL事在服务描述中给出的(如eventSubURL)。

SUBSCRIBE publisher pathHTTP/1.1
HOST: publisherhost:publisher port
USER-AGENT: OS/versionUPnP/1.1 product/version
CALLBACK: <deliveryURL>
NT: upnp:event
  • NT取upnp:event表示订阅事件
  • CALLBACK的值是回调的URL。

与之对应的事订阅的应答:

HTTP/1.1 200 OK
DATE: when response was generated
SERVER: OS/version UPnP/1.1 product/version
SID: uuid:subscription-UUID
CONTENT-LENGTH: 0
TIMEOUT: Second-1800
  • SID:本订阅的标识符,通常使用UUID
  • TIMETOUT:这里的值表示本订阅的有效期。这意味着在超时前,必须续订。

续订的请求与订阅类似,只是附加了SID:

SUBSCRIBE publisher path HTTP/1.1
HOST: publisher host:publisher port
SID: uuid:subscription UUID

退订也类似:

UNSUBSCRIBE publisher path HTTP/1.1
HOST: publisher host:publisher port
SID: uuid:subscription UUID

事件消息:

NOTIFY delivery path HTTP/1.1
HOST: delivery host:delivery port
CONTENT-TYPE: text/xml; charset="utf-8"
NT: upnp:event
NTS: upnp:propchange
SID: uuid:subscription-UUID
SEQ: event key
CONTENT-LENGTH: bytes in body
 
<?xml version="1.0"?>
<e:propertysetxmlns:e="urn:schemas-upnp-org:event-1-0">
    <e:property>
       <variableName>new value</variableName>
    </e:property>
</e:propertyset>
  • 每个产生事件的状态变数对应一个e:property标识,variableName是变数名
  • SEQ是消息的顺序号,从0开始
  • 当订阅者收到消息之后,必须在30秒内发送确认
  • 如果订阅者没有确认,设备仍然会发送之后的消息,直到本次订阅超时

6. 展示(Presentation)

只要得到了设备的URL,就可以取得该设备表达页面的URL,然后可以将此表达(展示)纳入用户的本地浏览器上。

presentation.png

这部分还包括与用户对话的界面,以及与用户进行会话的处理。

presentation_general.png

参考资料

Tags: UPnP
Archives QR Code
QR Code for this page
Tipping QR Code