DDoS分布式拒绝服务

213 阅读7分钟

Dos攻击目标分类

  • 网络
    • 基于大量的Flood耗尽目标网络带宽资源。
      • Syn Flood(TCP三次握手第一次请求建立连接发的包Syn请求建立连接)、UDP Flood,在不建立连接情况下直接发包,直接堵塞。
  • 协议
    • 攻击协议漏洞发起的拒绝服务攻击。
      • ICMP Flood、Ping of Death、ARP、DNS、802.11、SSL。
  • 应用
    • 针对应用软件和操作系统漏洞发起的拒绝服务攻击。
    • 大量频繁访问消耗系统资源严重的应用(CC)。
    • 通常表现为操作系统运行正常,网络流量不大,但服务停止响应。
    • 可以是一击毙命,也可以是耗尽目标资源。
DDoS攻击特性
  • 攻击资源:
    • 网络:带宽 让带宽达到上限
    • 防火墙:吞吐量、并发 防火墙并发达到上限
    • 网络协议: TCP SYN... 协议上限
    • 服务器:CPU、内存、IO 资源上限
    • 应用:处理请求能力 对OS资源的使用权上限
    • 缓存区溢出:
    • 程序逻辑漏洞:

Syn-Flood

利用了TCP连接可靠性的特征,向服务器发起TCP建立连接的第一个请求包。然后疯狂向服务器发送第一个请求建立连接的包,然后就不再回应包,让服务器一直处于等待中一直维护这种未被建立的连接,当默认服务器达到文件数据数最大上限时,资源耗尽。 通常Syn-Flood会伴随着源IP伪造的情况,通常情况下路由sNET。 通常情况下受害者会是IP包头的目的地址IP,但是有些攻击方式是通过路由转发包至来源地址(通过源IP伪造方式,但是经过自身路由的SNAT会自动替换)

在LInux大多数发行版中默认的文件句柄数为:1024

[root@localhost ~]# ulimit -n
1024

正常的TCP协议三次握手过程

19:40:34.323477 IP lqh.41236 > localhost.localdomain.ssh: Flags [S], seq 1291688683, win 64240, options [mss 1460,sackOK,TS val 2891719715 ecr 0,nop,wscale 7], length 0
# 客户端第一个包Syn请求连接,Flags标记位为S,第一次随机生成序列号为1291688683
19:40:34.323549 IP localhost.localdomain.ssh > lqh.41236: Flags [S.], seq 1181497359, ack 1291688684, win 65160, options [mss 1460,sackOK,TS val 368424206 ecr 2891719715,nop,wscale 7], length 0
# 服务器回应包,Syn+ACK标志位:SA, 返回序列号为刚才接收到的序列号+1
19:40:34.323645 IP lqh.41236 > localhost.localdomain.ssh: Flags [.], ack 1, win 502, options [nop,nop,TS val 2891719716 ecr 368424206], length 0
#客户端回应:ACK
  • 查看当前TCP连接状态
netstat -tan|awk '$1~/tcp/{print $NF}'|sort|uniq -c|sort -nr
netstat -an|awk '/^tcp/{++S[$NF]}END{for (a in S)print a,S[a]}'
状态 说明
LISTEN 服务器处于侦听状态,等待TCP端口的连接请求
SYN-SENT 在发送连接请求后,等待匹配的连接请求
SYN-RECEIVED 已经收到连接请求,在收到和发送一个连接请求后等待对方对连接请求的确认
ESTABLISHED 三次握手建立成功,代表成功建立一个TCP连接,我们常用此作为并发连接数
FIN-WAIT-1 等待远程TCP连接中断请求,或先前的连接中断请求的确认
FIN-WAIT-2 从远程TCP等待连接中断请求
CLOSE-WAIT 等待从本地用户发来的连接中断请求
CLOSING 等待远程TCP对连接中断的确认
LAST-ACK 等待原来发向远程TCP的连接中断的确认
TIME-WAIT 等待足够的时间以确保远程TCP连接收到中断请求的确认,最大四分钟
CLOSED 没有任何连接状态
  • 所以我们可以通过SYN-RECEIVED的数量来作为依据是否着受到了TCP-SynFlood攻击。
  • 针对Syn-Flood攻击方式的防御方式: 启用内核syn cookie
[root@localhost ~]# sysctl -a | grep syn
fs.quota.syncs = 0
fs.xfs.inherit_sync = 1
fs.xfs.xfssyncd_centisecs = 3000
net.ipv4.fib_sync_mem = 524288
net.ipv4.tcp_max_syn_backlog = 128 #TCP最大队列长度
net.ipv4.tcp_syn_retries = 6
net.ipv4.tcp_synack_retries = 5
net.ipv4.tcp_syncookies = 1 # 启用syncookie
sysctl: reading key "net.ipv6.conf.all.stable_secret"
net.ipv6.conf.all.max_desync_factor = 600
sysctl: reading key "net.ipv6.conf.default.stable_secret"
net.ipv6.conf.default.max_desync_factor = 600
sysctl: reading key "net.ipv6.conf.eth0.stable_secret"
net.ipv6.conf.eth0.max_desync_factor = 600
sysctl: reading key "net.ipv6.conf.lo.stable_secret"
net.ipv6.conf.lo.max_desync_factor = 600
虽然启用syncookies对Syn-Flood有些许帮助,但是如果量大并没有什么卵用,而且这个要计算HAS值所以CPU的消耗会增大。

Sockstress

针对TCP服务的拒绝服务攻击,针对服务器的硬件资源进行攻击。利用了TCP中window窗口大小的流量控制的漏洞。

  • Sockstress攻击特点: ①.攻击者成功完成TCP三次握手连接过程。 ②.在最后向服务端发送的的ack的window窗口大小数值为0。 ④.与服务端建立大量的socket连接。 ⑤.攻击者硬件资源消耗小。 ⑥.异步攻击,单机可拒绝服务高配置资源服务器。
  • 如何查看是否受到Sockstress攻击
[root@localhost ~]# netstat -tan|awk '$1~/tcp/{print $NF}'|sort|uniq -c|sort -nr
   3654 FIN_WAIT1
    101 ESTABLISHED
      5 LISTEN
13:37:03.267342 IP localhost.localdomain.http > lqh.61842: Flags [S.], seq 3494687279, ack 451541584, win 64240, options [mss 1460], length 0
13:37:03.267519 IP lqh.61842 > localhost.localdomain.http: Flags [.], ack 1, win 0, options [eol], length 0
#抓到win窗口大小为0
13:37:03.367581 IP lqh.58316 > localhost.localdomain.http: Flags [S], seq 292866170, win 59395, options [eol], length 0
13:37:03.367608 IP localhost.localdomain.http > lqh.58316: Flags [S.], seq 2445992567, ack 292866171, win 64240, options [mss 1460], length 0
13:37:03.367833 IP lqh.58316 > localhost.localdomain.http: Flags [.], ack 1, win 0, options [eol], length 0
13:37:03.467864 IP lqh.35505 > localhost.localdomain.http: Flags [S], seq 2100120839, win 59395, options [eol], length 0
13:37:03.467897 IP localhost.localdomain.http > lqh.35505: Flags [S.], seq 665729135, ack 2100120840, win 64240, options [mss 1460], length 0
13:37:03.468069 IP lqh.35505 > localhost.localdomain.http: Flags [.], ack 1, win 0, options [eol], length 0
13:37:33.854212 IP localhost.localdomain.http > lqh.32720: Flags [S.], seq 1959752701, ack 1933866633, win 64240, options [mss 1460], length 0
13:37:33.854221 IP localhost.localdomain.http > lqh.51888: Flags [S.], seq 4119515008, ack 1011716408, win 64240, options [mss 1460], length 0
13:37:34.366191 IP localhost.localdomain.http > lqh.18065: Flags [S.], seq 178502708, ack 2112554580, win 64240, options [mss 1460], length 0
13:37:34.366214 IP localhost.localdomain.http > lqh.35822: Flags [S.], seq 2503441005, ack 990158857, win 64240, options [mss 1460], length 0
13:37:34.366216 IP localhost.localdomain.http > lqh.4491: Flags [S.], seq 4272646883, ack 341291963, win 64240, options [mss 1460], length 0
13:37:34.366218 IP localhost.localdomain.http > lqh.41901: Flags [S.], seq 1936348529, ack 1007498231, win 64240, options [mss 1460], length 0
13:37:34.366221 IP localhost.localdomain.http > lqh.13483: Flags [S.], seq 3350601343, ack 330840653, win 64240, options [mss 1460], length 0
13:37:34.878194 IP localhost.localdomain.http > lqh.25295: Flags [S.], seq 1068087605, ack 1870816890, win 64240, options [mss 1460], length 0
13:37:34.878216 IP localhost.localdomain.http > lqh.36241: Flags [S.], seq 3332272409, ack 779372838, win 64240, options [mss 1460], length 0
13:37:34.878218 IP localhost.localdomain.http > lqh.59062: Flags [S.], seq 3631107949, ack 197752650, win 64240, options [mss 1460], length 0
13:37:34.878220 IP localhost.localdomain.http > lqh.49584: Flags [S.], seq 2323703460, ack 127758627, win 64240, options [mss 1460], length 0
13:37:34.878223 IP localhost.localdomain.http > lqh.61842: Flags [S.], seq 3494687279, ack 451541584, win 64240, options [mss 1460], length 0
#再次尝试与客户端进行重发Syn、ACK 申请窗口大小
13:37:35.389996 IP localhost.localdomain.http > lqh.58316: Flags [S.], seq 2445992567, ack 292866171, win 64240, options [mss 1460], length 0
13:37:35.390019 IP localhost.localdomain.http > lqh.35505: Flags [S.], seq 665729135, ack 2100120840, win 64240, options [mss 1460], length 0
- 可以根据FIN_WAIT1的指数,并结合网络抓包请求窗口大小为0,并无rst指针回应包。
  • Linux 操作系统默认TCP超时时间为2次方值,我这边Centos7默认为64秒,期间服务器会再次发送含有SYN.ACK标志这样的数据包,但是如果得不到回应就会等待维护超时时间丢弃掉这个TCP连接。所以说调整TCP超时维护时间也是一个小小的办法,但是如果是攻击程序维护源包回应那么服务器还是会陷入一个等待的情况。
  • 那么根据理论上分析得出,在攻击方不改变攻击策略和攻击大小量下,并且在不维护它发出的源包的情况下,我们服务器只要抗过了这个超时维护周期那么我们就对我们没有什么致命性的问题,通常情况下这种攻击会伪造源端口信息,所以基本上攻击程序不维护发出的源包。
[root@localhost ~]# sysctl net.ipv4.tcp_syn_retries
net.ipv4.tcp_syn_retries = 6
[root@localhost ~]# python
Python 2.7.5 (default, Aug  7 2019, 00:51:29)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 2**6
64