前言
前几天自己部署在腾讯云的蜜罐突然收到了一波ddos攻击,峰值高达70多个G,且因为持续大流量攻击导致腾讯云黑洞封了2天。事后看了腾讯云告警发现为udpflood
,于是去研究了一波。
关于ddos的介绍这边就不多累述了,ddos起源很早,种类繁多,本文主要是对本次受到的攻击类型(反射放大攻击)做一次分析以及拓展。
请注意,这并不是一项很新的技术,放大攻击最早应该可追溯到十年前…
一、关于放大攻击
众所周知,当你电脑同时打开非常非常多的大响应的网页的时候,你会发现你的网络明显变卡,假设目标网站性能是绝对顶得住,那顶不住的就是你自己的网络了。因为目标网站返回给你的响应很大,大到可能超出了你的入带宽限制。其实这就可以理解为一种基于放大攻击的DDOS,但这个假设场景仅仅为“self ddos”,我d我自己,没有意义~
要实现真正的ddos攻击,那我们必须实现通过我们发送请求,但是响应的数据返回给别人。很显然在上面那个场景中无法实现,因为目标网站肯定是谁请求就给谁响应。但是在某些特殊场景中我们可以通过构造特殊的请求来欺骗中间服务器,在我们构造的请求中替换源地址为攻击对象的地址,那么响应自然也就发到攻击对象那边去了,从而实现了ddos攻击。
所以,放大攻击的本质是欺骗目标服务器以及中间服务器的响应远大于请求。
二、基于UDP的反射放大攻击
在过去的十几年里,主流公开的都是基于UDP协议的放大攻击。
众所周知UDP协议是面向无连接的,所以客户端发送请求包的源IP很容易进行伪造,当把源IP修改为受害者的IP,最终服务端返回的响应包就会返回到受害者的IP,这就形成了一次反射攻击。
要形成放大攻击除了伪造源ip外,还需要中间服务的响应远大于请求,以及能够被请求(无需授权认证),能够满足要求的包括但不限于NTP、DNS、MEMCACHE、SSDP、QOTD、SNMP、CHARGEN、LDAP、WS-DISCOVERY。而所谓的放大倍数就是响应与请求的倍数。
下面放了一张源自网易易盾
的关于倍数的统计图片,仅供参考:
举两个个例子,先说说基于NTP的的反射放大攻击。
NTP是网络时间协议,通过网络协议使计算机之前的时间同步化,这是一个基于UDP的协议。
NTP 包含一个monlist功能,也被称为MON_GETLIST,在低版本中默认开启,主要用于监控NTP服务器,NTP服务器响应monlist后就会返回与 NTP 服务器进行过时间同步的最后 600 个客户端的 IP,响应包按照每6个IP进行分割,最多有100个响应包。
我们通过ntpdc命令手动向ntp服务器发送一个monlist请求来看看
通过抓包发现我们只是发送了一个长度为234字节的请求包,而收到了100个长度为482的响应包,从这里计算放大的倍数就是 482*100/234 = 206 倍,而通过自定义构造攻击请求包,可以使我们的请求长度更小,进一步提高放大倍数,从而提升攻击威力。
我们可以通过python来简单实现一个攻击脚本,利用python中的scapy包来自定义udp请求数据,最终可以实现请求的数据包长度只有50,响应数据包长度为530(取决于ntp服务器实际情况),放大倍数可达530*100/50=1060倍。
但这只是理论上,在实际网络环境中,ntp服务器响应的大小以及数量会存在差异。另外为了避免恶意利用,脚本就不放了,本文也只是在靶机环境进行实验。
假设攻击者找到的互联网上可供利用的ntp服务器有50w台(早期很常见),放大倍数也假设上述的情况,那么攻击者单次将可以打出50w*530*100/1048576/1024=24.6G
的流量,在实际攻击中会并发和轮询,峰值流量会更高。
时至今日,互联网上还是存在较多的存在缺陷的ntp服务,加固方法如下:
把 NTP 服务器升级到 4.2.7p26
关闭现在 NTP 服务的 monlist 功能,在ntp.conf配置文件中增加
disable monitor
选项在网络出口封禁 UDP 123 端口
再来说说一个威力更大的,利用Memcache来实现的反射放大攻击。
Memcache是一个开源的分布式内存对象缓存系统,使用量非常非常大。Memcache支持TCP和UDP种协议,而且经常做渗透的同学都知道Memcached存在一个未授权访问的漏洞,除了能够被攻击者操作数据库外,在低版本默认开启udp的情况下还能用来做ddos攻击。
Memcache可以通过set命令来插入数据,通过get命令来查询数据。Memcache默认的最大储存value是1M,攻击者可以事先基于TCP协议批量对满足条件的Memcache服务插入数据,然后自定义构造基于UDP的请求包,通过get命令查询key对应的value,并将源地址伪造成攻击对象的ip,即可实现放大攻击。
我们在本地用docker来运行一个Memcache,请注意在新版本中已经默认禁用udp了,所以启动的时候需要手动指定-U 11211
,并且将udp端口也映射出来。
默认最大写入为1MB,也就是1048576个字节,本地测试的时候发现直接写1MB进去不行,会提示过大,所以这边减去76个字节去插入
然后我们用udp的方式去请求查询,使用udp的时候要加上头部的8字节标志位。
python -c "print 'x00x00x00x00x00x01x00x00get arn'" |nc -nvvu 127.0.0.1 11211
通过抓包查看,我们发送查询的请求长度为58,而响应则返回了753*1442+401+57=1086284个字节长度,所以这里约放大了1.9w倍。
同样的在实际攻击中可以优化得放大倍数更大,理论上可达到5w倍的放大。
假设攻击者找到的互联网上可供利用的Memcache服务器有50w台(早期很常见),放大倍数也假设上述的情况,那么攻击者单次将可以打出50w*1086284/1048576/1024=505.8G的流量,在实际攻击中会并发和轮询,峰值流量会更高,很难扛得住~
Memcache在较早的时期就已经默认禁用了UDP的支持,当然,不排除业务需求而开起来的情况。未授权访问这个一直没有修,估计官方并不认为这是一个漏洞,但还是从1.4.3版本开始,支持SASL认证配置。
加固方式:
1、限制访问
2、启用认证功能
三、如何防范基于UDP的反射放大攻击
1、互联网服务提供商
不得不提到BCP38(后向拥塞防止)和 urpf(单播逆向路径转发)。
BCP38是一种最佳实践,有助于防止“反射”流量,这是由反射或放大攻击产生的流量。反射流量是发送到未发出请求的IP地址的网络流量,通常用于压倒和中断网络或服务器。BCP38通过要求所有从网络发送的流量必须具有有效的源IP地址来帮助防止反射流量。这有助于确保只允许通过网络的合法流量,并且阻止由于攻击而生成的任何流量。
URPF是一种用于验证传入流量有效性的安全机制。它通过将传入流量的源IP地址与网络的路由表进行比较,并且只允许通过源IP地址可以通过路由表到达的流量。这有助于防止伪造的流量(伪造或操纵源IP地址的流量)进入网络。URPF通常与BCP38结合使用,以提供额外的安全层,并防止某些类型的攻击。
目前只有国外一些小众机房没有做这些限制,而攻击者目前也只能通过那些机房的服务器来发起基于伪造UDP的放大攻击。
2、业务端
首先要检查开放的服务,该加固的加固,避免成为反射源。
另外根据情况购买高防包,或者接入CDN,但是当攻击流量大到一定程度时,还是会导致业务中断。
四、难以防范的tcp反射放大攻击
在我们的认知中,TCP需要完成3次握手,每个TCP连接都以客户端发送SYN数据包开始,服务器以SYN+ACK响应,客户端以ACK数据包完成握手,所以无法像udp那样实现欺骗反射攻击。
但是在很多的网络中间件在设计上不符合TCP标准,很多情况下只监控单向的报文,且响应的数据包很大,所以同样可以造成反射放大攻击。
在2021年的时候,国外一位安全研究者发布了一篇论文(https://www.usenix.org/conference/usenixsecurity21/presentation/bock),讲述了如何利用这些不规范的网络中间件来实现tcp反射放大攻击。
存在这些问题的网络中间件很多,上述论文中对不同国家的国家级防火墙进行了测试。
通过提交一些可能会被防火墙阻止的内容,如涩涩、BC等内容时,会返回阻断的页面。
这种攻击难以防范的原因在于攻击者发起的请求看上去就是一个完全正常的请求,而另一方面是要求所有互联网层面的网络中间件进行更新从而遵从TCP标准。
注:本文仅讨论反射放大攻击的技术原理以及对应的防御措施,DDOS攻击是违法的,请勿做ddos攻击行为。
参考
NTP 放大攻击的工作原理
https://www.cloudflare.com/zh-cn/learning/ddos/ntp-amplification-ddos-attack/
DDoS攻防之反射放大攻击(memcache案例)
https://www.4hou.com/posts/36PA
Weaponizing Middleboxes for TCP Reflected Amplification
https://www.usenix.org/conference/usenixsecurity21/presentation/bock
才疏学浅,若文章有错误,请各位师傅多多指教。
原文始发于微信公众号(台下言书):DDOS之反射放大攻击技术研究