Stupidly Simple DDoS Protocol (SSDP) generates 100 Gbps DDoS via CloudFlares Blog

Color Coding Indoor Fiber Optic Cables
July 11, 2017
9/11 16 years later
September 11, 2017
Show all

Stupidly Simple DDoS Protocol (SSDP) generates 100 Gbps DDoS via CloudFlares Blog

Last month CloudFlare.com shared statistics on some popular reflection attacks. Back then the average SSDP attack size was ~12 Gbps and largest SSDP reflection we recorded was:

  • 30 Mpps (millions of packets per second)
  • 80 Gbps (billions of bits per second)
  • using 940k reflector IPs

This changed a couple of days ago when we noticed an unusually large SSDP amplification. It’s worth deeper investigation since it crossed the symbolic threshold of 100 Gbps.

The packets per second chart during the attack looked like this:

The bandwidth usage:

This packet flood lasted 38 minutes. According to our sampled netflow data it utilized 930k reflector servers. We estimate that the during 38 minutes of the attack each reflector sent 112k packets to Cloudflare.

The reflector servers are across the globe, with a large presence in Argentina, Russia and China. Here are the unique IPs per country:

$ cat ips-nf-ct.txt|uniq|cut -f 2|sort|uniq -c|sort -nr|head

439126 CN
135783 RU
74825 AR
51222 US
41353 TW
32850 CA
19558 MY
18962 CO
14234 BR
10824 KR
10334 UA
9103 IT …

 

The reflector IP distribution across ASNs is typical. It pretty much follows the world’s largest residential ISPs:


$ cat ips-nf-asn.txt |uniq|cut -f 2|sort|uniq -c|sort -nr|head

318405 4837 # CN China Unicom

84781 4134 # CN China Telecom

72301 22927 # AR Telefonica de Argentina

23823 3462 # TW Chunghwa Telecom

19518 6327 # CA Shaw Communications Inc.

19464 4788 # MY TM Net

18809 3816 # CO Colombia Telecomunicaciones

11328 28573 # BR Claro SA

7070 10796 # US Time Warner Cable Internet

6840 8402 # RU OJSC “Vimpelcom”

6604 3269 # IT Telecom Italia

6377 12768 # RU JSC “ER-Telecom Holding”

What’s SSDP anyway?

The attack was composed of UDP packets with source port 1900. This port is used by the SSDP and is used by the UPnP protocols. UPnP is one of the zero-configuration networking protocols. Most likely your home devices support it, allowing them to be easily discovered by your computer or phone. When a new device (like your laptop) joins the network, it can query the local network for specific devices, like internet gateways, audio systems, TVs, or printers. Read more on how UPnP compares to Bonjour.

UPnP is poorly standardised, but here’s a snippet from the spec about the M-SEARCH frame – the main method for discovery:

When a control point is added to the network, the UPnP discovery protocol allows that control point to search for devices of interest on the network. It does this by multicasting on the reserved address and port (239.255.255.250:1900) a search message with a pattern, or target, equal to a type or identifier for a device or service.

Responses to M-SEARCH frame:

To be found by a network search, a device shall send a unicast UDP response to the source IP address and port that sent the request to the multicast address. Devices respond if the ST header field of the M-SEARCH request is “ssdp:all”, “upnp:rootdevice”, “uuid:” followed by a UUID that exactly matches the one advertised by the device, or if the M-SEARCH request matches a device type or service type supported by the device.

This works in practice. For example, my Chrome browser regularly asks for a Smart TV I guess:

$ 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

This frame is sent to a multicast IP address. Other devices listening on that address and supporting this specific ST (search-target) multiscreen type are supposed to answer.

Apart from queries for specific device types, there are two “generic” ST query types:

  • upnp:rootdevice: search for root devices
  • ssdp:all: search for all UPnP devices and services

To emulate these queries you can run this python script (based on this work):

#!/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(‘\r\n’.join(msg), (dst, 1900) )

while True:
try:
data, addr = s.recvfrom(32*1024)
except socket.timeout:
break
print “[+] %s\n%s” % (addr, data)

On my home network two devices show up:

$ python ssdp-query.py
[+] (‘192.168.1.71’, 1026)
HTTP/1.1 200 OK
CACHE-CONTROL: max-age = 60
EXT:
LOCATION: http://192.168.1.71:5200/Printer.xml
SERVER: Network Printer Server UPnP/1.0 OS 1.29.00.44 06-17-2009
ST: upnp:rootdevice
USN: uuid:Samsung-Printer-1_0-mrgutenberg::upnp:rootdevice

[+] (‘192.168.1.70’, 36319)
HTTP/1.1 200 OK
Location: http://192.168.1.70:49154/MediaRenderer/desc.xml
Cache-Control: max-age=1800
Content-Length: 0
Server: Linux/3.2 UPnP/1.0 Network_Module/1.0 (RX-S601D)
EXT:
ST: upnp:rootdevice
USN: uuid:9ab0c000-f668-11de-9976-000adedd7411::upnp:rootdevice

The firewall

Now that we understand the basics of SSDP, understanding the reflection attack should be easy. You see, there are in fact two ways of delivering the M-SEARCH frame:

  • what we presented, over the multicast address
  • directly to a UPnP/SSDP enabled host on a normal unicast address

The latter method works. We can specifically target my printer IP address:

$ python ssdp-query.py 192.168.1.71
[+] ('192.168.1.71', 1026)
HTTP/1.1 200 OK 
CACHE-CONTROL: max-age = 60 
EXT: 
LOCATION: http://192.168.1.71:5200/Printer.xml 
SERVER: Network Printer Server UPnP/1.0 OS 1.29.00.44 06-17-2009 
ST: upnp:rootdevice 
USN: uuid:Samsung-Printer-1_0-mrgutenberg::upnp:rootdevice

Now the problem is easily seen: the SSDP protocol does not check whether the querying party is in the same network as the device. It will happily respond to an M-SEARCH delivered over the public Internet. All it takes is a tiny misconfiguration in a firewall – port 1900 UDP open to the world – and a perfect target for UDP amplification will be available.

Given a misconfigured target our script will happily work over the internet:

$ python ssdp-query.py 100.42.x.x
[+] ('100.42.x.x', 1900)
HTTP/1.1 200 OK 
CACHE-CONTROL: max-age=120 
ST: upnp:rootdevice 
USN: uuid:3e55ade9-c344-4baa-841b-826bda77dcb2::upnp:rootdevice 
EXT: 
SERVER: TBS/R2 UPnP/1.0 MiniUPnPd/1.2 
LOCATION: http://192.168.2.1:40464/rootDesc.xml

The amplification

The real damage is done by the ssdp:all ST type though. These responses are much larger:

$ python ssdp-query.py 100.42.x.x ssdp:all
[+] (‘100.42.x.x’, 1900)
HTTP/1.1 200 OK
CACHE-CONTROL: max-age=120
ST: upnp:rootdevice
USN: uuid:3e55ade9-c344-4baa-841b-826bda77dcb2::upnp:rootdevice
EXT:
SERVER: TBS/R2 UPnP/1.0 MiniUPnPd/1.2
LOCATION: http://192.168.2.1:40464/rootDesc.xml

[+] (‘100.42.x.x’, 1900)
HTTP/1.1 200 OK
CACHE-CONTROL: max-age=120
ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1
USN: uuid:3e55ade9-c344-4baa-841b-826bda77dcb2::urn:schemas-upnp-org:device:InternetGatewayDevice:1
EXT:
SERVER: TBS/R2 UPnP/1.0 MiniUPnPd/1.2
LOCATION: http://192.168.2.1:40464/rootDesc.xml

… 6 more response packets….

In this particular case, a single SSDP M-SEARCH packet triggered 8 response packets. tcpdump view:

$ sudo tcpdump -ni en7 host 100.42.x.x -ttttt
00:00:00.000000 IP 192.168.1.200.61794 > 100.42.x.x.1900: UDP, length 88
00:00:00.197481 IP 100.42.x.x.1900 > 192.168.1.200.61794: UDP, length 227
00:00:00.199634 IP 100.42.x.x.1900 > 192.168.1.200.61794: UDP, length 299
00:00:00.202938 IP 100.42.x.x.1900 > 192.168.1.200.61794: UDP, length 295
00:00:00.208425 IP 100.42.x.x.1900 > 192.168.1.200.61794: UDP, length 275
00:00:00.209496 IP 100.42.x.x.1900 > 192.168.1.200.61794: UDP, length 307
00:00:00.212795 IP 100.42.x.x.1900 > 192.168.1.200.61794: UDP, length 289
00:00:00.215522 IP 100.42.x.x.1900 > 192.168.1.200.61794: UDP, length 291
00:00:00.219190 IP 100.42.x.x.1900 > 192.168.1.200.61794: UDP, length 291

That target exposes 8x packet count amplification and 26x bandwidth amplification. Sadly, this is typical for SSDP.

IP Spoofing

The final step for the attack is to fool the vulnerable servers to flood the target IP – not the attacker. For that the attacker needs to spoof the source IP address on their queries.

We probed the reflector IPs used in the shown 100 Gbps+ attack. We found that out of the 920k reflector IPs, only 350k (38%) still respond to SSDP probes.

Out of the reflectors that responded, each sent on average 7 packets:

$ cat results-first-run.txt|cut -f 1|sort|uniq -c|sed -s 's#^ \+##g'|cut -d " " -f 1| ~/mmhistogram -t "Response packets per IP" -p
Response packets per IP min:1.00 avg:6.99 med=8.00 max:186.00 dev:4.44 count:350337 
Response packets per IP: 
 value |-------------------------------------------------- count
 0 | ****************************** 23.29%
 1 | **** 3.30%
 2 | ** 2.29%
 4 |************************************************** 38.73%
 8 | ************************************** 29.51%
 16 | *** 2.88%
 32 | 0.01%
 64 | 0.00%
 128 | 0.00%

The response packets had 321 bytes (+/- 29 bytes) on average. Our request packets had 110 bytes.

According to our measurements with the ssdp:all M-SEARCH attacker would be able to achieve:

  • 7x packet number amplification
  • 20x bandwidth amplification

We can estimate the 43 Mpps/112 Gbps attack was generated with roughly:

  • 6.1 Mpps of spoofing capacity
  • 5.6 Gbps of spoofed bandwidth

In other words: a single well connected 10 Gbps server able to perform IP spoofing can deliver a significant SSDP attack.

More on the SSDP servers

Since we probed the vulnerable SSDP servers, here are the most common Server header values we received:

 104833 Linux/2.4.22-1.2115.nptl UPnP/1.0 miniupnpd/1.0
 77329 System/1.0 UPnP/1.0 IGD/1.0
 66639 TBS/R2 UPnP/1.0 MiniUPnPd/1.2
 12863 Ubuntu/7.10 UPnP/1.0 miniupnpd/1.0
 11544 ASUSTeK UPnP/1.0 MiniUPnPd/1.4
 10827 miniupnpd/1.0 UPnP/1.0
 8070 Linux UPnP/1.0 Huawei-ATP-IGD
 7941 TBS/R2 UPnP/1.0 MiniUPnPd/1.4
 7546 Net-OS 5.xx UPnP/1.0
 6043 LINUX-2.6 UPnP/1.0 MiniUPnPd/1.5
 5482 Ubuntu/lucid UPnP/1.0 MiniUPnPd/1.4
 4720 AirTies/ASP 1.0 UPnP/1.0 miniupnpd/1.0
 4667 Linux/2.6.30.9, UPnP/1.0, Portable SDK for UPnP devices/1.6.6
 3334 Fedora/10 UPnP/1.0 MiniUPnPd/1.4
 2814 1.0
 2044 miniupnpd/1.5 UPnP/1.0
 1330 1
 1325 Linux/2.6.21.5, UPnP/1.0, Portable SDK for UPnP devices/1.6.6
 843 Allegro-Software-RomUpnp/4.07 UPnP/1.0 IGD/1.00
 776 Upnp/1.0 UPnP/1.0 IGD/1.00
 675 Unspecified, UPnP/1.0, Unspecified
 648 WNR2000v5 UPnP/1.0 miniupnpd/1.0
 562 MIPS LINUX/2.4 UPnP/1.0 miniupnpd/1.0
 518 Fedora/8 UPnP/1.0 miniupnpd/1.0
 372 Tenda UPnP/1.0 miniupnpd/1.0
 346 Ubuntu/10.10 UPnP/1.0 miniupnpd/1.0
 330 MF60/1.0 UPnP/1.0 miniupnpd/1.0
 ...

The most common ST header values we saw:

 298497 upnp:rootdevice
 158442 urn:schemas-upnp-org:device:InternetGatewayDevice:1
 151642 urn:schemas-upnp-org:device:WANDevice:1
 148593 urn:schemas-upnp-org:device:WANConnectionDevice:1
 147461 urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1
 146970 urn:schemas-upnp-org:service:WANIPConnection:1
 145602 urn:schemas-upnp-org:service:Layer3Forwarding:1
 113453 urn:schemas-upnp-org:service:WANPPPConnection:1
 100961 urn:schemas-upnp-org:device:InternetGatewayDevice:
 100180 urn:schemas-upnp-org:device:WANDevice:
 99017 urn:schemas-upnp-org:service:WANCommonInterfaceConfig:
 98112 urn:schemas-upnp-org:device:WANConnectionDevice:
 97246 urn:schemas-upnp-org:service:WANPPPConnection:
 96259 urn:schemas-upnp-org:service:WANIPConnection:
 93987 urn:schemas-upnp-org:service:Layer3Forwarding:
 91108 urn:schemas-wifialliance-org:device:WFADevice:
 90818 urn:schemas-wifialliance-org:service:WFAWLANConfig:
 35511 uuid:IGD{8c80f73f-4ba0-45fa-835d-042505d052be}000000000000
 9822 urn:schemas-upnp-org:service:WANEthernetLinkConfig:1
 7737 uuid:WAN{84807575-251b-4c02-954b-e8e2ba7216a9}000000000000
 6063 urn:schemas-microsoft-com:service:OSInfo:1
 ...

The vulnerable IPs are seem to be mostly unprotected home routers.

Open SSDP is a vulnerability

It’s not a novelty that allowing UDP port 1900 traffic from the Internet to your home printer or such is not a good idea. This problem has been known since at least January 2013:

Authors of SSDP clearly didn’t give any thought to UDP amplification potential. There are a number of obvious recommendations about future use of SSDP protocol:

  • The authors of SSDP should answer if there is any real world use of unicast M-SEARCHqueries. From what I understand M-SEARCH only makes practical sense as a multicast query in local area network.
  • Unicast M-SEARCH support should be either deprecated or at least rate limited, in similar way to DNS Response Rate Limit techniques.
  • M-SEARCH responses should be only delivered to local network. Responses routed over the network make little sense and open described vulnerability.

In the meantime we recommend:

  • Network administrators should ensure inbound UDP port 1900 is blocked on firewall.
  • Internet service providers should never allow IP spoofing to be performed on their network. IP spoofing is the true root cause of the issue. See the infamous BCP38.
  • Internet service providers should allow their customers to use BGP flowspec to rate limit inbound UDP source port 1900 traffic, to relieve congestion during large SSDP attacks.
  • Internet providers should internally collect netflow protocol samples. The netflow is needed to identify the true source of the attack. With netflow it’s trivial to answer questions like: “Which of my customers sent 6.4Mpps of traffic to port 1900?”. Due to privacy concerns we recommend collecting netflow samples with largest possible sampling value: 1 in 64k packets. This will be sufficient to track DDoS attacks while preserving decent privacy of single customer connections.
  • Developers should not roll out their own UDP protocols without careful consideration of UDP amplification problems. UPnP should be properly standardized and scrutinized.
  • End users are encouraged to use the script scan their network for UPnP enabled devices. Consider if these devices should be allowed to access to the internet.

Furthermore, we prepared on online checking website. Click if you want to know if your public IP address has a vulnerable SSDP service:

Sadly, the most unprotected routers we saw in the described attack were from China, Russia and Argentina, places not historically known for the most agile internet service providers.

Summary

For Fixed Wireless ISP’s  perhaps we should be doing what Cloudflare is doing for it’s own customers and protecting the users from SSDP and other L3 Amplification attackes.   Unfortunately the raising of SSDP attack sizes might be a tough problem for other Internet citizens. We should as an industry encourage all wISPs to stop IP spoofing within their network, support BGP flowspec and configure in netflow collection.

Leave a Reply

Your email address will not be published. Required fields are marked *