Mitigating a DDOS attack – can you really do it?

Today I would like to smash your confidence about the security of your organization. You spent hundreds of dollars or euros on your security devices and you think you are safe. I believe there are many organizations like yours that think the same thing. Once they become victims, they realize they are not as safe as they had thought.
Let’s talk about DOS/DDOS attacks. I think most people have some knowledge about them. Today we should not talk only about DOS attacks because the risk of being seriously impacted is very low. Most network devices can easily mitigate such attacks because they come from one source IP address. The situation is different when we receive illegitimate traffic from many IP addresses. There are two possibilities here: we can be flooded by traffic from a real, existing source IP address or addresses; or there is one real source IP, but the packets contain random source IPs, which means you are not able to block them easily.
We can distinguish the following types of DOS/DDOS attacks:

I would like to analyze these three types of attacks in order to mitigate them. I prepared a virtual lab with the following elements:

10.0.0.10    <---------- A T T A C K ------------------------------|

  /-----\         -----             /----\                     -----------
 |WEB SRV|-------| ASA1 |----------| ISP  |--[INTERNET ]------| ATTACKER  |
  \-----/         -----             \----/                     -----------

Fig.1 Network Diagram

From the ‘Attacker’ machine I will generate traffic to the ‘Web server’, located in the DMZ. This scenario is the most common for small and medium-sized businesses (SMBs) segment. Usually these businesses manage their own firewall and have one ISP. IPS/IDS appliances are not too popular with SMBs .

Lab #1 – DOS attack
I started the first simulation with a DOS attack on a server (10.0.0.10). I set the firewall to permit all TCP traffic from any source to the destination 10.0.0.10 on the port 80.
First I checked the current configuration and utilization on all devices:

ISP#sh processes cpu sorted
CPU utilization for five seconds: 0%/0%; one minute: 1%; five minutes: 7%
 PID Runtime(ms)     Invoked      uSecs   5Sec   1Min   5Min TTY Process
 239       17132      254464         67  0.23%  0.26%  0.30%   0 ISG MIB jobs Man
 112        9740      127455         76  0.15%  0.14%  0.15%   0 IPAM Manager
   2        2660         874       3043  0.07%  0.04%  0.05%   0 Load Meter
  59        6960        1304       5337  0.07%  0.06%  0.07%   0 HC Counter Timer
 268        5224         877       5956  0.07%  0.07%  0.07%   0 Compute load avg
 174        3548       42094         84  0.07%  0.06%  0.07%   0 RBSCP Background
  82        7964      127454         62  0.07%  0.15%  0.15%   0 IP ARP Retry Age
   8           0           2          0  0.00%  0.00%  0.00%   0 Timers
   7          96          29       3310  0.00%  0.00%  0.00%   0 DiscardQ Backgro
  10       26904        1459      18440  0.00%  0.08%  0.15%   0 ARP Input
   6       11828         950      12450  0.00%  0.00%  0.00%   0 Pool Manager
 --More--

Fig.2 CPU usage – ISP router

ISP#sh run int gig0/0
Building configuration...

Current configuration : 165 bytes
!
interface GigabitEthernet0/0
 ip address 192.168.157.10 255.255.255.0
 ip access-group OUTSIDE in
 media-type gbic
 speed 1000
 duplex full
 negotiation auto
end
!


ISP#sh run | b access-list
ip access-list extended OUTSIDE
 permit tcp any host 10.0.0.10 eq www log
!

Fig.3 Interface settings and ACL on ISP

PER-FW# sh cpu usage
CPU utilization for 5 seconds = 0%; 1 minute: 0%; 5 minutes: 0%
PER-FW#

Fig.4 CPU usage – Perimeter Firewall

PER-FW# sh access-list
access-list cached ACL log flows: total 0, denied 0 (deny-flow-max 4096)
            alert-interval 300
access-list OUT; 1 elements; name hash: 0xcd7d0798
access-list OUT line 1 extended permit tcp any host 10.0.0.10 eq www (hitcnt=1) 0x5f077c5e
PER-FW#

Fig.5 Number of connection passed by the firewall

Let’s start the DOS attack using the ‘t50’ tool (part of the KALI distribution).

root@kali:~# t50 10.0.0.10 --flood --syn -s 192.168.157.200 --dport 80
entering in flood mode...
hit CTRL+C to break.
T50 5.4.1-rc1 successfully launched on Aug 30th 2014 22:41:39

After one minute I found almost 80,000 SYN packets:

ISP#sh access-lists
Extended IP access list OUTSIDE
    10 permit tcp any host 10.0.0.10 eq www log (79287 matches)
ISP#

As we see, CPU usage is close to 100%:

ISP#sh processes cpu
CPU utilization for five seconds: 96%/100%; one minute: 32%; five minutes: 30%
 PID Runtime(ms)     Invoked      uSecs   5Sec   1Min   5Min TTY Process
   1           0           2          0  0.00%  0.00%  0.00%   0 Chunk Manager
   2        5220        1525       3422  0.07%  0.04%  0.05%   0 Load Meter
   3       83540        5068      16483  3.73%  0.78%  0.58%   0 Exec
   4           0           1          0  0.00%  0.00%  0.00%   0 RO Notify Timers
   5       11812        1307       9037  0.00%  0.15%  0.12%   0 Check heaps
   6       57772        4431      13038  2.30%  1.02%  0.99%   0 Pool Manager
   7         212          67       3164  0.00%  0.00%  0.00%   0 DiscardQ Backgro
   8           0           2          0  0.00%  0.00%  0.00%   0 Timers
   9         344         397        866  0.00%  0.00%  0.00%   0 WATCH_AFS
  10       46644        4333      10764  0.07%  0.21%  0.18%   0 ARP Input
  11        4880        7878        619  0.07%  0.00%  0.00%   0 ARP Background
 --More--

Here are examples of connections initiated from the ‘Attacker’ seen on the ISP’s router:

ISP#sh logg

...

*Aug 31 00:20:46.451: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 192.168.157.200(9599) -> 10.0.0.10(80), 1 packet
*Aug 31 00:20:46.451: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 192.168.157.200(2627) -> 10.0.0.10(80), 1 packet
*Aug 31 00:20:46.451: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 192.168.157.200(8561) -> 10.0.0.10(80), 1 packet
*Aug 31 00:20:46.451: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 192.168.157.200(1329) -> 10.0.0.10(80), 1 packet
*Aug 31 00:21:17.215: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 192.168.157.200(18443) -> 10.0.0.10(80), 1 packet
*Aug 31 00:21:18.227: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 192.168.157.200(13679) -> 10.0.0.10(80), 1 packet
*Aug 31 00:21:19.247: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 192.168.157.200(9995) -> 10.0.0.10(80), 1 packet
*Aug 31 00:21:20.275: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 192.168.157.200(5977) -> 10.0.0.10(80), 1 packet
*Aug 31 00:21:21.311: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 192.168.157.200(3745) -> 10.0.0.10(80), 1 packet
*Aug 31 00:21:22.343: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 192.168.157.200(15022) -> 10.0.0.10(80), 1 packet

From the Perimeter Firewall’s point of view, the attack was not so heavy. The CPU usage was around 1-2%:

PER-FW# sh access-list
access-list cached ACL log flows: total 1529, denied 0 (deny-flow-max 4096)
            alert-interval 300
access-list OUT; 1 elements; name hash: 0xcd7d0798
access-list OUT line 1 extended permit tcp any host 10.0.0.10 eq www log informational interval 300 (hitcnt=879) 0x5f077c5e
PER-FW# sh cpu usage
CPU utilization for 5 seconds = 1%; 1 minute: 2%; 5 minutes: 1%
PER-FW#

The reason for the low impact might be the number of packets which hit the PER-FW. Let’s check the counters on the ISP:

ISP#sh int gig0/0 stat
GigabitEthernet0/0
          Switching path    Pkts In   Chars In   Pkts Out  Chars Out
               Processor      81789    4906579         17       1658
             Route cache          0          0          0          0
                   Total      81789    4906579         17       1658



ISP#sh int gig1/0 stat
GigabitEthernet1/0
          Switching path    Pkts In   Chars In   Pkts Out  Chars Out
               Processor          0          0       8962     538358
             Route cache        349      20242          0          0
                   Total        349      20242       8962     538358

As you can see, the number of packets sent out from the ISP router is 10 times less than it received. This could be caused by a lack of resources to process all packets.
Here we have sample connections initiated by the ‘Attacker’ as seen on the PER-FW:

%ASA-6-302013: Built inbound TCP connection 12328 for outside:192.168.157.200/13402 (192.168.157.200/13402) to inside:10.0.0.10/80 (10.0.0.10/80)
%ASA-6-106100: access-list OUT permitted tcp outside/192.168.157.200(23561) -> inside/10.0.0.10(80) hit-cnt 1 first hit [0x5f077c5e, 0x0]
%ASA-6-302013: Built inbound TCP connection 12329 for outside:192.168.157.200/23561 (192.168.157.200/23561) to inside:10.0.0.10/80 (10.0.0.10/80)
%ASA-6-106100: access-list OUT permitted tcp outside/192.168.157.200(29917) -> inside/10.0.0.10(80) hit-cnt 1 first hit [0x5f077c5e, 0x0]
%ASA-6-302013: Built inbound TCP connection 12330 for outside:192.168.157.200/29917 (192.168.157.200/29917) to inside:10.0.0.10/80 (10.0.0.10/80)
%ASA-6-106100: access-list OUT permitted tcp outside/192.168.157.200(17876) -> inside/10.0.0.10(80) hit-cnt 1 first hit [0x5f077c5e, 0x0]
%ASA-6-302013: Built inbound TCP connection 12331 for outside:192.168.157.200/17876 (192.168.157.200/17876) to inside:10.0.0.10/80 (10.0.0.10/80)
%ASA-6-106100: access-list OUT permitted tcp outside/192.168.157.200(14328) -> inside/10.0.0.10(80) hit-cnt 1 first hit [0x5f077c5e, 0x0]
%ASA-6-302013: Built inbound TCP connection 12332 for outside:192.168.157.200/14328 (192.168.157.200/14328) to inside:10.0.0.10/80 (10.0.0.10/80)
%ASA-6-106100: access-list OUT permitted tcp outside/192.168.157.200(5033) -> inside/10.0.0.10(80) hit-cnt 1 first hit [0x5f077c5e, 0x0]
%ASA-6-302013: Built inbound TCP connection 12333 for outside:192.168.157.200/5033 (192.168.157.200/5033) to inside:10.0.0.10/80 (10.0.0.10/80)
<--- More --->

In this case we can easily locate the source of our problems. Let’s see how we can do this.
The first problem you may notice is the ‘log’ parameter in the access-list. This is a very CPU intensive parameter and it shouldn’t be used in your production configuration:

conf t
ip access-list extended OUTSIDE
 no permit tcp any host 10.0.0.10 eq www log
 permit tcp any host 10.0.0.10 eq www 
end

Here I’ve initiatedan attack once again to check the results:

ISP#sh processes cpu sorted
CPU utilization for five seconds: 31%/100%; one minute: 61%; five minutes: 33%
 PID Runtime(ms)     Invoked      uSecs   5Sec   1Min   5Min TTY Process
 145       27216       12685       2145  1.03%  0.27%  0.10%   0 CEF: IPv4 proces
 239       38360      494717         77  0.71%  0.74%  0.44%   0 ISG MIB jobs Man
 112       20068      251110         79  0.31%  0.28%  0.20%   0 IPAM Manager
  82       15004      251100         59  0.31%  0.26%  0.19%   0 IP ARP Retry Age
  10       52028        5623       9252  0.31%  0.58%  0.27%   0 ARP Input
   2        6136        1793       3422  0.07%  0.06%  0.06%   0 Load Meter
  27        4340        8667        500  0.07%  0.02%  0.00%   0 IPC Periodic Tim
 174        9048       84571        106  0.07%  0.12%  0.10%   0 RBSCP Background
 270       66340        8950       7412  0.07%  0.67%  0.42%   0 Per-Second Jobs
   9         360         475        757  0.00%  0.00%  0.00%   0 WATCH_AFS
   7         220          76       2894  0.00%  0.00%  0.00%   0 DiscardQ Backgro
 --More--

CPU usage has dropped from 96% to 31%!

ISP#sh int gig0/0 stat
GigabitEthernet0/0
          Switching path    Pkts In   Chars In   Pkts Out  Chars Out
               Processor        193      11307         30       2774
             Route cache     390697   23441820          0          0
                   Total     390890   23453127         30       2774

ISP#sh int gig1/0 stat
GigabitEthernet1/0
          Switching path    Pkts In   Chars In   Pkts Out  Chars Out
               Processor          0          0         20       2174
             Route cache        413      23954       6971     376434
                   Total        413      23954       6991     378608
ISP#

Let’s check the CPU usage of the PER-FW:

PER-FW# sh cpu usage
CPU utilization for 5 seconds = 10%; 1 minute: 5%; 5 minutes: 2%
PER-FW# sh access-list
access-list cached ACL log flows: total 5011, denied 0 (deny-flow-max 4096)
            alert-interval 300
access-list OUT; 1 elements; name hash: 0xcd7d0798
access-list OUT line 1 extended permit tcp any host 10.0.0.10 eq www log informational interval 300 (hitcnt=5123) 0x5f077c5e
PER-FW#

In this case we have to isolate the traffic from the PRE-FW and the DMZ. The easiest way is to add an access-list (ACL) which blocks the traffic based on its source IP address:

!
interface GigabitEthernet0/0
 ip address 192.168.157.10 255.255.255.0
 ip access-group ATTACK-ACL in
 media-type gbic
 speed 1000
 duplex full
 negotiation auto
!

!
ip access-list extended ATTACK-ACL
 deny   tcp host 192.168.157.200 host 10.0.0.10 eq www
!

The negative effect of the ACL is higher CPU usage, but as you see not one packet hit the PER-FW:

ISP#sh processes cpu sorted
CPU utilization for five seconds: 89%/100%; one minute: 77%; five minutes: 35%
 PID Runtime(ms)     Invoked      uSecs   5Sec   1Min   5Min TTY Process
  83     1339100       99226      13495 37.87% 31.74% 11.97%   0 IP Input
   3      127132        9806      12964  1.12%  0.70%  1.22%   0 Exec
 145       38500       18525       2078  0.71%  0.18%  0.10%   0 CEF: IPv4 proces
 112       29524      366360         80  0.47%  0.19%  0.17%   0 IPAM Manager
 239       60840      722891         84  0.39%  0.37%  0.35%   0 ISG MIB jobs Man
   2        9348        2610       3581  0.31%  0.10%  0.06%   0 Load Meter
  44        3724       12985        286  0.23%  0.02%  0.00%   0 GraphIt
  59       19504        3887       5017  0.07%  0.09%  0.08%   0 HC Counter Timer
  98        8872       50501        175  0.07%  0.07%  0.02%   0 SSS Feature Time
  82       23952      366347         65  0.07%  0.13%  0.15%   0 IP ARP Retry Age
 270       88148       12990       6785  0.07%  0.49%  0.24%   0 Per-Second Jobs

ISP#
PER-FW# sh cpu usage
CPU utilization for 5 seconds = 1%; 1 minute: 1%; 5 minutes: 1%
PER-FW# sh access-list
access-list cached ACL log flows: total 0, denied 0 (deny-flow-max 4096)
            alert-interval 300
access-list OUT; 1 elements; name hash: 0xcd7d0798
access-list OUT line 1 extended permit tcp any host 10.0.0.10 eq www log informational interval 300 (hitcnt=0) 0x5f077c5e
PER-FW#

The next option is to use Policy Based Routing (PBR) for traffic coming from the ‘Attacker’:

!
access-list 1 permit 192.168.157.200
!
route-map ATTACK permit 10
 match ip address 1
 set interface Null0
!
interface gig0/0
 ip policy route-map ATTACK
!

ISP#sh route-map ATTACK
route-map ATTACK, permit, sequence 10
  Match clauses:
    ip address (access-lists): 1
  Set clauses:
    interface Null0
  Policy routing matches: 598255 packets, 35895300 bytes
ISP#

It should be processed by the hardware, so it will not impact the CPU on the ISP’s router.

Lab #2 – DDOS attack
Due to technical limitations I will only test a scenario in which an attack comes from one physical machine, but the packets contain spoofed source IP addresses. I removed all security features applied in lab #1, so now only http traffic is allowed from any source to the destination 10.0.0.10.
I started this attack using random IP sources :

root@kali:~# t50 10.0.0.10 --flood --syn --dport 80
entering in flood mode...
hit CTRL+C to break.
T50 5.4.1-rc1 successfully launched on Aug 30th 2014 22:41:39

As expected CPU usage on the ISP’s router is very high:

ISP#sh processes cpu sorted
CPU utilization for five seconds: 94%/100%; one minute: 31%; five minutes: 14%
 PID Runtime(ms)     Invoked      uSecs   5Sec   1Min   5Min TTY Process
  83     1474212      106143      13888 26.77%  9.08%  3.87%   0 IP Input
 270       93876       16754       5603  2.39%  0.49%  0.20%   0 Per-Second Jobs
   6       91056        7058      12901  1.83%  0.96%  0.42%   0 Pool Manager
   3      145300       11877      12233  0.95%  0.51%  0.53%   0 Exec
 174       15604      160192         97  0.39%  0.09%  0.08%   0 RBSCP Background
 112       33524      479984         69  0.39%  0.18%  0.16%   0 IPAM Manager
 239       70372      949141         74  0.39%  0.36%  0.32%   0 ISG MIB jobs Man
  50       27368        6837       4002  0.39%  0.10%  0.06%   0 Net Background
  82       27472      479970         57  0.15%  0.13%  0.13%   0 IP ARP Retry Age
  11        8368       17366        481  0.15%  0.02%  0.00%   0 ARP Background
   5       24248        2830       8568  0.07%  0.12%  0.12%   0 Check heaps

The number of hits is very similar to test #1:

ISP#sh access-lists OUTSIDE
Extended IP access list OUTSIDE
    10 permit tcp any host 10.0.0.10 eq www log (72422 matches)
ISP#
ISP#sh int gig0/0 stats
GigabitEthernet0/0
          Switching path    Pkts In   Chars In   Pkts Out  Chars Out
               Processor      72550    4357936         36       4074
             Route cache          0          0          0          0
                   Total      72550    4357936         36       4074
ISP#sh int gig1/0 stats
GigabitEthernet1/0
          Switching path    Pkts In   Chars In   Pkts Out  Chars Out
               Processor          0          0       8852     532396
             Route cache          0          0          0          0
                   Total          0          0       8852     532396
ISP#

As you see in the following log, the connections came from different source IPs:

ISP#sh logging
Syslog logging: enabled (0 messages dropped, 1549 messages rate-limited, 0 flushes, 0 overruns, xml disabled, filtering disabled)
…

*Aug 31 02:52:06.902: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 220.199.63.3(155) -> 10.0.0.10(80), 1 packet
*Aug 31 02:52:06.902: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 164.55.130.104(28412) -> 10.0.0.10(80), 1 packet
*Aug 31 02:52:06.902: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 83.17.127.33(2912) -> 10.0.0.10(80), 1 packet
*Aug 31 02:52:06.902: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 80.202.164.15(7333) -> 10.0.0.10(80), 1 packet
*Aug 31 02:52:06.902: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 35.163.122.116(14173) -> 10.0.0.10(80), 1 packet
*Aug 31 02:52:06.902: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 160.76.89.101(23452) -> 10.0.0.10(80), 1 packet
*Aug 31 02:54:33.038: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 150.234.98.10(30593) -> 10.0.0.10(80), 1 packet
*Aug 31 02:54:34.082: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 50.7.245.9(8186) -> 10.0.0.10(80), 1 packet
*Aug 31 02:54:35.098: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 32.64.62.34(8789) -> 10.0.0.10(80), 1 packet
*Aug 31 02:54:36.114: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 197.138.244.20(31482) -> 10.0.0.10(80), 1 packet
*Aug 31 02:54:37.126: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 77.36.118.8(24865) -> 10.0.0.10(80), 1 packet
*Aug 31 02:54:38.174: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 103.95.142.100(11182) -> 10.0.0.10(80), 1 packet
*Aug 31 02:54:39.194: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 64.230.212.54(24549) -> 10.0.0.10(80), 1 packet
*Aug 31 02:54:40.218: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 210.25.64.40(23580) -> 10.0.0.10(80), 1 packet
*Aug 31 02:54:41.218: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 130.11.182.87(3643) -> 10.0.0.10(80), 1 packet
*Aug 31 02:54:42.230: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 181.182.64.60(14103) -> 10.0.0.10(80), 1 packet
*Aug 31 02:54:43.242: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 92.8.226.119(24074) -> 10.0.0.10(80), 1 packet
*Aug 31 02:54:44.250: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 34.72.28.48(22367) -> 10.0.0.10(80), 1 packet
*Aug 31 02:54:44.566: %SEC-6-IPACCESSLOGRL: access-list logging rate-limited or missed 13666 packets
*Aug 31 02:54:45.254: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 25.9.251.30(23508) -> 10.0.0.10(80), 1 packet
*Aug 31 02:54:46.258: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 201.27.106.117(26452) -> 10.0.0.10(80), 1 packet
*Aug 31 02:54:47.278: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 190.52.74.50(6904) -> 10.0.0.10(80), 1 packet
*Aug 31 02:54:48.286: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 169.147.17.89(12970) -> 10.0.0.10(80), 1 packet
*Aug 31 02:54:49.294: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 196.174.184.49(24059) -> 10.0.0.10(80), 1 packet
*Aug 31 02:54:50.326: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 118.237.206.110(1664) -> 10.0.0.10(80), 1 packet
*Aug 31 02:54:51.326: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 132.72.239.123(22164) -> 10.0.0.10(80), 1 packet
*Aug 31 02:54:52.358: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 26.238.113.114(12075) -> 10.0.0.10(80), 1 packet
*Aug 31 02:54:53.366: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 200.78.129.114(27771) -> 10.0.0.10(80), 1 packet
*Aug 31 02:54:54.374: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 44.69.75.92(25733) -> 10.0.0.10(80), 1 packet
*Aug 31 02:54:55.402: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 185.39.35.54(9501) -> 10.0.0.10(80), 1 packet
*Aug 31 02:54:56.406: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 149.238.124.68(689) -> 10.0.0.10(80), 1 packet
*Aug 31 02:54:57.458: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 215.40.122.24(14267) -> 10.0.0.10(80), 1 packet
*Aug 31 02:54:58.534: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 141.225.192.103(24388) -> 10.0.0.10(80), 1 packet
*Aug 31 02:54:59.542: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 65.67.18.17(7899) -> 10.0.0.10(80), 1 packet
*Aug 31 02:55:00.542: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 57.135.236.19(3134) -> 10.0.0.10(80), 1 packet
*Aug 31 02:55:01.610: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 240.55.235.108(23735) -> 10.0.0.10(80), 1 packet
*Aug 31 02:55:02.726: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 52.202.105.109(23049) -> 10.0.0.10(80), 1 packet
*Aug 31 02:55:03.738: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 226.5.29.67(12367) -> 10.0.0.10(80), 1 packet
*Aug 31 02:55:04.766: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 1.160.121.91(10350) -> 10.0.0.10(80), 1 packet
*Aug 31 02:55:05.786: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 254.144.152.15(28777) -> 10.0.0.10(80), 1 packet
*Aug 31 02:55:06.802: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 90.84.122.90(31084) -> 10.0.0.10(80), 1 packet
*Aug 31 02:55:07.806: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 67.119.134.11(24975) -> 10.0.0.10(80), 1 packet
*Aug 31 02:55:08.830: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 48.195.167.60(31799) -> 10.0.0.10(80), 1 packet
*Aug 31 02:55:09.834: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 117.232.51.94(29094) -> 10.0.0.10(80), 1 packet
*Aug 31 02:55:10.854: %SEC-6-IPACCESSLOGP: list OUTSIDE permitted tcp 83.219.21.118(24424) -> 10.0.0.10(80), 1 packet
 --More—

The CPU on the PER-FW is not very high:

PER-FW# sh cpu usage
CPU utilization for 5 seconds = 1%; 1 minute: 1%; 5 minutes: 1%

PER-FW# sh access-list
access-list cached ACL log flows: total 732, denied 0 (deny-flow-max 4096)
            alert-interval 300
access-list OUT; 1 elements; name hash: 0xcd7d0798
access-list OUT line 1 extended permit tcp any host 10.0.0.10 eq www log informational interval 300 (hitcnt=732) 0x5f077c5e
PER-FW#


PER-FW# sh int gig0 stats
Interface GigabitEthernet0 "outside", is up, line protocol is up
  Hardware is Linux Ethernet Dev, BW 100 Mbps, DLY 100 usec
        (Full-duplex), (100 Mbps)
        Input flow control is unsupported, output flow control is unsupported
        MAC address 00ab.cd92.5200, MTU 1500
        IP address 192.168.158.11, subnet mask 255.255.255.0
        7814 packets input, 443038 bytes, 0 no buffer
        Received 0 broadcasts, 0 runts, 0 giants
        0 input errors, 0 CRC, 0 frame, 0 overrun, 0 ignored, 0 abort
        0 pause input, 0 resume input
        0 L2 decode drops
        8 packets output, 534 bytes, 0 underruns
        0 pause output, 0 resume output
        0 output errors, 0 collisions, 0 interface resets
        0 late collisions, 0 deferred
        0 input reset drops, 0 output reset drops
        input queue (blocks free curr/low): hardware (0/0)
        output queue (blocks free curr/low): hardware (0/0)
  Traffic Statistics for "outside":
        918 packets input, 38467 bytes
        0 packets output, 0 bytes
        92 packets dropped
      1 minute input rate 0 pkts/sec,  16 bytes/sec
      1 minute output rate 0 pkts/sec,  0 bytes/sec
      1 minute drop rate, 0 pkts/sec
      5 minute input rate 2 pkts/sec,  106 bytes/sec
      5 minute output rate 0 pkts/sec,  0 bytes/sec
      5 minute drop rate, 0 pkts/sec
PER-FW# sh int gig1 stats
Interface GigabitEthernet1 "inside", is up, line protocol is up
  Hardware is Linux Ethernet Dev, BW 100 Mbps, DLY 100 usec
        (Full-duplex), (100 Mbps)
        Input flow control is unsupported, output flow control is unsupported
        MAC address 00ab.cd92.5201, MTU 1500
        IP address 10.0.0.1, subnet mask 255.255.255.0
        1329 packets input, 88071 bytes, 0 no buffer
        Received 0 broadcasts, 0 runts, 0 giants
        0 input errors, 0 CRC, 0 frame, 0 overrun, 0 ignored, 0 abort
        0 pause input, 0 resume input
        0 L2 decode drops
        7139 packets output, 385491 bytes, 0 underruns
        0 pause output, 0 resume output
        0 output errors, 0 collisions, 0 interface resets
        0 late collisions, 0 deferred
        0 input reset drops, 0 output reset drops
        input queue (blocks free curr/low): hardware (0/0)
        output queue (blocks free curr/low): hardware (0/0)
  Traffic Statistics for "inside":
        393 packets input, 19227 bytes
        830 packets output, 33200 bytes
        393 packets dropped
      1 minute input rate 0 pkts/sec,  11 bytes/sec
      1 minute output rate 0 pkts/sec,  0 bytes/sec
      1 minute drop rate, 0 pkts/sec
      5 minute input rate 1 pkts/sec,  46 bytes/sec
      5 minute output rate 2 pkts/sec,  97 bytes/sec
      5 minute drop rate, 1 pkts/sec
PER-FW#

As you can see below, the half-open connections are kept only for 30 seconds:

PER-FW# sh conn
388 in use, 2542 most used
TCP outside 132.16.242.95:4437 inside 10.0.0.10:80, idle 0:00:00, bytes 0, flags SaAB
TCP outside 45.180.196.105:7374 inside 10.0.0.10:80, idle 0:00:00, bytes 0, flags SaAB
…
TCP outside 139.45.38.60:29808 inside 10.0.0.10:80, idle 0:00:00, bytes 0, flags SaAB
TCP outside 251.45.52.118:9456 inside 10.0.0.10:80, idle 0:00:00, bytes 0, flags SaAB
TCP outside 120.180.46.9:32555 inside 10.0.0.10:80, idle 0:00:02, bytes 0, flags SaAB
TCP outside 190.97.134.67:15763 inside 10.0.0.10:80, idle 0:00:02, bytes 0, flags SaAB
…
TCP outside 93.216.144.56:12253 inside 10.0.0.10:80, idle 0:00:03, bytes 0, flags SaAB
TCP outside 79.73.193.9:28466 inside 10.0.0.10:80, idle 0:00:03, bytes 0, flags SaAB
TCP outside 115.141.225.36:2679 inside 10.0.0.10:80, idle 0:00:03, bytes 0, flags SaAB
TCP outside 202.235.0.52:18265 inside 10.0.0.10:80, idle 0:00:03, bytes 0, flags SaAB
TCP outside 46.100.213.111:3357 inside 10.0.0.10:80, idle 0:00:03, bytes 0, flags SaAB
…
TCP outside 52.54.191.123:30871 inside 10.0.0.10:80, idle 0:00:13, bytes 0, flags SaAB
TCP outside 171.140.183.72:13459 inside 10.0.0.10:80, idle 0:00:13, bytes 0, flags SaAB
TCP outside 146.14.23.38:10416 inside 10.0.0.10:80, idle 0:00:13, bytes 0, flags SaAB
TCP outside 29.105.29.26:25413 inside 10.0.0.10:80, idle 0:00:13, bytes 0, flags SaAB
TCP outside 134.132.159.121:1246 inside 10.0.0.10:80, idle 0:00:13, bytes 0, flags SaAB
….
TCP outside 207.26.176.50:18211 inside 10.0.0.10:80, idle 0:00:20, bytes 0, flags SaAB
TCP outside 46.13.236.42:20774 inside 10.0.0.10:80, idle 0:00:20, bytes 0, flags SaAB
TCP outside 184.58.42.97:28843 inside 10.0.0.10:80, idle 0:00:20, bytes 0, flags SaAB
…
TCP outside 16.185.54.105:12733 inside 10.0.0.10:80, idle 0:00:27, bytes 0, flags SaAB
TCP outside 157.244.239.122:11022 inside 10.0.0.10:80, idle 0:00:27, bytes 0, flags SaAB
TCP outside 130.80.98.111:2086 inside 10.0.0.10:80, idle 0:00:27, bytes 0, flags SaAB
TCP outside 102.155.65.57:9322 inside 10.0.0.10:80, idle 0:00:29, bytes 0, flags SaAB
TCP outside 79.180.252.112:20785 inside 10.0.0.10:80, idle 0:00:29, bytes 0, flags SaAB
TCP outside 112.112.154.108:18489 inside 10.0.0.10:80, idle 0:00:29, bytes 0, flags SaAB
TCP outside 191.31.218.24:2074 inside 10.0.0.10:80, idle 0:00:29, bytes 0, flags SaAB
TCP outside 213.125.40.95:19220 inside 10.0.0.10:80, idle 0:00:29, bytes 0, flags SaAB
TCP outside 65.75.170.103:8192 inside 10.0.0.10:80, idle 0:00:29, bytes 0, flags SaAB
PER-FW#

After 30 seconds they are removed:

PER-FW# sh logg
Syslog logging: enabled
    Facility: 20
    Timestamp logging: disabled
    Standby logging: disabled
    Debug-trace logging: disabled
    Console logging: disabled
    Monitor logging: disabled
    Buffer logging: level informational, 22071 messages logged
    Trap logging: disabled
    Permit-hostdown logging: disabled
    History logging: disabled
    Device ID: disabled
    Mail logging: disabled
    ASDM logging: disabled
nside:10.0.0.10/80 duration 0:00:30 bytes 0 SYN Timeout
%ASA-6-302014: Teardown TCP connection 3419 for outside:61.84.231.56/5802 to inside:10.0.0.10/80 duration 0:00:30 bytes 0 SYN Timeout
…
%ASA-6-302014: Teardown TCP connection 3503 for outside:92.159.9.91/21461 to inside:10.0.0.10/80 duration 0:00:30 bytes 0 SYN Timeout
%ASA-6-302014: Teardown TCP connection 3504 for outside:175.111.170.38/10465 to inside:10.0.0.10/80 duration 0:00:30 bytes 0 SYN Timeout
%ASA-6-302014: Teardown TCP connection 3505 for outside:58.116.52.96/8622 to inside:10.0.0.10/80 duration 0:00:30 bytes 0 SYN 
…
%ASA-6-302014: Teardown TCP connection 3522 for outside:95.189.67.74/17573 to inside:10.0.0.10/80 duration 0:00:30 bytes 0 SYN Timeout
%ASA-6-302014: Teardown TCP connection 3523 for outside:150.0.190.70/2709 to inside:10.0.0.10/80 duration 0:00:30 bytes 0 SYN Timeout
%ASA-6-302014: Teardown TCP connection 3524 for outside:211.185.70.62/32324 to inside:10.0.0.10/80 duration 0:00:30 bytes 0 SYN Timeout
%ASA-6-302014: Teardown TCP connection 3525 for outside:204.68.234.108/26687 to inside:10.0.0.10/80 duration 0:00:30 bytes 0 SYN 

Below you can find the CPU usage of the WEB-SRV:

WEB-SRV#sh processes cpu sorted
CPU utilization for five seconds: 12%/2%; one minute: 4%; five minutes: 2%
 PID Runtime(ms)     Invoked      uSecs   5Sec   1Min   5Min TTY Process
  83      227296       34712       6548  4.79%  1.78%  0.81%   0 IP Input
   3       11328        1288       8795  3.43%  0.48%  0.36%   0 Exec
 239       21852      907335         24  0.47%  0.32%  0.29%   0 ISG MIB jobs Man
 150       20708       11147       1857  0.31%  0.18%  0.05%   0 TCP Timer
 270        7356       14662        501  0.15%  0.03%  0.00%   0 Per-Second Jobs
  82        8544      453167         18  0.15%  0.15%  0.13%   0 IP ARP Retry Age
 112       10512      453168         23  0.15%  0.16%  0.15%   0 IPAM Manager
  59       11256        4395       2561  0.07%  0.08%  0.07%   0 HC Counter Timer
 173         184        1463        125  0.07%  0.00%  0.00%   0 QoS stats proces
 174        3136      145816         21  0.07%  0.07%  0.07%   0 RBSCP Background
 268       11416        2934       3890  0.07%  0.08%  0.07%   0 Compute load avg

WEB-SRV#

WEB-SRV#sh int gig0/0
GigabitEthernet0/0 is up, line protocol is up
  Hardware is i82543 (Livengood), address is ca02.10e8.0008 (bia ca02.10e8.0008)
  Internet address is 10.0.0.10/24
  MTU 1500 bytes, BW 1000000 Kbit/sec, DLY 10 usec,
     reliability 255/255, txload 1/255, rxload 1/255
  Encapsulation ARPA, loopback not set
  Keepalive set (10 sec)
  Full Duplex, 1000Mbps, link type is auto, media type is SX
  output flow-control is XON, input flow-control is XON
  ARP type: ARPA, ARP Timeout 04:00:00
  Last input 00:08:13, output 00:00:00, output hang never
  Last clearing of "show interface" counters 00:11:26
  Input queue: 0/75/0/0 (size/max/drops/flushes); Total output drops: 0
  Queueing strategy: fifo
  Output queue: 0/40 (size/max)
  5 minute input rate 0 bits/sec, 0 packets/sec
  5 minute output rate 0 bits/sec, 0 packets/sec
     830 packets input, 44820 bytes, 0 no buffer
     Received 0 broadcasts (0 IP multicasts)
     0 runts, 0 giants, 0 throttles
     0 input errors, 0 CRC, 0 frame, 0 overrun, 0 ignored
     0 watchdog, 0 multicast, 0 pause input
     435 packets output, 30199 bytes, 0 underruns
     0 output errors, 0 collisions, 0 interface resets
     0 unknown protocol drops
     0 babbles, 0 late collision, 0 deferred
     0 lost carrier, 0 no carrier, 0 pause output
     0 output buffer failures, 0 output buffers swapped out

WEB-SRV#sh int gig0/0 stats
GigabitEthernet0/0
          Switching path    Pkts In   Chars In   Pkts Out  Chars Out
               Processor        830      44820        436      30259
             Route cache          0          0          0          0
                   Total        830      44820        436      30259
WEB-SRV#

Let’s think a while about how we can mitigate the attack or how we can minimize its impact on our network. As you can see, we can’t apply an access list with the source of the attacker’s IP address because in this case every connection comes from a different IP address. We can’t use policy base routing (PBR), because we can’t identify the ‘bad’ traffic. We can deny all connections to our web server, but it is not a good solution the server needs to be available to our clients. This is a list of some possible solutions:

a) Context-Based Access Control (CBAC):

!CBAC TCP/UDP Intercept Feature

R3:
ip inspect max-incomplete low 500
ip inspect max-incomplete high 700
ip inspect one-minute low 90
ip inspect one-minute high 100
ip inspect tcp synwait-time 15
ip inspect tcp max-incomplete host 50 block-time 5
!
ip inspect name PROTECTDOS tcp
ip inspect name PROTECTDOS udp
ip inspect name PROTECTDOS icmp
!
ip access-list extended ATTACK
deny ip any any log
!
interface FastEthernet 0/0
ip inspect PROTECTDOS out
ip access-group ATTACK in

b) Zone Base Policy Firewall (ZBPF)

parameter-map type inspect ATTACK_CONTROL
 audit-trail on
 alert off
 max-incomplete low 200
 max-incomplete high 300
 udp idle-time 50
 dns-timeout 5
 tcp idle-time 60
 tcp synwait-time 5

zone security outside
zone security dmz


interface GigabitEthernet0/1
 zone-member security dmz
!
interface GigabitEthernet0/0
 zone-member security outside


class-map type inspect match-any DMZ-protocols
 match protocol http

policy-map type inspect outside_to_dmz

 class type inspect DMZ-protocols
  inspect ATTACK_CONTROL

 class class-default
  drop

zone-pair security OUT>DMZ source outside destination dmz
 service-policy type inspect outside_to_dmz

c) ASA:

class-map ATTACK
match any

policy-map ATTACK
class ATTACK
set connection conn-max 500 embryonic-conn-max 100
set connection timeout idle 2:0:0 embryonic 0:40:0 half-closed 0:20:0 dcd

service-policy CONNS interface outside

The number of DOS/DDOS attacks will grow as it is the easiest way to stop someone’s business. The motivations may be different, but the effect is the same: your service is not available. You should prepare your business for these kinds of attacks. Maybe you will never use this plan, but it’s definitely better to be prepared. You can’t think ‘I have a firewall, so I’m safe!’ It isn’t true, even Cisco openly says: “Although firewalls play a critical role in any organization’s security solution, they are not purpose-built DDoS prevention devices.”

 
3
Kudos
 
3
Kudos

Now read this

FlexVPN - troubleshooting

I would like to share with you very useful commands which can helpful you during your troubleshooting. Instead of checking (sometimes very long) configuration, you can check/compare the same block of configuration between your peers. 1)... Continue →