Web Application Firewalls with Mod Security
One of the biggest problems that businesses and individuals face today is the cost of web application security.
It is not uncommon in the UK, for example, to pay a daily rate of around £1000 to have a website tested by an application security consultant. Web Application Firewalls can be just as bad. A very large vendor charges around $15,000 for a software virtual appliance and $20,000 for a hardware version with support for 12 months.
However, the costs of WAFs have been cut recently with the introduction of cloud based firewall services. The idea behind this type of product is that one firewall can cover more than one application server.
This article is going to discuss the use of an open source web application firewall and provide proof of concept of the idea of creating an appliance out of it.
While an in-depth discussion of web application security is beyond the scope of this article, I believe there are three different ways in which you can secure your web application:
- Secure Development Life Cycle (SDLC)
- Web Application Testing
- Web Application Firewall (WAF)
Developers should be incorporating every step into the creation of their web app, but we will be focusing on the WAF here.
Mod Security is a free open source web application firewall that was recently acquired by Trustwave (www.trustwave.com) as part of their SpiderLabs research division (where I will begin working this July). This allows them to develop additions quickly and get them out into the community to be tested. Mod Security is one of the most widely deployed and maintained WAFs available. As such, a lot of research and additional projects have been built on this and can all be found on the Mod Security website (www.modsecurity.org)
This web application firewall has been created to secure an Apache web server. There are a number of ports that are currently being made available. They can be found on the website, but they are still early in their development.
The method discussed in this article intercepts all requests and then sends the parsed / accepted requests to the relevant web server meaning that it will secure not just an Apache server but all types of servers available.
To demonstrate what we want to discuss, we will be using two virtual machines. This example will be using Ubuntu Minimal 10.04 (http://archive.ubuntu.com/ubuntu/dists/lucid/main/installer-i386/current/images/netboot/mini.iso) because it is the quickest install I have found and because this isn’t going to be a live server, so it doesn’t matter what I use. You can prepare your Virtual Machines the same way if you want to follow along with what I am doing and not just read the article.
The image below shows the settings that I chose at the software selection stage of the installation. This again is to help me speed up the process and you may decide to install Apache, PHP and MySQL etc. manually. I also installed OpenSSH so that I could SSH from my host machine to the guests and not have to enter the VM when it is powered on.
I created two VMs with the same configuration, barring the hostname. This is so I can emulate one server being the WAF and another server being the application server. Make sure that you bridge the connections onto your local network so that the VMs can communicate.
The next two sections are dedicated to setting up a working proof of concept of what I want to discuss. Please note that this is not an exhaustive walkthrough, or the way I would go about it in a real world example. If you decide to do this, you should read further into the security of using a reverse proxy as well as configuring Mod Security.
Setting Up the Client
To test that WAF is working once we have it set up we need to create a vulnerability on the client. The simplest way to test this would be to create a file inclusion vulnerability on the server. Since we installed LAMP server we can use PHP to do this by doing the following:
1. cd /var/www/
2. nano include.php
3. <? $i = $_GET['i'];
include ($i); ?>
This script simply takes the parameter i in the GET request and includes it into the include.php file. Now by requesting the page http://ip-address/include.php?i=/etc/passwd we can see:
So what we are doing here is including the file passwd from the etc folder. This is a common site in a pen testing report that has a local file inclusion included, as it shows a file that should not be accessible from a web facing application.
Now that this is prepared we can now configure the WAF.
Setting up the Web Application Firewall
There are a number of different ways to install Mod Security: source, installers and package managers. The latest version of Mod Security at the time of writing this article is 2.6.0 and can be found here – http://www.modsecurity.org/download/. Again, as above, I am going to cut some corners and install an older version of the firewall from the package manager as I only need to show the cross server protection. Luckily enough, this operating system has a very easy install of Mod Security which I found here – http://blog.ebizdaddy.com. If there are any problems with access being denied or not having enough permissions use sudo.
1. sudo apt-get install libapache2-mod-security
2. a2enmod mod-security
3. nano /etc/apache2/conf.d/mod-security
4. mkdir /etc/apache2/modsecurity-rules
5. cd /etc/apache2/modsecurity-rules
6. wget tar -xvf modsecurity-apache_2.5.12.tar.gz
7. rm -rf CHANGELOG LICENSE READ util
8. sudo service apache2 restart
That’s all there is to it! Again if you had any troubles just try doing the whole process with sudo i.e. sudo su. Now that this has been installed, it is time to connect the two servers and get this WAF protecting that vulnerable page.
The ability for the WAF to cover a different server is possible using what is known as a reverse proxy. A reverse proxy acts as a gateway for servers and enables one web server to provide content for others in a transparent manner. It can be used to cache content from the client and as such improve performance as well (in this case) secure it. It is recommended that if you decide to do this you do research into vulnerabilities caused by using reverse proxying and ways to secure yourself against malicious attacks.
The proxy configuration is done completely on the WAF server – the client server does not need any configuration at all. In this case, we will be changing the /etc/apache2/sites-enabled/000-default file. This file is called by the httpd.conf file (or in this case apache2.conf file) and included at the bottom. To begin with we need enable the proxy module and this can be done simply by adding the following two lines at the top of the file.
1. sudo /etc/apache2/sites-enabled/000-default
LoadModule proxy_module /usr/lib/apache2/modules/mod_proxy.so
LoadModule proxy_http_module /usr/lib/apache2/modules/mod_proxy_http.so
We now need to proxy the request to the web server. Again this is simply done by adding a few lines into the virtual host container.
ProxyPass / http://ip-address/
ProxyPassReverse / http://ip-address/
…and THAT IS IT! You now have a WAF that is covering a completely separate server. Now, when calling the IP of the firewall it takes the request, parses and makes sure that it is a genuine request by checking it against the Mod Security rules. It then sends it onto the application server and the application server sends back the response. Take a look at the vulnerable page now.
Mod Security knows that requesting /etc/passwd is not supposed to happen on a web application so it throws up this error.
This is a very simple example of how we can use Mod Security to cover a separate server to the one that it sits on. It is a great example of what a reverse proxy can do and how you can use Apache only modifications i.e. Mod Security and cover Java based / IIS based servers etc
What is interesting about the setup that we have created is that it is referencing an IP that is on the local network. What would happen if it were to reference something that was out of the network? Well, the same thing happens as I saw by referencing my blog found at http://tmacuk.co.uk.
You can see from the IP address in the URL bar that we are requesting the local WAF, but because of the rules that are present in the 000-default file we see the content on my website. Let us look a bit further into this.
When running Tamper Data alongside the request we first see that we are performing GET request for the IP address 192.168.0.10 (in this case). There is then a short delay which then returns a 200 status code and the response from the application server. Here are the two requests:
17:09:55.386[0ms][total 0ms] Status: pending
GET http://192.168.0.10/ Load Flags[LOAD_DOCUMENT_URI LOAD_INITIAL_DOCUMENT_URI ] Content Size[unknown] Mime Type[unknown]
17:10:03.618[957ms][total 9214ms] Status: 200[OK]
GET http://192.168.0.10/ Load Flags[LOAD_DOCUMENT_URI LOAD_REPLACE LOAD_INITIAL_DOCUMENT_URI ] Content Size[-1] Mime Type[text/html]
The difference here is in the load flags. The additional flag of LOAD_REPLACE seems to be loading http://tmacuk.co.uk and then the LOAD_INITIAL_DOCUMENT_URI then loads the page with the Mod Security firewall in place. I haven’t been able to find information on the load flags so if I am wrong please comment and I will edit the article – what I am saying is right but maybe just not as in-depth as it should be.
Some nice DNS settings would have to be included if this was to be included into a real web server configuration. The domain name would have to be associated with the WAF instead of the web server otherwise the URL will stay as the IP address. This then poses a problem for multiple servers being covered by the WAF. The way to do this would be to create virtual host containers for each different hostname. In each container you the do the ProxyPass rules to forward all traffic to the relevant application server.
Mod Security has many different options that can be called into play when you enable it to run. I am not going to go into them today because that is a whole article in itself and it is highly documented in the FAQs on their website. I am, though, going to show you an example config found here: http://www.thebitsource.com/infrastructure-operations/web-application/securing-apache-web-servers-modsecurity/. It is commented so that you can get a brief idea on how it works but I recommend that you do look at the options available in the Mod Security guides.
# First, let's set up the reverse proxy
ProxyPass / http://192.168.1.2/
ProxyPassReverse / http://192.168.1.2/
# Yes, we want to use mod_security
# Let's use this as the mod_security dir
# Debug log
# Serial audit log
SecRule REQBODY_PROCESSOR_ERROR "!@eq 0"
"phase:2,t:none,log,deny,msg:'Failed to parse request body.',severity:2"
SecRule MULTIPART_STRICT_ERROR "!@eq 0"
"phase:2,t:none,log,deny,msg:'Multipart request body
failed strict validation:
# Did we see anything that might be a boundary?
SecRule MULTIPART_UNMATCHED_BOUNDARY "!@eq 0"
"phase:2,t:none,log,deny,msg:'Multipart parser detected a possible unmatched
The cost of securing your web application and server can be high. Using open source alternatives to the WAF and SLDC can help a lot and this is what discussing here. You can easily create a firewall that will cover many different servers without giving away too much information. That way the reader can’t learn things like the different settings and addons for Mod Security that are, or are not, installed.