Testing your installation
After completing the installation we need a way to test that the ModSecurity module has been loaded and is working as it should. The procedure described here can be used to test that ModSecurity is functioning correctly whenever you feel the need to verify this (such as after making changes to your Apache configuration file).
Creating a simple ModSecurity rule
To test that ModSecurity is working correctly we will create a simple HTML file and then deny access to it using a ModSecurity rule. Change to your web server's DocumentRoot
directory and run the following command to create a file called secret.html
containing our secret string:
$ echo "The owl flies at midnight" > secret.html
Next, verify that you are able to access the file and see its content at the location http://yourserver/secret.html
.
The main configuration directive used to create ModSecurity rules is called SecRule
. You will learn all about using the SecRule
directive in Chapter 2, but for now all you need to know is that this directive allows you to block content based on regular expressions.
We will now create a security rule to block access to this file. Enter the following in your modsec.conf
file, below the configuration settings.
# Block all requests that have the string "secret" in the URI SecRule REQUEST_URI "secret"
Save the file and restart Apache to make it load the new security rule. Now try accessing the file again—you should get an "access denied" message, meaning that ModSecurity is doing its job and blocking access to the file because the URI contains the regular expression "secret".
Tip
If you add new ModSecurity rules on a production server, you can use apachectl graceful
to restart Apache without closing currently open connections. However, this can cause inconsistent behavior when testing rules, as sometimes you may get an Apache instance that has not yet terminated after the graceful restart (and thus has the old ModSecurity rules loaded in memory). Consider always doing a full restart with apachectl restart
when testing out your rules.
What ModSecurity does with this rule is match the "secret" phrase against the request URI. Since the regular expression "secret" matches the filename secret.html
, the rule is a match and the default action specifies that the request should be denied with a 403 error.
Disguising the web server signature
Suppose a highly motivated attacker wanted to target your server specifically. What would be one of the first things he would do? Finding out which operating system and web server software your system is running would be important to him, as he would then be able to create a replica of your server and probe it for weaknesses in the comfort of his own home.
It follows, then, that disguising what web server software your system is running can help prevent an attack, or at least make it more difficult to carry out. This is actually something that is debated in the security community as some argue that "security by obscurity" is never the way to go. I am however of the belief that you should make life as difficult as possible for potential attackers, and if that means disguising the server version and list of installed modules then that's what you should do.
Apache itself actually doesn't provide a configuration directive to change the server signature—all you can do (unless you change the source code and compile Apache from source) is to use ServerTokens ProductOnly
in the Apache configuration file, which will reduce the server signature to "Apache".
Using ModSecurity, we can change the server name to a different brand of server entirely, like for example Microsoft-IIS/5.0
. We will however be a little bit more sneaky and just change the server version to make it look like we are running an old legacy version of Apache.
First you need to tell Apache to send full server version information. This is so that ModSecurity can recognize and alter the server signature—setting the signature to full creates a big enough buffer space in memory to allow for alterations. Simply make sure you have the following line in your httpd.conf:
# Send full server signature so ModSecurity can alter it ServerTokens Full
Finally, put the following line in your modsec.conf
file and restart Apache to change the server signature:
# Alter the web server signature sent by Apache SecServerSignature "Apache 1.3.24"
This is an old version of Apache full of security vulnerabilities. Seeing this, an attacker might well waste a lot of time trying to use an old exploit to break into the system, hopefully triggering audit logs along the way to alert you of the attempted break-in.
The possibilities are endless when running your web server under a false flag—you could for example add unused Apache modules to the server signature to make it look like you are running all sorts of exploitable modules. This will not be a big stumbling block to an experienced attacker, as there are programs out there that fingerprint web servers and give the best guess as to the real name and version being run (we will be defeating this sort of program later on, in Chapter 6). However, it only makes sense to make the attacker's job as difficult as possible—every little bit really does help.
To test that your new server signature is working, you can use netcat while logged into your server to take a look at the response header Apache is sending out. If the server signature change was successful, you should see a line reading Server: Apache 1.3.24 in the header near the top of the output:
$ echo -e "HEAD / HTTP/1.0\n\n" | nc localhost 80 HTTP/1.1 200 OK Date: Wed, 28 Jan 2009 15:01:56 GMT Server: Apache 1.3.24 Last-Modified: Mon, 26 Jan 2009 12:01:12 GMT ETag: "6391bf-20-461617eaf9200" Accept-Ranges: bytes Content-Length: 32 Connection: close Content-Type: text/html; charset=UTF-8