Skip to content

Instantly share code, notes, and snippets.

@redesigned
Created September 18, 2013 11:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save redesigned/6607741 to your computer and use it in GitHub Desktop.
Save redesigned/6607741 to your computer and use it in GitHub Desktop.
mod_security
Troubleshooting Mod_Security 2.5:
The first step is to identify which rule is blocking your users or breaking your site. To see what is happening, check your Apache Error log or your Mod_Security log. In your logs, you will see something like this:
Pattern match "(?:cd |\;|php |echo |perl |killall |python |rpm |yum |apt-get |emerge |lynx |links |mkdir |elinks |wget |lwp-(?:download|request|mirror|rget) |id|uname |cvs |svn |(?:s|r)(?:cp|sh) |net(?:stat|cat) |rexec |smbclient |t?ftp |ncftp |curl |telnet |g?cc |cp ..." at REQUEST_URI. [file "/etc/modsecurity/10_asl_rules.conf"]
[line "587"] [id "340037"] [rev "3"] [msg "Atomicorp.com - FREE UNSUPPORTED DELAYED FEED - WAF Rules: Generic command injection"] [severity "CRITICAL"]
yoursite.com 81.99.13.12 340037 [07/Jan/2011:22:43:29 --0800]
Pattern match "(?:cd |\;|php |echo |perl |killall |python |rpm |yum |apt-get |emerge |lynx |links |mkdir |elinks |wget |lwp-(?:download|request|mirror|rget) |id|uname |cvs |svn |(?:s|r)(?:cp|sh) |net(?:stat|cat) |rexec |smbclient |t?ftp |ncftp |curl |telnet |g?cc |cp ..." at REQUEST_URI. [file "/etc/modsecurity/10_asl_rules.conf"] [line "587"] [id "340037"] [rev "3"] [msg "Atomicorp.com - FREE UNSUPPORTED DELAYED FEED - WAF Rules: Generic command injection"] [severity "CRITICAL"]
[07/Jan/2011:22:43:29 --0800] THcUgdXS8AADiSIm4AX 81.99.13.12 42556 42.22.93.39 80
--c349556d-B--
GET /modules/forum/hide-comments.png HTTP/1.1
Host: yoursite.com
User-Agent: Mozilla/5.0 (iPad; U; CPU OS 4_2_1 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5
Referer: http://yoursite.com/the-referring-page.html
Accept: */*
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Look through the log for the “id” and file – in the example above, it’s [file/etc/modsecurity/10_asl_rules.conf] and the ID is rule #340037. Now you know what mod_security file to focus on (10_asl_rules.conf) and where in that file to start looking (rule/id 340037).
Open up file 10_asl_rules.conf and search until you find 340037 -
Rule 340037 looks like this:
# Rule 340037: generic attack signature
SecRule REQUEST_URI "(?:cd |\;|php |echo |perl |killall |python |rpm |yum |apt-get |emerge |lynx |links |mkdir |elinks |wget |lwp-(?:download|request|mirror|rget) |id|uname |cvs |svn |(?:s|r)(?:cp|sh) |net(?:stat|cat) |rexec |smbclient |t?ftp |ncftp |curl |telnet |g?cc |cpp |g\+\+ |/bin/(xterm|id|bash|sh|echo|kill|chmod|ch?sh|python|perl|nasm|ping|mail|ssh))" \
"id:340037,rev:3,severity:2,msg:'Atomicorp.com - FREE UNSUPPORTED DELAYED FEED - WAF Rules: Generic command injection'"
Now you need to figure out what it is about this rule that is going wrong, so back to the error log:
The error (above) says “Pattern match” (then all the match-rules) at REQUEST_URI. “REQUEST_URI” is the Mod_Security directive to inspect the URL being requested. (For a list of all the directives, check the MODSECURITY online-manual). To see what the URL was, find the GET command a little further down – in the example above, it’s GET /modules/forum/hide-comments.png
So we now know that rule #340037 located in file 10_asl_rules.conf does not like “modules/forum/hide-comments.png” – So let’s figure out why.
Rule 340037 (above) is made up of just a few lines (like most rules). The first line, starting with the ‘#’ is a comment describing the rule: # Rule 340037: generic attack signature
The next line:
"SecRule REQUEST_URI "(?:cd |\;|php |echo |perl |killall |python |rpm |yum |apt-get |emerge |lynx |links |mkdir |elinks |wget |lwp-(?:download|request|mirror|rget) |id|uname |cvs |svn |(?:s|r)(?:cp|sh) |net(?:stat|cat) |rexec |smbclient |t?ftp |ncftp |curl |telnet |g?cc |cpp |g\+\+ |/bin/(xterm|id|bash|sh|echo|kill|chmod|ch?sh|python|perl|nasm|ping|mail|ssh))"
Basically says if the URL matches this very complex regular expression, then do what’s in the next line, which reads:
"id:340037,rev:3,severity:2,msg:'Atomicorp.com - FREE UNSUPPORTED DELAYED FEED - WAF Rules: Generic command injection'"
This ID’s the rule as ’340037′ with revision#3, sets the severity level for logging, and assigns the message to show in the logs – because elsewhere in the mod_security configuration the default action as been set to “deny” – this page/url will been blocked – but WHY?
To figure out what it is about about the path “modules/forum/hide-comments.png” that the expression above does not like you can try to read-through it and figure it out (good luck!) or use a RegEx (Regular Expression) tool such as www.gskinner.com/RegExr to see what the match is. In our example, it is the “id” in the path ‘hide-comments.png’ that matches (?:download|request|mirror|rget) |id|uname |cvs |svn |(?:s|r) in the rule.
Now we know where and why Mod_Security has blocked this particular page.. Now what?
Now you have to decide what to do about it – here are some choices:
1) Disable the entire rule
2) Disable the rule only for this particular URL (“ByLocation”)
3) Create a slightly modified custom rule that overrides this rule and works with this particular page/URL
Which route you take depends on many things and I can’t tell you which to choose – that part you will have to figure out on your own.
Option 1 – Disable the entire rule:
You could simply delete all the lines associated with rule 340037, or comment them out by putting a ‘#’ on each line, then restart Apache. The problem with this method is that if you ever update your rules, your changes will be overwritten with the new file, and the rule would be active again. A better way to disable the rule is to add the following line in your HTTP.CONF or MODSEC2.CONF file:
SecRuleRemoveById 340037
Restart Apache and now rule 340037 will be disabled
Option 2 – Disable the rule just for this particular URL:
You can tell Mod_security to ignore rule 340037 only for the URL /modules/forum/hide-comments.png by adding the following line to your HTTP.CONF or MODSEC2.CONF file:
<LocationMatch modules/forum/hide-comments.png>
SecRuleRemoveById 340037
</LocationMatch>
Restart Apache and now rule 340037 will be ignored/disabled only for the URL /modules/forum/hide-comments.png
Option 3 – Replace rule 340037 with your own, slightly customized rule:
You can create your own custom rule that does not include the “id” match, then disable the ‘real’ rule 340037.
First, create a new file named something like “99_my_rules.conf” and place in the same directory as your other Mod_Security rules (probably at /etc/modsecurity). Copy and paste rule 340037 from 10_asl_rules.conf and put into your new custom-rules file and make the following changes:
Change “340037″ to 990037 – This will keep you from confusing it with the real rule “340037″
Change the message from : ‘Atomicorp.com – FREE UNSUPPORTED DELAYED FEED – WAF Rules: Generic command injection’
to something like: ‘My custom rule that replaces 340037′
Find the part of the expression that we want to get rid of – in this case it is the “id” at this part:
|request|mirror|rget) |id|uname |cvs |svn
Remove the “id|”, which should leave just:
|request|mirror|rget) |uname |cvs |svn
and save the file.
In your HTTP.CONF or MODSEC2.CONF file, disable the original rule 340037 by following Option #1 above
Add the following line in your HTTP.CONF or MODSEC2.CONF file to tell Mod_security to load your new custom rules:
Include /etc/modsecurity/99_my_rules.conf — place this line right after the other rules listed. Be sure to use the correct path for your system.
Restart Apache and now the original rule 340037 will be disabled and your new rule 990037 will be active. If you ever need to create any other custom rules, just add them into your new 99_my_rules.conf file (and restart Apache).
Some things to keep in mind when changing Mod_Security rules:
Before you change any files, make a copy of it first. It’s very easy to make a syntax error, or screw something up.
Each time you restart Apache, make sure it actually starts and check your site! If Apache will not start, just put back the backup file that you made, and start Apache again – then figure out what went wrong.
If you disabled blocking in Mod_Security with the SecFilterEngine Off directive, be sure to change it back to SecFilterEngine ON
Most important – watch your logs very closely and verify that ModSecurity is only blocking things you really want blocked.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment