
众所周知,TCP连接的建立需要三次握手:客户端发出SYN包,服务端回复SYN+ACK包,最后客户端回复ACK包。但并不是每个客户端IT有礼貌地走完这个流程,比如一些扫描器利用SYN包偷窥后就不说话了,这种情况下服务端无法明确对面是不想连接了还是有网络延迟,就会很难办。于是不少不聪明的服务端会保留连接状态等一段时间再放弃,这段时间,称之为半连接状态,服务器会保留一小截内存去记住连接相关的数据,也制造了被利用的条件
SYN泛洪
简单的来说,SYN泛洪就是疯狂的向一个服务器发起TCP连接,发送一个SYN包然后已读不回,在短时间内造成服务器上的大量连接处于半连接状态。由于服务器需要给每个连接分配一点内存,积少成多,只要请求的数量够多,服务器的内存就会被消耗殆尽,影响其原有的服务。
Python实现IT
SYN泛洪需要操作报文的IP层以及TCP层数据,这些可以用Scapy库进行构造,然后从客户端的每个非重要端口(1024-65534)依次发起一道连接
1 | from scapy.all import * |
可以用Wireshark抓包看到反馈
观测到SYN ACK回应,说明成功生效
为了防止倒流回来的SYN ACK包把自己反冲了,泛洪前立个防火墙过滤掉返回的包
1 | iptables -A OUTPUT -p tcp —tcp-flags ALL RST -d <target_ip> -j DROP |
封装
可以把这段代码封装成一个命令行脚本指令,方便调用
1 | # TODO |
分布式泛洪
一台计算机的端口数量以及带宽终归有极限,想要冲烂一台服务器有些痴人说梦。但是一堆计算机们联合起来情况就不一样了。滴轨道离子炮(low Orbit Ion Cannon)便是一种将机器们团结起来的工具 – 人们可以自愿把自己的PC连接到一台位于中央的IRC服务器,当有成员向这台IRC服务器发送泛洪请求时,其他成员会一起满足他的愿望。
聪明的服务器
那么聪明的服务器遇到这种情况会怎么做呢?
聪明的服务器在接收到最初的SYN包时不会分配任何内存去维持连接,而是哈希包中TCP层和IP层的信息计算出一个cookie值通过序列号字段返回给客户端,直到客户端发出ACK包时根据序列号以及包的其他信息去确认客户端是否之前二次握手过,再根据验证情况决定是否建立TCP连接。