SSDP协议

SSDP协议

0x01何为SSDP

SSDP 使用一个固定的组播地址 239.255.255.250 和 UDP 端口号 1900 来监听其他设备的请求。SSDP 协议的请求消息有两种类型,第一种是服务通知,设备和服务使用此类通知消息声明自己存在;第二种是查询请求,协议客户端用此请求查询某种类型的设备和服务。

“为了能被网络搜索发现,目标设备应该向发起多播请求的源IP地址及端口发送单播UDP响应。如果M-SEARCH请求报文的ST头部字段以“ssdp:all”、“upnp:rootdevice”或者“uuid:”开头,后面跟着与设备相匹配的UUID信息,或者如果M-SERCH请求与设备支持的设备类型或服务类型相匹配,那么该设备就会应答M-SEARCH请求报文”。这种策略在实际环境中能够正常工作。例如,我的Chrome浏览器经常会请求搜索智能电视:

1
2
3
4
5
6
7
$ sudo tcpdump -ni eth0 udp and port 1900 -A IP 192.168.1.124.53044 > 239.255.255.250.1900: UDP, length 175   
M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
MAN: "ssdp:discover"
MX: 1
ST: urn:dial-multiscreen-org:service:dial:1
USER-AGENT: Google Chrome/58.0.3029.110 Windows

这个报文被发往一个多播IP地址。监听这一地址的其他设备如果与报文头部中指定的ST(search-target,搜索目标)多屏幕类型设备相匹配,那么这些设备应该会响应这个请求报文。除了请求具体的设备类型,请求报文中还可以包含两类“通用的”ST查询类型:
1、upnp:rootdevice:搜索root设备
2、ssdp:all:搜索所有的UPnP设备以及服务你可以运行以下python脚本(在另一脚本的基础上修改而得),使用前面提到的这些ST查询类型来枚举网络中的设备列表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

#!/usr/bin/env python2
import socket
import sys dst = "239.255.255.250"
if len(sys.argv) > 1:
dst = sys.argv[1]
st = "upnp:rootdevice"
if len(sys.argv) > 2:
st = sys.argv[2]
msg = [
'M-SEARCH * HTTP/1.1',
'Host:239.255.255.250:1900',
'ST:%s' % (st,),
'Man:"ssdp:discover"',
'MX:1', ''] s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
s.settimeout(10)
s.sendto('rn'.join(msg), (dst, 1900) )
while True:
try:
data, addr = s.recvfrom(32*1024)
except socket.timeout:
break
print "[+] %sn%s" % (addr, data)

0x02设备查询

当一个客户端接入网络的时候,它可以向一个特定的多播地址的 SSDP 端口使用 M-SEARCH 方法发送 “ssdp:discover” 消息。当设备监听到这个保留的多播地址上由控制点发送的消息的时候,设备将通过单播的方式直接响应控制点的请求。

典型的设备查询请求消息格式:

1
2
3
4
5
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

响应消息

响应消息应该包含服务的位置信息(Location 或AL头),ST和USN头。响应消息应该包含cache控制信息(max-age 或者 Expires头)。

典型的响应消息格式:

1
2
3
4
5
HTTP/1.1 200 OK
Cache-Control: max-age= seconds until advertisement expires
S: uuid:ijklmnop-7dec-11d0-a765-00a0c91e6bf6
Location: URL for UPnP description for root device
Cache-Control: no-cache="Ext",max-age=5000ST:ge:fridge // search targetUSN: uuid:abcdefgh-7dec-11d0-a765-00a0c91e6bf6

设备通知消息

在设备加入网络时,它应当向一个特定的多播地址的 SSDP 端口使用 NOTIFY 方法发送 “ssdp:alive” 消息,以便宣布自己的存在,更新期限信息,更新位置信息。

1 ssdp:alive 消息

由于 UDP 协议是不可信的,设备应该定期发送它的公告消息。在设备加入网络时,它必须用 NOTIFY 方法发送一个多播传送请求。NOTIFY 方法发送的请求没有回应消息。

典型的设备通知消息格式如下:

1
2
3
4
5
6
7

NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900
CACHE-CONTROL: max-age = seconds until advertisement expires
LOCATION: URL for UPnP description for root deviceNT: search target
NTS: ssdp:alive
USN: advertisement UUID

2 ssdp:byebye消息

当一个设备计划从网络上卸载的时候,它也应当向一个特定的多播地址的 SSDP 端口使用 NOTIFY 方法发送 “ssdp:byebye” 消息。但是,即使没有发送 “ssdp:byebye” 消息,控制点也会根据 “ssdp:alive” 消息指定的超时值,将超时并且没有再次收到的 “ssdp:alive” 消息对应的设备认为是失效的设备。

典型的设备卸载消息格式如下:

1
2
3
4
NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900NT: search target
NTS: ssdp:byebye
USN: advertisement UUID

参考

P2P 网络核心技术:UPnP 和 SSDP 协议 - 知乎 (zhihu.com)

-------------本文结束感谢您的阅读-------------
+ +