SYN_FLOOD攻击和HTTP慢速攻击是DDOS攻击的两种方式。
SYN Flood攻击
SYN Flood攻击的原理就是阻断TCP三次握手的第三次ACK包,即不对服务器发送的SYN+ACK数据包做出应答。由于服务器没有收到客户端发来的确认响应,就会一直保持连接直到超时,当有大量这种半开连接建立时,即造成SYN Flood攻击。
客户端通过发送在TCP报头中SYN标志的数据分段到服务端来请求建立连接。通常情况下,服务端根据IP报头中的来源地址来返回SYN/ACK标志的数据包给客户端,客户端再返回ACK到服务端来完成一个完整的连接(Figure-1)。
在攻击发生时,客户端的来源IP地址是经过伪造的(spoofed),现行的IP路由机制仅检查目的IP地址并进行转发,该IP包到达目的主机后返回路径无法通过路由达到的,于是目的主机无法通过TCP三次握手建立连接。在此期间因为TCP缓存队列已经填满,而拒绝新的连接请求。目的主机一直尝试直至超时(大约75秒)。这就是该攻击类型的基本机制。发动攻击的主机只要发送较少的,来源地址经过伪装而且无法通过路由达到的SYN连接请求到目标主机提供TCP服务的端口,将目的主机的TCP缓存队列填满,就可以实施一次成功的攻击。实际情况下,发动攻击时往往是持续且高速的。
可以按照这个思路进行数据包构造,这里使用python的scapy模块来模拟发包:
在进行攻击之前,是可以正常访问10.1.1.235的,并且还可以用wireshark看到访问的数据包:
在模拟发包的同时,Wireshark抓包,可以看到目标服务器成功给我们返回SYN+ACK数据包,但是第三个数据包却是RST数据包而不是ACK数据包,这是怎么回事?其实这个RST数据包是系统自己发送的,原因在于一开始的SYN数据包是我们使用scapy模块发出的,并不是操作系统自己主动发出的,所以当操作系统收到一个SYN+ACK数据包时,它会认为这个连接不是我发出的,就会主动拒绝连接,并返回RST数据包。既然这样,我们可以使用linux下的iptables命令禁止系统自动给目标发送RST数据包,从而达到建立半开连接的效果,命令如下:
iptables -A OUTPUT -p tcp --tcp-flags RST RST -d 10.1.1.235 -j DROP
接下来我们就可以把刚刚构造数据包的思路加上多线程模块写成一个SYN Flood攻击脚本,并执行。
发包同时发现目标服务器的Web应用已经无法访问(因为有缓存所以还看得到页面内容,但可以看到左下角和右上角显示正在连接):
同时用Wireshark抓包,可以看到抓取到大量的SYN请求数据包,并且已经没有RST数据包了:
回到服务器(Metasploitable2)上,查看服务器所建立的连接。使用命令netstat -pantu | grep SYN查看已建立的SYN连接数,可发现此时已建立了大量连接:
查看TCP连接数:
统计80端口连接数:netstat -nat|grep -i "80"|wc -l
包发送完毕:
HTTP慢速攻击
这里进行HTTP慢速攻击使用的是slowhttptest。可以使用-h选项来查看使用说明:
Slowloris攻击方式
Slowloris是在2009年由web安全专家RSnake提供的一种攻击方式,原理是以极低的速度往服务器端发送HTTP请求,HTTP协议规定必须HTTPrequest必须完整收到以后才能开始处理,所以在HTTP request没有被服务器完全接受之前,服务器会保持该TCP连接。由于服务器的并发连接数有一定的上限,因此恶意占用所有连接不释放会导致服务器无法接受新的请求,导致拒绝服务。为了保持恶意连接,RSnake构造一个不完整的HTTP请求,服务器认为请求接受不完整,会继续保持TCP连接。当服务器TCP的连接数达到上限,就会导致拒绝服务。
slowhttptest -c 1000 -H -g -o my_header_stats -i 10 -r 200 -t GET -u http://10.1.1.235 -x 24 -p 3
有时我们需要测试一个url,但域名并没解析,这时为了一个简单的测试而写host或去做域名解析,显然这并不高效,而有些域名甚至是正式的域名,因此我们可有使用curl命令进行测试。 通过curl -I 目标IP命令:
开始攻击前:
开始攻击后:
Netstat命令用于显示各种网络相关信息,如网络连接,路由表,接口状态(Interface Statistics),masquerade 连接,多播成员(Multicast Memberships) 等等,输入如下命令查看服务端(M2)建立的连接数:
netstat -pantu | grep ESTABLISHED
查询连接数: sudo netstat -pantu | grep DSTABLISHED | wc -l
重置之后再次查询可发现恢复正常: sudo netstat -pantu | grep ESTABLISHED
重置前服务器上的Web服务已经完全不能访问了,抓包验证攻击手法:
数据包上点击右键,选择“追踪流/TCP流”,可以看到结尾添加了一个X-***,这样看我们可能看不出什么,我们将这组数据转换成原始数据看看:
可以看到所有结尾都是是0d0a,0d表示\r,0a表示\n,也就是说结尾是\r\n。而正常的请求头结尾应该是\r\n\r\n,如果以\r\n结尾,服务器就会认为客户端的数据还没传输完,就需要一直保持连接直到超时。
Slow POST攻击方式
在POST提交方式中,允许在HTTP的头中声明content-length,也就是POST内容的长度。在提交了头以后,将后面的body部分卡住不发送,这时服务器在接受了POST长度以后,就会等待客户端发送POST的内容,攻击者保持连接并且以10s-100s一个字节的速度去发送,就达到了消耗资源的效果,因此不断地增加这样的链接,就会使得服务器的资源被消耗,最后可能会宕机。
slowhttptest -c 3000 -B -g -o my_body_stats -i 110 -r 200 -s 8192 -t FAKEVERB -u http://10.1.1.235/admin/login.php -x 10 -p 3
服务器已挂:
在受害机(M2)查询连接数: netstat -pantu | grep ESTABLISHED
追踪tcp流:header结尾是正常的“0d0a 0d 0a”,但Content-Length字段设置为一个很大的值8192,同时不在一个包中发送完整POST数据而是每间隔100秒发送随机的key-value键值对。
Slow read攻击方式
采用调整TCP协议中的滑动窗口大小,来对服务器单次发送的数据大小进行控制,使得服务器需要对一个回应分成很多个包来发送。要使这种攻击效果更加明显,请求的资源要尽量大。
输入以下命令进行攻击:通过设置TCP接收窗口大小为32(-z32)来限制每次服务器给我们发送的数据大小。slowhttptest -c 8000 -X -r 200 -w 500 -y 1000 -n 5 -z 32 -k 3 -t GET -u http://10.1.1.235/admin/login.php -x 24 -p 3
通过抓包分析,我们可以观察到目标服务器每次只给我们返回32字节的数据:
当请求a.wmv资源(大小有9M多)时,客户端windowssize被刻意设置为1152字节。客户端缓冲区在被来自服务器的数据填满后,发出了[TCPZeroWindow]告警,迫使服务端等待。
HTTP慢速攻击是利用HTTP现有合法机制,在建立了与HTTP服务器的连接后,尽量长时间保持该连接,不释放,达到对HTTP服务器的攻击。常见的攻击有三种:
A. Slow POST: 攻击者发送POST报文向服务器请求提交数据,将总报文长度设置为一个很大的数值,但是在随后的数据发送中,每次只发送很小的报文,这样导致服务器端一直等待攻击者发送数据。
B. Slow headers: 攻击者通过GET或者POST向服务器建立连接,每30 s才向服务器发送一个HTTP头部,因为Web服务器一直没有收到2个连续的\r\n,所以认为客户端没有发送完头部,从而会一直等待客户端头信息中的结束符而导致连接始终被占用,因此消耗了服务器的连接和内存资源。
C. Slowread:攻击者客户端与Web服务器建立连接并发送了一个HTTP请求,并以很低的速度读取Web服务器的Response,比如很长一段时间攻击者客户端不读取任何数据,通过发送Zero Window(表示自己没有缓冲区用于接收数据)到服务器,服务器不得不持续地向客户端发出Zero Window Probe包,询问客户端是否可以接收数据。直到连接快超时之前才读取一个字节,以消耗服务器的连接和内存资源。