I would like to detect and send alert with snort for:
request /abc/abc.jsp and
cookie abc value is null
I tried:
alert tcp $EXTERNAL_NET any -> $HOME_NET $HTTP_PORT (sid:xxx; gid:1; content:"/abc/abc.php"; http_uri; pcre:"abc=''"; msg:"BLACKLIST - request without cookie ";)
but it does not seem to work...
Your pcre content is not following the correct syntax. You need to put the content between forward slashes (/). See the manual here. So your pcre option should look like the following:
pcre:"/abc=''/"
I would also note that this pcre probably isn't sufficient for what you want to do. I would do something like the following:
pcre:"/abc=('|\")(\1)/C"
This will allow you to look for both single and double quotes so this would match either of the following:
abc=''
abc=""
Also adding the C at the end of the pcre will tell snort to only check the following:
Match normalized HTTP request or HTTP response cookie
Which is more efficient and less prone to false positive since it's only checking the normalized cookie content.
It's also less prone to false negatives because it's checking the normalized content of the cookie because if the cookie is for some reason URL encoded ' would be %27 and " would be %22 and the pcre won't match. Giving the C option snort will check the normalized payload and would match.
So your final rule might look like:
alert tcp $EXTERNAL_NET any -> $HOME_NET $HTTP_PORT (sid:xxx; gid:1; content:"/abc/abc.php"; http_uri; pcre:"/abc=('|\")(\1)/C"; msg:"BLACKLIST - request without cookie ";)
Cookie structure: name=value;
If u want to detect cookie abc value is null, use pattern abc=;
alert tcp any any -> any any (msg:"test-cookie"; content:"abc=\;"; http_cookie; nocase;)
Related
I am trying to create a simple rule to alert when "MZ" are the first two characters in the HTTP body.
My current rule is:
alert tcp any any -> any any (msg:"Test"; content:"MZ"; depth: 2; http_client_body; sid:51; rev:1;)
But this finds no results despite "MZ" definitely being present in the HTTP body.
Assistance much appreciated.
After seeking assistance from a few other sources, it turns out I was asking snort to look in the wrong place:
The correct rule is below:
alert tcp any any -> any any (msg:"Test"; file_data; content:"MZ"; depth: 2; sid:51; rev:1;)
Instead of http_client_body after the content string, the rule needed file_data before the content string.
http_client_body = the request body
file_data = the response body*
(*It's more complicated than that, but this is sufficient to explain this case. Please see the Snort documentation for further reference)
I've set up mod_security on my server with the Owasp predefined modsec rules.
However, I'm getting a lot of false positive so I've started to set up whitelist rules.
I have a false positive on this url:
http://example.com/fr/share/?u=http%3A%2F%2Fwww.example.com%2Fen%2Ffiles%2Fimgs%2F%3Fpage%3D100%2
with "Multiple URL Encoding Detected","OWASP_CRS/PROTOCOL_VIOLATION/EVASION"
due to the rule:
SecRule ARGS "\%((?!$|\W)|[0-9a-fA-F]{2}|u[0-9a-fA-F]{4})" "phase:2,rev:'2',ver:'OWASP_CRS/2.2.9',maturity:'6',accuracy:'8',t:none,block,msg:'Multiple URL Encoding Detected',id:'1',tag:'OWASP_CRS/PROTOCOL_VIOLATION/EVASION',severity:'4',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.warning_anomaly_score},setvar:tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/EVASION-%{matched_var_name}=%{matched_var}"
So the main idea for me is to create a rule that still does the check except for the parameters "u" on url starting by /fr/share/?.
I have some hints with :
SecRule ARGS|!ARGS:u ... but how can I combine the mention where !REQUEST_URI equal to "/fr/share?.*"
So there are several options here.
You could rewrite the rule, and use chaining, to test for multiple conditions (note I've stripped off some of the rule actions for formatting reasons):
SecRule ARGS "\%((?!$|\W)|[0-9a-fA-F]{2}|u[0-9a-fA-F]{4})" \
"phase:2,rev:'2',ver:'OWASP_CRS/2.2.9',maturity:'6',accuracy:'8', \
t:none,block,msg:'Multiple URL Encoding Detected',id:'1',chain"
SecRule REQUEST_URI "!#beginsWith /fr/share/" "t:none"
The "chain" action means the rule on the next line must also pass before the actions are taken, so in this case it's checking the REQUEST_URI does not begin with /fr/share.
However this means you've got your own copy of this rule and makes upgrading to future versions of the Core Rule Set more difficult. It's much preferred to leave the original rule in place (which I've looked up and is actually rule id 950109 rather than rule id 1 that you've given so I presume that rule 1 is your copy).
So, to leave the original rule in place, but not have it false alerting you've a few options, detailed below in increasing complexity:
You could disable the whole rule:
SecRuleRemoveById 950109
This should be specified AFTER the rule is defined.
Obviously that's a bit extreme if it's only giving a false positive for one particular URL, parameter combination and means you lose the protection that rule is giving you for the any other url or parameter.
You could disable that rule for just that 'u' parameter:
SecRuleUpdateTargetById 950109 !ARGS:'u'
I think this can be specified before or after that rule is defined but not 100% sure on that.
But this will disable the for ALL 'u' parameters and you only want to disable it for this particular call, so slightly better but still not what you are looking for.
Therefore the best way is to use the ctl action, on a rule which matches the URL, to alter the original rule for that parameter:
SecRule REQUEST_URI "#beginsWith /fr/share/" \
"t:none,id:1,nolog,pass,ctl:ruleRemoveTargetById=950109;ARGS:u"
An almost identical request to what you are asking for, for rule 981260, is documented here:
https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#ctl
Please bear with me as I am not a coder by nature.
This is what I trying to achieve using HAproxy but after hours of checking, I am unable to make it works somehow.
From
domain.com/alpha
domain.com/beta
To
domain.com/alpha will point to backend1/path/index.cgi
domain.com/beta will point to backend2/path/index.cgi
I have tried, multiple ways but come to no avail, I did read about rewrite/redirect but somehow it makes me very confuse. eg "reqrep"
by using the alpha.domain.com points to backend1/path works as expected but I need the path inline because of certificate limitation.
Thank you in advance and if possible explain abit how it works and whats the correct terms (example: rewrite, redirect) so that I can have clue on that and I will advance from there.
This is what I was able to come up with:
frontend HTTP
mode http
bind *:80
acl alpha url_beg /alpha
acl beta url_beg /beta
use_backend backend_alpha if alpha
use_backend backend_beta if beta
backend backend_alpha
reqrep ^([^\ ]*\ /)alpha[/]?(.*) \1path/index.cgi
server server_alpha localhost:8080
backend backend_beta
reqrep ^([^\ ]*\ /)beta[/]?(.*) \1path/index.cgi
server server_beta localhost:8081
Obviously you would then replace localhost:8080 and localhost:8081 with the correct locations for your case.
Explanation
First, in the frontend named HTTP there are two ACLs (Access Control Lists) which test what is in the beginning of the URL (hence the keyword url_beg). The result of these rules are if the url begins with /alpha then the variable called alpha is set to true and then the same for beta.
Next in the frontend, there are two use_backend commands which will direct the request to backend_alpha if the variable alpha is set to true and the same for backend_beta if beta is set to true.
As a result the frontend does the work of taking the url and deciding which server to use.
The two backends (backend_alpha and backend_beta) are almost identical except for the text alpha and beta and the location of the respective servers. The first command in the backend is the reqrep command which you pointed out. What the reqrep command does is takes a url, searches for a particular part using Regular Expression and then replaces it with something else. In this case we have this url:
http://example.com/alpha
In the first part of the reqrep command:
^([^\ ]*\ /) takes http://example.com/ and stores it in a variable called \1
alpha then matches with the alpha in the given url
[/]?(.*) takes everything after alpha and stores it in a variable called
\2 (in this case \2 would equal nothing as there is nothing after alpha in the url)
Then the second part of the reqrep command says take the contents of \1 (http://example.com/) and add path/index.cgi to the end and make that the new url to send to the server.
As a result for both alpha and beta urls the resulting url sent to the server is http://example.com/path/index.cgi.
Finally the server command sends the request of to the appropriate server.
I would like to point out I am not an expert on the complicated Regular Expression part (I find it a bit confusing as well) but hopefully someone else who knows a bit more can explain it in more detail or correct me if I am wrong.
I hope that helps :)
I am trying to verify the contents of the http response to find a content "abbb" in it.So my rule was
alert tcp MY_SERVER HTTP_PORTS -> any any(msg:"The page accessed has content abbb";to_client; established; content:"abb";sid:XXXXX; rev:x;)
unfortunately this rule seems not to work. Can anyone please tell if there is some issue with my rule.
For starters you need to fix the to_client part of the rule as this is not valid syntax. You will need to change this to be:
flow:to_client,established;
You can find more on flow here.
If you are just looking for the content "abbb" sent from your server to the client then you just need a simple content match like you have. I recommend using the fast pattern matcher here to improve the efficiency of the rule. So your content match would look something like:
content:"abbb"; fast_pattern:only;
Putting this together, your rule might look something like:
alert tcp MY_SERVER HTTP_PORTS -> any any(msg:"The page accessed has content abbb";
flow:to_client,established; content:"abbb"; fast_pattern:only; sid:XXXXX; rev:x;)
If this still isn't triggering then there is probably something else going on. Since you are just looking for this in the content you need to check your inspection depth in the http preprocessor. There is a server_flow_depth and a client_flow_depth. Try setting these to 0 (unlimited) and see if your rule is triggering after. For example if you had a client_flow_depth of 300 and the content "abbb" didn't come until after 500 bytes then the rule is never going to trigger because snort isn't configured to inspect that far into the payload.
If you have adaptive profiling enabled then you need to add the metadata service for http otherwise the rule won't match http traffic. This would look something like:
metadata:service http;
If you don't use adaptive profiling then it will use the ports in the rule header.
How to Redirect to URL using Regular Expressions in Fiddler?
If URL mathes
regex:(?insx)^http://www.(.*)$
respond to
http://proxy.exampleproxy.info/?u=(???? what wtite here ???)
You can use AutoResponder tab to provide regex with groups as match rule and use substitution syntax in action string.
For example write this in match rule input:
regex:(?isx).*\.mycdn\.net\/.+\.(jpg|png)\?w=(\d+)&h=(\d+) #matching image urls from cdn
and this in action string input:
*redir:http://lorempixel.com/$2/$3/cats
this rule will match url like this:
http://someimage.mycdn.net/some-directory/some-url.jpg?w=300&h=166
and would redirect to this url
http://lorempixel.com/300/166/cats/
*redir action means that fiddler would respond with 307 code (Temporary Redirect) and Location header with url to redirect. If you omit this string then fiddler would respond with 301 code (Moved Permanently) instead.
fiddler2 doesn't support using the capture text in the response.
http://groups.google.com/group/httpfiddler/msg/60e8b897867cdb7b
Need to use rules instead.