In my previous post I already went into a couple of screens, mainly ones that detect or block network reconnaissance tactics, such as Ping Sweeps, Port Scans and OS detection. This article will focus more on the DoS and DDoS attacks itself, like SYN and session floods.
The network topology will remain the same as last time, with one host on the dmz network and an attacker on the outside, where the Screen is positioned.
ip-spoofing – Unicast Reverse Path Forwarding check
Similar to how the RPF mechanism on routers and other L3 devices works, the IP-Spoofing Screen compares the source address of the incoming packet against the longest matched prefix in the forwarding-table. If the best route found is pointing to an interface other than the one on which the packet was received, the OS decides it must be a spoofed packet and drops it.
We already have a Screen profile configured from the previous post, so I will just be adding the ip-spoofing option:
[edit security screen ids-option Attack-Screen]
root@NP-vSRX-01# set ip spoofing
[edit security screen ids-option Attack-Screen]
root@NP-vSRX-01# show | compare
[edit security screen ids-option Attack-Screen ip]
+ spoofing;
To spoof the packets’ source IP, I will be using NPING, which gives you granular control of all the fields and options in the L3 and L4 protocol headers.
I will be sending 5 packets, destined for the server’s IP address on port 80, with a spoofed IP address of 10.0.100.50.
lab@Host200:~$ sudo nping --tcp -p 80 -S 10.0.100.50 10.0.100.100
Starting Nping 0.6.46 ( http://nmap.org/nping ) at 2015-07-28 23:10 CEST
SENT (0.0028s) TCP 10.0.100.50:49704 > 10.0.100.100:80 S ttl=64 id=13538 iplen=40 seq=3917867081 win=1480
SENT (1.0032s) TCP 10.0.100.50:49704 > 10.0.100.100:80 S ttl=64 id=13538 iplen=40 seq=3917867081 win=1480
SENT (2.0046s) TCP 10.0.100.50:49704 > 10.0.100.100:80 S ttl=64 id=13538 iplen=40 seq=3917867081 win=1480
SENT (3.0060s) TCP 10.0.100.50:49704 > 10.0.100.100:80 S ttl=64 id=13538 iplen=40 seq=3917867081 win=1480
SENT (4.0073s) TCP 10.0.100.50:49704 > 10.0.100.100:80 S ttl=64 id=13538 iplen=40 seq=3917867081 win=1480
Max rtt: N/A | Min rtt: N/A | Avg rtt: N/A
Raw packets sent: 5 (200B) | Rcvd: 0 (0B) | Lost: 5 (100.00%)
Nping done: 1 IP address pinged in 5.01 seconds
The source IP obviously belongs to the same subnet as the destination so if the ip-spoofing Screen works as advertised, we should see it in the logs:
2015-07-28 21:06:30 UTC IP spoofing! source: 10.0.100.50, destination: 10.0.100.100, protocol-id: 6, zone name: attacker, interface name: ge-0/0/2.0, action: drop
2015-07-28 21:06:31 UTC IP spoofing! source: 10.0.100.50, destination: 10.0.100.100, protocol-id: 6, zone name: attacker, interface name: ge-0/0/2.0, action: drop
2015-07-28 21:06:32 UTC IP spoofing! source: 10.0.100.50, destination: 10.0.100.100, protocol-id: 6, zone name: attacker, interface name: ge-0/0/2.0, action: drop
2015-07-28 21:06:33 UTC IP spoofing! source: 10.0.100.50, destination: 10.0.100.100, protocol-id: 6, zone name: attacker, interface name: ge-0/0/2.0, action: drop
2015-07-28 21:06:34 UTC IP spoofing! source: 10.0.100.50, destination: 10.0.100.100, protocol-id: 6, zone name: attacker, interface name: ge-0/0/2.0, action: drop
The packets were dropped -which is good- but unfortunately, the log doesn’t mention any source or destination ports in the logs. If somebody was trying to send spoofed packets to my server, it would be great to know which port they were targeting.
Sidenote – the SRX also has a second way of configuring this, being the standard rpf-check, which is covered in the JNCIA curriculum. This one is easier though.
session-limt – Limiting sessions by Source or Destination IP
This Screen can put a cap on the maximum number of connections any given source or destination IP can create. Any subsequent connections will be dropped. This is a very basic setting, and it does require you to establish a baseline for the amount of connections you expect on any given server. If you are unsure at first, you can configure the alarm-without-drop
setting to create a baseline first.
For this example, suppose that we are a small shop running an FTP service and we never expect more than 64 simultaneous connections to our server. I will configure a destination-limit of 64 connections and a source-limit of 16 to protect it against flooding by a single remote host.
[edit security screen ids-option Attack-Screen]
root@NP-vSRX-01# set limit-session destination-ip-based 64 source-ip-based 16
Flooding the server with connection attempts, 1000 packets per second.
lab@Host200:~$ sudo nping 10.0.100.100 --tcp-connect -rate=1000 -c 5000 -q $1 -p 21
Starting Nping 0.6.46 ( http://nmap.org/nping ) at 2015-08-11 23:10 CEST
Max rtt: 1.956ms | Min rtt: 0.108ms | Avg rtt: 0.950ms
TCP connection attempts: 5000 | Successful connections: 16 | Failed: 4984 (99.68%)
Nping done: 1 IP address pinged in 9.17 seconds
As configured on the screen, the remote host only received 16 responses from the FTP server. Again, this logging is pretty basic – no destination IP or port numbers mentioned…
2015-08-11 21:33:50 UTC Src IP session limit! source: 10.0.200.200, zone name: attacker, interface name: ge-0/0/2.0, action: drop
2015-08-11 21:33:50 UTC Src IP session limit! source: 10.0.200.200, zone name: attacker, interface name: ge-0/0/2.0, action: drop
2015-08-11 21:33:50 UTC Src IP session limit! source: 10.0.200.200, zone name: attacker, interface name: ge-0/0/2.0, action: drop
By using randomized source IP addresses (with hping3) I was also able to trigger the destination-limit.
2015-08-11 21:27:04 UTC Dst IP session limit! destination: 10.0.100.100, zone name: attacker, interface name: ge-0/0/2.0, action: drop
2015-08-11 21:27:04 UTC Dst IP session limit! destination: 10.0.100.100, zone name: attacker, interface name: ge-0/0/2.0, action: drop
2015-08-11 21:27:04 UTC Dst IP session limit! destination: 10.0.100.100, zone name: attacker, interface name: ge-0/0/2.0, action: drop
It’s pretty basic, but it does protect your device from getting flooded by remote hosts. While testing without the screen, it wasn’t that difficult to DoS my virtual machines’ FTP, SSH and Telnet daemons when flooding connections (at 1 Gbps 🙂 )
syn-ack-ack – Handshake proxying
Similar to the session-limit, the SYN-ACK-ACK screen will limit the number of concurrent sessions any untrusted host can establish. This time, the SRX will serve as the middle-man between the source and destination hosts. First, the SRX will check the session table and, if a new session needs to be initiated, perform the three-way handshake with the initiator. Once the handshake between the remote host and SRX is complete, the SRX will proxy the three-way handshake to the server, after which the original source and destination can communicate.
The SRX keeps track of all the sessions it has established and will, once the syn-ack-ack proxy treshold for a particular source IP has been reached, reject any further connection attempts.
Defining a threshold of 512 sesssions:
[edit security screen ids-option Attack-Screen]
root@NP-vSRX-01# set tcp syn-ack-ack-proxy threshold 512
Again, it would be best to make a good baseline of expected traffic patterns before implementing this…
syn-flood – embryonic session floods
Probably the most commmon Layer4 attack is the SYN flood, in which your boxes get flooded with SYN packets from seemingly thousands of hosts. Although it is quite possible that you’re being pwned by a botnet, it’s more likely that the packets are being spoofed with random source IPs. The server will then create a half-open socket, reply to the bogus IP with a SYN-ACK and wait for a response that will never come. Obviously, at thousand and thousands of packets per second, this can fill up the session table quite rapidly and kill your server.
By enabling this screen, the SRX will monitor and police the number of SYN packets passing through the device. There are five parameters to consider for the syn-flood screen:
- Attack Threshold – the total number of SYN packets per second that can be received before the SRX starts proxying SYN packets, taking the burden off the servers shoulders
- Alarm Threshold – how many embryonic sessions can be created before a syslog event is logged
- Source Threshold – the total number of SYN packets that can be received from any given source IP
- Destination Threshold – the number of SYN packets that can be received destined for a particular destination IP (your server)
- Timeout – how long the SRX should wait before killing of a half-open session
Let’s illustrate with an example. At 100 SYN packets, the SRX will go into proxying mode. When 50 more packets are received within a second, an alarm will be logged. The threshold per source IP is 50 pps. Half-open sessions will time out after 10 seconds.
[edit security screen ids-option Attack-Screen tcp syn-flood]
root@NP-vSRX-01# show
alarm-threshold 150;
attack-threshold 100;
source-threshold 50;
timeout 10;
Flooding port 21 with hping3:
lab@Host200:~$ sudo hping3 -S --flood -V $1 10.0.100.100 -p 21
using eth0, addr: 10.0.200.200, MTU: 1500
HPING 10.0.100.100 (eth0 10.0.100.100): S set, 40 headers + 0 data bytes
hping in flood mode, no replies will be shown
^C
--- 10.0.100.100 hping statistic ---
4735022 packets transmitted, 0 packets received, 100% packet loss
round-trip min/avg/max = 0.0/0.0/0.0 ms
The SRX security log:
2015-08-14 20:33:19 UTC SYN flood Src-IP based! source: 10.0.200.200:1106, destination: 10.0.100.100:21, zone name: attacker, interface name: ge-0/0/2.0, action: drop
2015-08-14 20:33:19 UTC SYN flood Src-IP based! source: 10.0.200.200:1107, destination: 10.0.100.100:21, zone name: attacker, interface name: ge-0/0/2.0, action: drop
2015-08-14 20:33:19 UTC SYN flood Src-IP based! source: 10.0.200.200:1108, destination: 10.0.100.100:21, zone name: attacker, interface name: ge-0/0/2.0, action: drop
2015-08-14 20:33:19 UTC SYN flood! destination: 10.0.100.100, zone name: attacker, interface name: ge-0/0/2.0, action: alarm-without-drop
2015-08-14 20:33:20 UTC SYN flood! destination: 10.0.100.100, zone name: attacker, interface name: ge-0/0/2.0, action: alarm-without-drop
2015-08-14 20:33:21 UTC SYN flood! destination: 10.0.100.100, zone name: attacker, interface name: ge-0/0/2.0, action: alarm-without-drop
Another good example can be found on the Juniper site.
Enabling SYN Cookies
With the SYN cookie feature, the SRX will take some attributes of the original SYN packet and run it through a mathematical formula, resulting in a hashed number. This number will be used as the Initial Sequence number in the returned SYN-ACK packet. When the final ACK packet is received, it is validated against the “challenge” that was sent in the initial response.
You can read all about SYN Cookies here and here.
Enabling it is not done at the ids-options, but at the flow options:
[edit security flow]
root@NP-vSRX-01# set syn-flood-protection-mode syn-cookie
Dropping TCP LAND attacks
By sending a specially crafted TCP packet to a server, which contains the same IP as destination in the source field it is possible to exhaust the session table. The server would then send the responses to itself and create half-open sessions. This is called a Local Area Network Denial attack. Seems like recent operating systems are no longer vulnerable but then again, not everyone is running recent operating systems 🙂
Enabling it – I also disabled the RPF check just to be sure it will be hit:
[edit security screen ids-option Attack-Screen]
root@NP-vSRX-01# set tcp land
I first tried triggering this with just a couple of packets crafted in nping, but it was not triggering the Screen. Seems like the LAND screen doesn’t filter every packet, but instead only triggers when being flooded…
lab@Host200:~$ sudo hping3 -S --flood -V $1 10.0.100.100 -p 21 -a 10.0.100.100
using eth0, addr: 10.0.200.200, MTU: 1500
HPING 10.0.100.100 (eth0 10.0.100.100): S set, 40 headers + 0 data bytes
hping in flood mode, no replies will be shown
^C
--- 10.0.100.100 hping statistic ---
4561685 packets transmitted, 0 packets received, 100% packet loss
round-trip min/avg/max = 0.0/0.0/0.0 ms
This time, the LAND attack was logged on the SRX:
2015-08-14 21:09:59 UTC Land attack! source: 10.0.100.100:21, destination: 10.0.100.100:21, zone name: attacker, interface name: ge-0/0/2.0, action: drop
2015-08-14 21:10:00 UTC Land attack! source: 10.0.100.100:21, destination: 10.0.100.100:21, zone name: attacker, interface name: ge-0/0/2.0, action: drop
2015-08-14 21:10:01 UTC Land attack! source: 10.0.100.100:21, destination: 10.0.100.100:21, zone name: attacker, interface name: ge-0/0/2.0, action: drop
2015-08-14 21:10:01 UTC Land attack! source: 10.0.100.100:21, destination: 10.0.100.100:21, zone name: attacker, interface name: ge-0/0/2.0, action: drop
2015-08-14 21:10:01 UTC Land attack! source: 10.0.100.100:21, destination: 10.0.100.100:21, zone name: attacker, interface name: ge-0/0/2.0, action: drop
2015-08-14 21:10:02 UTC Land attack! source: 10.0.100.100:21, destination: 10.0.100.100:21, zone name: attacker, interface name: ge-0/0/2.0, action: drop
However, it didn’t stop all packets. This was rushing across the screen on the end node, using tcpdump:
23:14:01.539414 IP 10.0.100.100.21 > 10.0.100.100.4271: Flags [S.], seq 1210268274, ack 1980846482, win 0, length 0
23:14:01.539415 IP 10.0.100.100.21 > 10.0.100.100.4272: Flags [S.], seq 1893206533, ack 1324671463, win 0, length 0
23:14:01.539416 IP 10.0.100.100.21 > 10.0.100.100.4273: Flags [S.], seq 1640167563, ack 1602524016, win 0, length 0
23:14:01.539641 IP 10.0.100.100.21 > 10.0.100.100.4274: Flags [S.], seq 1406775185, ack 1845052534, win 0, length 0
23:14:01.539643 IP 10.0.100.100.21 > 10.0.100.100.4275: Flags [S.], seq 339434124, ack 711012714, win 0, length 0
23:14:01.539644 IP 10.0.100.100.21 > 10.0.100.100.4276: Flags [S.], seq 1167828292, ack 2077183650, win 0, length 0
23:14:01.539645 IP 10.0.100.100.21 > 10.0.100.100.4277: Flags [S.], seq 275256947, ack 780565910, win 0, length 0
23:14:01.539645 IP 10.0.100.100.21 > 10.0.100.100.4278: Flags [S.], seq 296173682, ack 804236181, win 0, length 0
23:14:01.539646 IP 10.0.100.100.21 > 10.0.100.100.4279: Flags [S.], seq 505740912, ack 547788184, win 0, length 0
So it does detect the land packets, but doesn’t block all of them. A better option in this case would be to enable the ip-spoofing option:
2015-08-14 21:23:48 UTC IP spoofing! source: 10.0.100.100, destination: 10.0.100.100, protocol-id: 6, zone name: attacker, interface name: ge-0/0/2.0, action: drop
I’ll be wrapping up here for today. Part three will cover the last Screen options from the JNCIS-SEC curriculum, mostly smaller options related to OS attacks and some of the IP header fields.
Thanks for reading!