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:

  1. Secure Development Life Cycle (SDLC)
  2. Web Application Testing
  3. 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

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.

Preparation

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

<IfModule security2_module>
Include modsecurity-rules/*.conf
Include modsecurity-rules/base_rules/*.conf
</IfModule>

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.

Reverse Proxy

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.

ProxyRequests off
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

The Cloud

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.

Want to learn more?? The InfoSec Institute Web Application Penetration Testing Boot Camp focuses on preparing you for the real world of Web App Pen Testing through extensive lab exercises, thought provoking lectures led by an expert instructor. We review of the entire body of knowledge as it pertains to web application pen testing through a high-energy seminar approach.

The Web Application Penetration Testing course from InfoSec Institute is a totally hands-on learning experience. From the first day to the last day, you will learn the ins and outs of Web App Pen Testing by attending thought provoking lectures led by an expert instructor. Every lecture is directly followed up by a comprehensive lab exercise (we also set up and provide lab workstations so you don't waste valuable class time installing tools and apps). Benefits to you are:

  • Get CWAPT Certified
  • Learn the Secrets of Web App Pen Testing in a totally hands-on classroom environment
  • Learn how to exploit and defend real-world web apps: not just silly sample code
  • Complete the 83 Step "Web App Pen Test Methodology", and bring a copy back to work with you
  • Learn how perform OWASP Top 10 Assessments: for PCI DSS compliance

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

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.

Additions

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.

<VirtualHost www.modsecurity.org>
# First, let's set up the reverse proxy
ProxyRequests Off
ProxyPass / http://192.168.1.2/
ProxyPassReverse / http://192.168.1.2/
<IfModule mod_security.c>
# Yes, we want to use mod_security
SecRuleEngine On
SecRequestBodyAccess On
SecResponseBodyAccess Off

# Let's use this as the mod_security dir
SecUploadDir /tmp/
SecUploadKeepFiles Off

# Debug log
SecDebugLog /var/log/modsec_debug.log
SecDebugLogLevel 0

# Serial audit log
SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus ^5
SecAuditLogParts ABIFHZ
SecAuditLogType Serial
SecAuditLog /var/log/modsec_audit.log

SecRequestBodyLimit 131072

SecRequestBodyInMemoryLimit 131072

SecResponseBodyLimit 524288

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:
PE %{REQBODY_PROCESSOR_ERROR},
BQ %{MULTIPART_BOUNDARY_QUOTED},
BW %{MULTIPART_BOUNDARY_WHITESPACE},
DB %{MULTIPART_DATA_BEFORE},
DA %{MULTIPART_DATA_AFTER},
HF %{MULTIPART_HEADER_FOLDING},
LF %{MULTIPART_LF_LINE},
SM %{MULTIPART_SEMICOLON_MISSING},
IQ %{MULTIPART_INVALID_QUOTING}'"

# 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
boundary.'"
</IfModule>
</VirtualHost>

Conclusion

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.