文章转载安全客,源地址:https://www.anquanke.com/post/id/231441
CDN 2021 完全攻击指南 (二)中主要介绍了协议层管制下的放大攻击和HPACK编码攻击,本篇文章是完结篇,将会介绍另外两种扩展的攻击手段。
基于HTTP慢速访问的预请求攻击
HTTP慢速攻击(HTTP Slow Dos Attack)是针对应用层的拒绝服务攻击,主要针对的协议为HTTP,攻击相对DDOS来说,更加隐蔽和高效。
HTTP协议建立连接后会保持打开状态,直到数据接收完成为止,所以HTTP慢速攻击利用了HTTP的合法机制,以极低的速度往服务器发送HTTP请求,同时长时间的保持连接不释放。
若是达到了Web Server对于并发连接数的上限,同时恶意占用的连接没有被释放,那么服务器端将无法接受新的请求,导致了拒绝服务,攻击的成本非常低。
先来看一个简单的GET请求:
我用burp发了一个简单的GET请求,但是确什么响应也没有,Response直接卡住,这类问题其实平常大家测试时候肯定都有遇见过。
原因就是红框中的 \r\n
,又称为CRLF,在正常的HTTP数据包头部,是以2个CRLF空红标记表示结束的。
由于此次GET请求中,我的服务器只收到了一个 \r\n
标记,因此将认为HTTP请求头部分没有结束,并保持此连接不释放,继续等待我传递完整的请求。
此时输入回车,再发送数据包,就可以正常得到响应了,因为用2个CRLF标记表示当前请求的HTTP头已经结束,body为空,服务器正常处理。
那么当我们作为客户端发送一个HTTP请求,故意只构造一个 CRLF 标记,剩下的内容分为10s发送一次,那么服务器需要一直等待客户端最后的的 CRLF 标记通知,然后才能解析这个报文。
那么并发呢?我们通过程序或者脚本并发发送更多的这样的请求,那么服务器会给客户端预留处更多的系统资源来等待和处理一直未传送完成的报文。
假设服务器的最大连接数是100个,我们使用脚本并发先连接上100次服务器,并且报头部connection字段启用Keep-Alive,那么其他正常的用户就无法正常访问网站了。
实际测试中我们使用 SlowHTTPTest,SlowHTTPTest 是一个可配置的应用层拒绝服务攻击测试工具,它可以工作在Linux,OSX和Cygwin环境以及Windows命令行接口,可以帮助安全测试人员检验服务器对慢速攻击的处理能力。
这里选择手动构建、源码安装,因为签名和源的问题可能导致直接 apt-get install
安装产生问题。
安装 openssl
和 libssl-dev
依赖:
sudo apt-get install openssl
sudo apt-get install libssl-dev
克隆 SlowHTTPTest 项目到本地:
git clone https://github.com/shekyan/slowhttptest
配置和安装:
# ./configure
# make && make install
这样我们就源码构建好了,然后看是否正常启动:
查看帮助:
帮助说明里面告诉我们,攻击的类型支持 Slowloris
、Slow body
和 Slow read
三种,下面分别介绍。
Slowloris
针对于HTTP请求头部的慢速攻击,前面已经讲到过并举例,通过畸形的 CRLF
标记对请求进行长时间连接。
# slowhttptest -c 1000 -H -i 10 -r 100 -s 4096 -t GET -u http://xxx.com -p 3 -x 10 -g -o Attack_status
解释一下参数:
-c : 指定连接数
-H : 攻击类型为 Slowloris
-i : 发送数据间隔
-r : 连接速率
-s : 指定 Content-legth 大小
-t : 使用的请求类型
-u : 目标网站
-p : 响应超时时间
-x : 每次发送的最大数据长度
-g : 生成统计报告
-o : 输出报告文件
执行后可以看到,几秒钟后web服务器的连接池就被占满无法访问,当前连接数为996,目标服务器服务已不可用:
Slow body
该攻击会构造一个POST数据包,将数据缓慢传输,使服务器端一直等待接收报文。
slowhttptest -c 1000 -B -i 110 -r 100 -s 8192 -t GET -u http://xxx.com -x 10 -p 3 -g -o Attack_status.html
-B
参说明启用Slow Http Post模式发送未完成的HTTP消息体。
Slow read
Slow read 会在Web服务器响应内容传输回来的时候,客户端缓慢的读取响应报文,就是慢速读取web服务器传输过来的数据,如果攻击者将window size置为一个特别小的值,但是却又请求一个特别大的资源,那么服务器就会与这个连接进行长时间通信,如果建立的连接数足够大就会占满web服务器的连接池。
当web服务器缓冲区未发送的资源堆积过多时还会导致缓冲区溢出,也无法响应其他请求。
slowhttptest -c 1000 -X -r 100 -w 512 -y 1024 -n 5 -z 32 -k 3 -u http:// -p 3 -g -o Attack_status.html
其中:
-X : 使用Slow Read attack模式,缓慢读取HTTP响应请求;
-w -y : 指定window size大小
-n : 指定读取数据的间隔;
-z : 指定每次从接收数据的缓冲区中读取数据的长度
-k : 在同一连接中重复请求的次数
通常,为了防止由于Dos攻击,CDN会断开与后端服务器的连接,并吸收所有流量。在转发GET请求时的确阻止了慢速攻击,但是针对 Pre-POST 的 slow body 慢速攻击,仍然有很大一部分的 CDN 无法正确处理。
在HTTP /1.x 中,这种攻击的损耗比为 1:1,于是可以采用 HTTP2 复用 http 流来实现减少损耗比,达成放大攻击。
基于全球访问的出口阻断攻击
这种攻击源于CDN设计中的一种特性Shield,设想如下场景:
当多个地区的客户端请求后端服务器新的未被缓存的资源时,CDN会将请求分发到不同的节点,不同节点的 CDN 再去请求服务器,这样在大量客户端访问时,这样的设计是不合理的,很容易造成服务器瘫痪。
于是CDN厂商使用了Shield,进行了入口/出口的IP分配机制,来提供资源利用率和减少连接污染:
将请求流量统一整理,交由CDN厂商的Shield再去请求后端服务器获取资源,一下子就减小了对服务器的请求压力。
那么 入口/出口 IP 是否存在一些通用的规律呢,可以见下表统计:
不难发现,大多数CDN厂商的入口 IP 数量远远大于出口 IP 数量,并且在同一个时间区段内,超过90%以上的出口 IP 是同一个,那么现在只需要攻击出口 IP 的 CDN 节点,即可实现出口阻断攻击,将造成单位时间区域内,全球客户端无法访问该节点保护的服务器群。
实际的攻击案例如图:
当全球不同地区的客户通过CDN Shield请求国内的目标服务器时,在单位时间内,Shield节点的 IP 地址大多数是一样的。
此时攻击者通过提交敏感的封禁关键词请求,因为请求国内的网站需要经过 GFW 防火墙,此时触发了规则,GFW 直接封禁该出口 IP,导致其他客户的访问出口也被锁死,因此无法访问目标服务器。