ModSecurity Sql Injections prevention

Today we had a long day, some nice people were tryin’ some sql injections in our applications. Unfortunately they got it quite easy against an old web application (sic). Our alerting system rang since 14.00 and from then we had a very intense afternoon…

The situation is easy to understand:

  • PHP is not such strong-typed language
  • sometimes the lazy programmer forgets to cast variables against their types…
  • and then somebody else finds a good way to retrieve informations from the database (and maybe from the system)

After the first few minutes-panic, we realized that the solution was to install ModSecurity on our system (we do run some LAMP machines, so we needed a module for Apache).

ModSecurity 2.7.7 on Scientific Linux 6.4

Dependencies

The ModSecurity’s installation process on Scientific Linux 6.4 is quite easy, first of all you have to install the necessary dependencies:

yum install libxml2 libxml2-devel httpd-devel pcre-devel curl-devel

ModSecurity

Than you can proceed with ModSecurity itself:

cd /usr/src
wget --no-check-certificate https://www.modsecurity.org/tarball/2.7.7/modsecurity-apache_2.7.7.tar.gz
tar -xzvf modsecurity-apache_2.7.7.tar.gz
cd modsecurity-apache_2.7.7
./configure
make
make install
cp modsecurity.conf-recommended /etc/httpd/conf.d/modsecurity.conf
cp unicode.mapping /etc/httpd/conf.d/unicode.mapping

OWASP CRS

ModSecurity needs a few rules to work on… so you have to install them and activate all…

cd /etc/httpd/
wget https://github.com/SpiderLabs/owasp-modsecurity-crs/tarball/master -O SpiderLabs-owasp-modsecurity-crs-2.2.8-8.tar
tar -xvf SpiderLabs-owasp-modsecurity-crs-2.2.8-8.tar
mv SpiderLabs-owasp-modsecurity-crs-7528b8b modsecurity-crs
cd modsecurity-crs
cp modsecurity_crs_10_setup.conf.example modsecurity_crs_10_config.conf
for f in `ls base_rules/` ; do ln -s /etc/httpd/modsecurity-crs/base_rules/$f activated_rules/$f ; done
for f in `ls optional_rules/ | grep comment_spam` ; do ln -s /etc/httpd/modsecurity-crs/optional_rules/$f activated_rules/$f ; done

General configuration

Then you can proceed to configure the Apache module:

vi /etc/httpd/conf.d/modsecurity.conf

Add the following line to the top of the file:

LoadModule security2_module modules/mod_security2.so

Activate the engine modifying the SecRuleEngine directive setting it On:

SecRuleEngine On

Put the following lines at the end of the file:

SecPcreMatchLimit 150000
SecPcreMatchLimitRecursion 150000
<IfModule security2_module>
    Include /etc/httpd/modsecurity-crs/modsecurity_crs_10_config.conf
    Include /etc/httpd/modsecurity-crs/activated_rules/*.conf
</IfModule>

Last, but very important, you have to add mod_unique_id to the apache conf file. Mod_unique_id is normally shipped with the apache package, but you have to activate it putting the right code in the right place… First enter the apache conf file with vi:

vi /etc/httpd/conf/httpd.conf

Put the following line (if not already there):

LoadModule unique_id_module modules/mod_unique_id.so

Tweaking

ModSecurity is very polite: it does what you tell it to do: after a few days you will discover a word of false positives… and this not so good….

Accordingly with Spiderlabs’ Blog there are two ways to let ModSecurity work:

  • Traditional Detection Mode (which is the default)
  • Anomaly Scoring Detection Mode – Collaborative Rules

I strongly encourage the use of the second one…. to activate it you have to follow these few steps.

First open the modsecurity_crs_10_config.conf file:

vi /etc/httpd/modsecurity-crs/modsecurity_crs_10_config.conf

Identify the following line:

SecDefaultAction "phase:1,pass,log"

and substitute it with

SecDefaultAction "phase:2,pass,log,noauditlog"

(the “log, noauditlog” part is to avoid ModSecurity logging to /var/log/modsec_audit.log)

Then identify the following lines:

#SecAction \
"id:'900004', \
phase:1, \
t:none, \
setvar:tx.anomaly_score_blocking=on, \
nolog, \
pass"

and uncomment the first one:

SecAction \
"id:'900004', \
phase:1, \
t:none, \
setvar:tx.anomaly_score_blocking=on, \
nolog, \
pass"

A restart…

After this you can restart apache and take a look at log files

/etc/init.d/httpd restart && tail -f /var/log/httpd/error_log

If you’ve done all right, you should read something like

[...] ModSecurity for Apache/2.7.7 (http://www.modsecurity.org/) configured.
[...] ModSecurity: APR compiled version="1.2.7"; loaded version="1.2.7"
[...] ModSecurity: PCRE compiled version="8.10"; loaded version="8.10 2010-06-25"
[...] ModSecurity: LIBXML compiled version="2.6.26"

That’s it! Enjoy your brand new protection system!

Flush sendmail queue

Sendmail is my preferred MTA and i have it installed on every system we use. Often i have the need to flush sendmail queue and let emails flow throught again.

It’s simple to let sendmail flush out all queued messages, use this command:

sendmail -v -q

This BASH line will flush the entire queue with a high verbosity, so it will be quite easy any debugging action…

Sometimes it can happen that a busy system (when the load reaches some high levels) enqueues all messages. This is normally managed by a setting in sendmail.cf file:

# load average at which we just queue messages
#O QueueLA=8

# load average at which we refuse connections
#O RefuseLA=12

I personally discurage the editing of sendmail.cf, since i prefer to modify the sendmail.mc:

vi /etc/mail/sendmail.mc

Add, if they’re not present, the following lines:

define(`confQUEUE_LA', `25')dnl
define(`confREFUSE_LA', `26')dnl

In this case we are setting sendmail to queue (without delivery) messages when the machine’s load in higher than 25, and refuse new connections when the load is over 26…. consider not to leave those values in a production environment!

After doing this you should recompile your configuration with:

make -C /etc/mail
/etc/init.d/sendmail restart

The last command will restart sendmail with it’s new configuration.