购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.4.3 UDP Flood Attack

1.UDP Flood Attack简介

UDP Flood Attack是另一种使用广泛的DDoS攻击手段。它通过向目标服务器发送大量的UDP报文来达到消耗目标服务器资源的目的,以至于目标服务器无法接受和处理正常的请求。由于UDP协议是一种无连接、无状态的协议,不需要像TCP协议那样进行三次握手,导致它很容易被滥用,并且使得攻击者可以通过伪造源地址等方式隐藏自己的身份。

我们以如图2-13所示的SNMP为例,SNMP客户端向SNMP服务器发送一个SNMP请求,SNMP服务器在接到请求之后,会对请求进行处理,处理后会把结果以SNMP响应的方式返回给SNMP客户端。以上描述的是一个正常的UDP客户端与UDP服务器交互的过程。

图2-13 正常的UDP 连接

如图2-14所示是一个典型的UDP Flood Attack过程。攻击者利用一些现成的工具向目标服务器发起大量经过伪造的UDP数据包,这些UDP数据包中的源地址和报文内容通常都是伪造的。目标服务器在接收到这些伪造的UDP数据包之后,会尝试对内容进行处理,当发现请求的端口没有服务监听或者无法处理时,就会把错误信息(例如目标无法到达)返回给伪造的IP地址。当这种伪造的请求足够快、足够多时,就会消耗目标服务器的大量资源,使得正常访问的SNMP客户端无法访问服务器,从而达到DDoS攻击的效果。

图2-14 UDP Flood Attack

2.UDP Flood Attack的防御手段

UDP Flood Attack属于比较典型的流量型攻击。在Linux主机上,在攻击流量不大的情况下,我们可以考虑利用操作系统本身的iptables对UDP Flood Attack进行简单有效的防御。下面的iptables配置在真实环境中也可以根据具体场景进行必要的部署,这里我们针对两个场景,介绍利用iptables进行防御的做法,以供参考。

(1)场景一

攻击者使用真实地址(或者虚假但固定的地址),每个攻击者同时发起大量的UDP请求,对目标服务器进行攻击。在这个场景中,为了方便验证攻击和防御效果,我们利用了SNMP服务器作为目标和验证对象。


测试环境如下所示。
虚拟化:VirtualBox 5.2
虚拟机:attacker(操作系统:Ubuntu 16.04.5 LTS, 相关软件:hping3, IP地址:192.168.1.7)
虚拟机:target(操作系统:Ubuntu 16.04.5 LTS, 相关软件:snmpd, IP地址:192.168.1.6)

在虚拟机target上,确认snmpd服务的状态。


root@target:~# service snmpd status
● snmpd.service - LSB: SNMP agents
   Loaded: loaded (/etc/init.d/snmpd; bad; vendor preset: enabled)
   Active: active (running) since Sat 2019-12-21 18:40:43 CST; 1min 19s ago
       Docs: man:systemd-sysv-generator(8)
   CGroup: /system.slice/snmpd.service
           └─1811 /usr/sbin/snmpd -Lsd -Lf /dev/null -u snmp -g snmp -I -smux mteTrigger mteTriggerConf -p /run/snmpd.pid
…
root@target:~#

在虚拟机target上,尝试正常访问snmpd。


root@target:~# snmpwalk -v 2c -c public 192.168.1.6 1.3.6.1.2.1.1.1
iso.3.6.1.2.1.1.1.0 = STRING: "Linux target 4.4.0-165-generic #193-Ubuntu SMP Tue Sep 17 17:42:52 UTC 2019 x86_64"
root@target:~#

在虚拟机attacker上,利用hping3针对虚拟机target的SNMP(UDP端口161)开始发起攻击。


root@attacker:~# sudo hping3 --udp --flood -p 161 -V 192.168.1.6
using enp0s3, addr: 192.168.1.7, MTU: 1500
HPING 192.168.1.6 (enp0s3 192.168.1.6): udp mode set, 28 headers + 0 data bytes
hping in flood mode, no replies will be shown
root@attacker:~#

在虚拟机target上,再次访问snmpd,发现已经无法使用了,表明攻击成功了。


root@target:~# snmpwalk -v 2c -c public 192.168.1.6 1.3.6.1.2.1.1.1
Timeout: No Response from 192.168.1.6
root@target:~#

在虚拟机target上,利用tcpdump查看刚才攻击时获得的数据,发现了从attacker到target的SNMP(UDP端口161)的海量请求。正是这个原因阻塞了正常的来自target自身服务器的访问请求。


root@target:~# tcpdump -nn -XX -vvv udp port 161
tcpdump: listening on enp0s3, link-type EN10MB (Ethernet), capture size 262144 bytes
19:26:52.666960 IP (tos 0x0, ttl 64, id 21327, offset 0, flags [none], proto UDP (17), length 28)
    192.168.1.7.34980 > 192.168.1.6.161: [udp sum ok]  [nothing to parse]
        0x0000:  0800 2790 a015 0800 272c 6d5e 0800 4500  ..'.....',m^..E.
        0x0010:  001c 534f 0000 4011 a424 c0a8 0107 c0a8  ..SO..@..$......
        0x0020:  0106 88a4 00a1 0008 f33a 0000 0000 0000  .........:......
        0x0030:  0000 0000 0000 0000 0000 0000            ............
19:26:52.666962 IP (tos 0x0, ttl 64, id 18430, offset 0, flags [none], proto UDP (17), length 28)
    192.168.1.7.34981 > 192.168.1.6.161: [udp sum ok]  [nothing to parse]
        0x0000:  0800 2790 a015 0800 272c 6d5e 0800 4500  ..'.....',m^..E.
        0x0010:  001c 47fe 0000 4011 af75 c0a8 0107 c0a8  ..G...@..u......
        0x0020:  0106 88a5 00a1 0008 f339 0000 0000 0000  .........9......
        0x0030:  0000 0000 0000 0000 0000 0000            ............
...
zeeman@target:~$

在虚拟机target上,利用vmstat可以看到CPU资源已经被耗尽了,也就没法接收新的SNMP请求了。


root@target:~# vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r  b   swpd   free   buff  cache  si   so   bi    bo    in   cs us sy id wa st
3  0      0 533588  26132 388608   0    0   88    87  2738 1192  3  9 87  0  0
1  0      0 533656  26132 388904   0    0    0     0 13756 6585 23 77  0  0  0
3  0      0 533600  26132 388992   0    0    0     0 11973 9427 25 75  0  0  0

在虚拟机target上,创建如下iptables。这条规则的主要作用是对SNMP(UDP端口161)的访问请求(INPUT)的连接数进行限制,超过5个连接后,所有连接都会被DROP。连接数具体是多少要根据协议特点和有可能的使用频率进行调整,以达到最好的效果。


root@target:~# iptables -I INPUT -p udp --dport 161 -m connlimit --connlimit-above 5 -j DROP
root@target:~# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source      destination
DROP       udp  --  anywhere      anywhere      udp dpt:snmp #conn src/32 > 5

Chain FORWARD (policy ACCEPT)
target     prot opt source      destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source      destination
root@target:~#

在虚拟机target上访问snmpd,这次由于有iptables做了连接的限制,所以没有影响其他主机对该服务的访问。


root@target:~# snmpwalk -v 2c -c public 192.168.1.6 1.3.6.1.2.1.1.1
iso.3.6.1.2.1.1.1.0 = STRING: "Linux target 4.4.0-165-generic #193-Ubuntu SMP Tue Sep 17 17:42:52 UTC 2019 x86_64"
root@target:~#

在虚拟机target上查看iptables,可以看到已经ACCEPT的有2256个数据包,DROP的有2400万个数据包。


root@target:~# iptables -nvL
Chain INPUT (policy ACCEPT 2256 packets, 107K bytes)
pkts bytes target     prot opt in     out     source               destination
    24M  671M DROP       udp  --  *      *       0.0.0.0/0         0.0.0.0/0
            udp dpt:161 #conn src/32 > 5

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 893 packets, 201K bytes)
pkts bytes target     prot opt in     out     source               destination
root@target:~#

这里需要说明的是,如果攻击源来自更多的服务器,那么攻击还是会给目标服务器造成相同的、不能正常访问的结果的。所以,我们要对攻击规模有比较明确的了解,这样才能做出比较合适的判断并找出适合的应对措施。

(2)场景二

攻击者使用虚假的、随机产生的源地址,同时发起大量的UDP请求对目标服务器进行攻击。在这个场景中,为了方便验证攻击和防御效果,我们利用了SNMP服务器作为目标和验证对象。


测试环境如下所示。
虚拟化:VirtualBox 5.2
虚拟机:attacker(操作系统:Ubuntu 16.04.5 LTS, 相关软件:hping3, IP地址:10.68.6.90)
虚拟机:target(操作系统:Ubuntu 16.04.5 LTS, 相关软件:snmpd(161), IP地址:10.68.6.91)

在虚拟机attacker上,利用hping3针对虚拟机target的SNMP(UDP端口161)发起攻击。这次不同的是,源地址是随机的,并且在数据报文里放了长度为5字节的数据。


zeeman@attacker:~$ sudo hping3 --udp --flood -d 5 -p 161 --rand-source -V 10.68.6.91
using enp0s3, addr: 10.68.6.90, MTU: 1500
HPING 10.68.6.91 (enp0s3 10.68.6.91): udp mode set, 28 headers + 0 data bytes
hping in flood mode, no replies will be shown
zeeman@attacker:~$

在虚拟机target上访问snmpd,由于之前的iptables的策略,因此只对连接数做了一些限制,超过5个的连接会被DROP掉。当源地址是随机的时候,由每个源地址产生的包就只有1个,不会超过5个,因此这个规则基本上是没用的,同时也可以看到,攻击再次成功了。


zeeman@target:~$ sudo iptables -nvL
Chain INPUT (policy ACCEPT 433K packets, 12M bytes)
pkts bytes target     prot opt in     out     source               destination
    0     0 DROP       udp  --  *      *       0.0.0.0/0           0.0.0.0/0
            udp dpt:161 #conn src/32 > 5

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 87 packets, 10684 bytes)
pkts bytes target     prot opt in     out     source               destination
zeeman@target:~$ snmpwalk -v 2c -c public 10.68.6.91 1.3.6.1.2.1.1.1
Timeout: No Response from 10.68.6.91
zeeman@target:~$

在虚拟机target上,利用tcpdump查看刚才攻击时获得的数据,发现海量从attacker到target的UDP端口161(SNMP)的请求,而且看到发送的UDP报文是5个字节,并且都是X。


zeeman@target:~$ sudo tcpdump -nn -XX -vvv udp port 161
tcpdump: listening on enp0s3, link-type EN10MB (Ethernet), capture size 262144 bytes
...
18:10:40.313829 IP (tos 0x0, ttl 64, id 5813, offset 0, flags [none], proto UDP (17), length 33)
    69.234.208.49.12494 > 10.68.6.91.161: [udp sum ok]  [len3<asnlen88]
        0x0000:  0800 27b0 7447 0800 27a8 0743 0800 4500  ..'.tG..'..C..E.
        0x0010:  0021 16b5 0000 4011 3d5d 45ea d031 0a44  .!....@.=]E..1.D
        0x0020:  065b 30ce 00a1 000d 9ef9 5858 5858 5800  .[0.......XXXXX.
        0x0030:  0000 0000 0000 0000 0000 0000            ............
18:10:40.314001 IP (tos 0x0, ttl 64, id 5140, offset 0, flags [none], proto UDP (17), length 33)
    141.117.222.204.12500 > 10.68.6.91.161: [udp sum ok]  [len3<asnlen88]
        0x0000:  0800 27b0 7447 0800 27a8 0743 0800 4500  ..'.tG..'..C..E.
        0x0010:  0021 1414 0000 4011 e9d7 8d75 decc 0a44  .!....@....u...D
        0x0020:  065b 30d4 00a1 000d 48cd 5858 5858 5800  .[0.....H.XXXXX.
        0x0030:  0000 0000 0000 0000 0000 0000            ............
...
^C
440 packets captured
9868 packets received by filter
9428 packets dropped by kernel
zeeman@target:~$

在虚拟机target上,有针对性地创建如下的iptables。这里需要注意的是,规则中进行匹配的字符串是大小写敏感的,这个规则的主要目的是根据进行攻击的UDP包的特点(包的内容是一样的,都是“XXXXX”)进行防御。


zeeman@target:~$ sudo iptables -I INPUT -p udp --dport 161 -m string --string "XXXXX" --algo kmp -j DROP
zeeman@target:~$ sudo iptables -nvL
Chain INPUT (policy ACCEPT 21 packets, 1784 bytes)
pkts bytes target     prot opt in     out     source               destination
    0     0 DROP       udp  --  *      *       0.0.0.0/0            0.0.0.0/0
            udp dpt:161 STRING match  "XXXXX" ALGO name kmp TO 65535

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 5 packets, 808 bytes)
pkts bytes target     prot opt in     out     source               destination
zeeman@attacker:~$

在虚拟机attacker上,利用hping3针对虚拟机target的SNMP(UDP端口161),再次发起攻击。


zeeman@attacker:~$ sudo hping3 --udp --flood -d 5 -p 161 --rand-source -V 10.68.6.91
using enp0s3, addr: 10.68.6.90, MTU: 1500
HPING 10.68.6.91 (enp0s3 10.68.6.91): udp mode set, 28 headers + 0 data bytes
hping in flood mode, no replies will be shown
zeeman@attacker:~$

在虚拟机target上,访问snmpd,可以正常访问。正是由于对包的内容进行了过滤,把攻击的流量都DROP掉了,所以才保护了正常的流量。


zeeman@target:~$ snmpwalk -v 2c -c public 10.68.6.91 1.3.6.1.2.1.1.1
iso.3.6.1.2.1.1.1.0 = STRING: "Linux target 4.4.0-131-generic #157-Ubuntu SMP Thu Jul 12 15:51:36 UTC 2018 x86_64"
zeeman@target:~$ sudo iptables -nvL
Chain INPUT (policy ACCEPT 266 packets, 14375 bytes)
pkts bytes target     prot opt in     out     source               destination
336K   11M DROP       udp  --  *      *       0.0.0.0/0            0.0.0.0/0
            udp dpt:161 STRING match  "XXXXX" ALGO name kmp TO 65535

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 40 packets, 5591 bytes)
pkts bytes target     prot opt in     out     source               destination
zeeman@target:~$

在利用iptables进行过滤时,我们还可以考虑基于其他的攻击特征进行规则调整,例如根据报文长度进行过滤,根据源地址进行过滤,根据端口进行过滤等。当然,具体规则的调整还需要根据具体情况来进行。

在虚拟机target上,我们可以看看正常的SNMP的报文内容是什么样的,它和那些伪造的报文内容还是有很大差别的。 zEu8LwDoRrsqga78QlIotk+6BcOL6NeVur3fO1fDLpFktJ9UbKYzc2bQZNQ01IHz


zeeman@target:~$ sudo tcpdump -nn -XX -vvv udp port 161
tcpdump: listening on enp0s3, link-type EN10MB (Ethernet), capture size 262144 bytes
18:27:57.496152 IP (tos 0x0, ttl 64, id 42947, offset 0, flags [DF], proto UDP (17), length 70)
    10.68.6.90.32903 > 10.68.6.91.161: [udp sum ok]  { SNMPv2c { GetNextRequest(27) R=1363945077  .1.3.6.1.2.1.1.1 } }
        0x0000:  0800 27b0 7447 0800 27a8 0743 0800 4500  ..'.tG..'..C..E.
        0x0010:  0046 a7c3 4000 4011 71a7 0a44 065a 0a44  .F..@.@.q..D.Z.D
        0x0020:  065b 8087 00a1 0032 cd09 3028 0201 0104  .[.....2..0(....
        0x0030:  0670 7562 6c69 63a1 1b02 0451 4c26 7502  .public....QL&u.
        0x0040:  0100 0201 0030 0d30 0b06 072b 0601 0201  .....0.0...+....
        0x0050:  0101 0500                                ....
18:27:57.497470 IP (tos 0x0, ttl 64, id 23750, offset 0, flags [DF], proto UDP (17), length 153)
    10.68.6.91.161 > 10.68.6.90.32903: [bad udp cksum 0x21d3 -> 0x9ef4!]  { SNMPv2c { GetResponse(110) R=1363945077  .1.3.6.1.2.1.1.1.0="Linux target 4.4.0-131-
generic #157-Ubuntu SMP Thu Jul 12 15:51:36 UTC 2018 x86_64" } }
        0x0000:  0800 27a8 0743 0800 27b0 7447 0800 4500  ..'..C..'.tG..E.
        0x0010:  0099 5cc6 4000 4011 bc51 0a44 065b 0a44  ..\.@.@..Q.D.[.D
        0x0020:  065a 00a1 8087 0085 21d3 307b 0201 0104  .Z......!.0{....
        0x0030:  0670 7562 6c69 63a2 6e02 0451 4c26 7502  .public.n..QL&u.
        0x0040:  0100 0201 0030 6030 5e06 082b 0601 0201  .....0`0^..+....
        0x0050:  0101 0004 524c 696e 7578 2074 6172 6765  ....RLinux.targe
        0x0060:  7420 342e 342e 302d 3133 312d 6765 6e65  t.4.4.0-131-gene
        0x0070:  7269 6320 2331 3537 2d55 6275 6e74 7520  ric.#157-Ubuntu.
        0x0080:  534d 5020 5468 7520 4a75 6c20 3132 2031  SMP.Thu.Jul.12.1
        0x0090:  353a 3531 3a33 3620 5554 4320 3230 3138  5:51:36.UTC.2018
        0x00a0:  2078 3836 5f36 34                        .x86_64
18:27:57.500797 IP (tos 0x0, ttl 64, id 42948, offset 0, flags [DF], proto UDP (17), length 71)
    10.68.6.90.32903 > 10.68.6.91.161: [udp sum ok]  { SNMPv2c { GetNextRequest(28) R=1363945078  .1.3.6.1.2.1.1.1.0 } }
        0x0000:  0800 27b0 7447 0800 27a8 0743 0800 4500  ..'.tG..'..C..E.
        0x0010:  0047 a7c4 4000 4011 71a5 0a44 065a 0a44  .G..@.@.q..D.Z.D
        0x0020:  065b 8087 00a1 0033 cd01 3029 0201 0104  .[.....3..0)....
        0x0030:  0670 7562 6c69 63a1 1c02 0451 4c26 7602  .public....QL&v.
        0x0040:  0100 0201 0030 0e30 0c06 082b 0601 0201  .....0.0...+....
        0x0050:  0101 0005 00                             .....
18:27:57.501675 IP (tos 0x0, ttl 64, id 23751, offset 0, flags [DF], proto UDP (17), length 81)
    10.68.6.91.161 > 10.68.6.90.32903: [bad udp cksum 0x218b -> 0xcea8!]  { SNMPv2c { GetResponse(38) R=1363945078  .1.3.6.1.2.1.1.2.0=.1.3.6.1.4.1.8072.3.2.10 } }
        0x0000:  0800 27a8 0743 0800 27b0 7447 0800 4500  ..'..C..'.tG..E.
        0x0010:  0051 5cc7 4000 4011 bc98 0a44 065b 0a44  .Q\.@.@....D.[.D
        0x0020:  065a 00a1 8087 003d 218b 3033 0201 0104  .Z.....=!.03....
        0x0030:  0670 7562 6c69 63a2 2602 0451 4c26 7602  .public.&..QL&v.
        0x0040:  0100 0201 0030 1830 1606 082b 0601 0201  .....0.0...+....
        0x0050:  0102 0006 0a2b 0601 0401 bf08 0302 0a    .....+.........
zeeman@target:~$

点击中间区域
呼出菜单
上一章
目录
下一章
×