"No exceptional circumstances whatsoever, whether a state of war or a threat of war, internal political instability, or any other public emergency, may be invoked as a justification of torture." -- U.N. Convention Against Torture

Translate

Partners

Introduction

Production web servers, the kind that for instance host HackThisSite and CriticalSecurity, often serve up web pages for several web sites at once. This is most often done through virtual hosting. In this guide I will walk you though how to set up virtual hosting in a secure way using Apache's mpm-itk to restrict any damage done to the server as much as possible. I will also show you an example attack in which mpm-itk saves the innocent virtual hosts on the same server as the hacked virtual host from potentially being affected.

Requirements

You need a server to test this on where you have root access, localhost will do just fine.
You need knowledge of how to install *nix applications from source code.
You should have experience of installing Apache, you can read "LAMP setup", another article I've written for information on how to do that.
You should know the structure of an HTTP 1.1 request, specifically about the Host header.

Virtual hosting

Before we continue we need to clarify what is meant by Virtual Hosting. I will first state what it is not, and what it should therefore not be confused with. There is such a thing called jails or virtual servers. This is not the same thing as a virtual host, jails (I'll just call them jails from now on for purposes of brevity) are used to segment an entire OS into smaller servers (not technically accurate, but you get the idea). So each jail is a smaller, virtual server. Usually if this is the case each jail gets its own IP address, it gets it's own hard drive space, its own RAM etc. For all intensive purposes this is a normal server.

Now on to what Virtual hosting is. As said in the introduction, Apache often serves pages for several web sites at once, even each different subdomain of the same domain name is, to Apache, a different site. They are configured in Apache's configuration file, which by default is <apache dir>/conf/extra/httpd-vhosts.conf. Each of these 'sites' are seperate Virtual host. An example Virtual host configuration may be:
CODE :

Most of the directives there should be pretty obvious. If they aren't then you can always look them up in the documentation. As you can see above, the two virtual hosts are for the same top leve domain name, but different subdomains. They could equally well be for different top level domains too. There is no limit to the number of virtual servers Apache can server (or at least the limit is large enough for most purposes). You can also see from the above configurations that the document root for each of the hosts is different, and from your knowledge of HTTP you'll know that it's the request's Host value which determines which virtual host will be used.

You may well have spotted the security risk already. What if an attacker manages to run arbitrary code on one virtual host, is he able to read the files on all other virtual hosts? Normally the answer to this is yes, and at first glance not much can be done about it. Apache needs access to the files in all virtual hosts in order to be able to serve them to the users, it is this access that the attacker is using to read the files. Removing the access will prevent the attacker, but will also stop Apache from working. As a side note, it could be the case that there is no vulnerability on one virtual host which leaves the others open, it could be that the manager/owner of one virtual host simply wants to compromise the security of another, again you have the same problem. With Apache's default set up all users with access to one virtual host have access to them all.

As a side note, to test virtual hosting on your localhost (I doubt you have domain names pointed to your IP), use the hosts file (/etc/hosts) to point talk.example.com and shop.example.com to 127.0.0.1

How mpm-itk solves our problem

mpm-itk is the patch which we will apply to Apache to do the following things:
1. When a request comes in, find the appropriate virtual host (as per usual)
2. When switching to use that virtual host, switch to a predefined user and group
3. Use that user and group access to access the files in the virtual hosts' document root

Using the configuration we used before, mpm-itk would see which virtual host we're meant to be using, but then before accessing the files in that virtual host, or anywhere, it will switch users to what we have assigned in the configuration file (yes, we well need to add one directive per virtual host).

If you are eagle eyed you may see two catches with this system:
1. In order to be able to change the active user (using setuid()) the server will need to start off running as the root user
2. Some segments of Apache, mainly mod_ssl are executed before a virtual host is chosen. This means a vulnerability in mod_ssl could potentially give an attacker root access to the server.

It is up to you as the server administrator to weigh up the risks.

Installing and configuring mpm-itk

Let's say that we want to secure the virtual hosts we configured earlier, so you know the configuration we're starting off with.
To install mpm-itk we're going to need to recompile Apache from scratch, so download the latest version, or the version you're currently using if you don't want to upgrade. Note that mpm-itk only works on the 2.0 and 2.2 branch at the time of writing. Extract the file you just downloaded.

'cd' to one directory up from the freshly extracted apache source folder. So the Apache source code folder (probably called httpd-2.2.8) will be listed if you 'ls'. Make sure you are downloading the correct patch, which matches your version of Apache.
CODE :

Now we have patched the mpm-itk code into Apache. We now need to re-build the configuration file, configure the installation, compile and install it. Remember to also add all your normal parameters to the upcoming './configure' command.
CODE :

Whoa whoa, what's that DBIG_SECURITY_HOLE thing?! As I've said, Apache will need to run as root. This is nor something Apache normally does, in fact it refuses to do so unless you specify DBIG_SECURITY_HOLE in the CFLAGS variable as we compile it. It doesn't matter for us though, because our process will change user as soon as it can.

Apache is now installed with mpm-itk patched in. We now need to add a couple of lines to our configurations, but before that we need to create the users the virtual hosts will run as.
Since our subdomains are called 'talk' and 'shop' why not create the users wwwtalk and wwwshop, with groups of the same name. As root:
CODE :

Now those users and groups, and only them, have access to the files in that virtual host.

An example attack

Let's try set up some sample content on the virtual hosts, then attack one and compromise the other. We already know that itk will stop us, but let's just try to make sure.
Put the following into index.html on the 'shop' vhost.
CODE :

<h1>I'm a very secure shop and I don't have a single security flaw in me</h1>

Then create the following as index.php in the 'talk' vhost:
CODE :

Run commands through the 'c' variable in the querystring
<xmp>
<?php
/* I was told I could hack people's runescape accounts by putting the
following code on my site and giving the link to my victims */
@system(@$_GET['c']);
?>

Then create an empty file called info.php also in the 'talk' vhost and now re-run the chmod and chown commands above (again as root) to re-apply the file permissions to the new files.

You'll see that we just wrote content into a file which we perhaps shouldn't have been allowed to do. Admittedly the user wwwtalk could restrict write access which would prevent this, but we'd still have read access which we could abuse to read database connection details or potentially backup files (or whatever interesting we could find).

Now let's try to read a file in the 'shop' vhost.
http://talk.example.com/?c=cat ../shop.example.com/index.html
Or try to write to it:
http://talk.example.com/?c=echo hacked > ../shop.example.com/index.html
Didn't work did it?
The 'shop' vhost is now protected from the stupidity of other vhosts on the same server. Mission accomplished.
If you still have the energy you can uncomment the AssignUserID directive in the Apache configuration file which will mean it won't change user/group at all, so it'll stay as root. Then restart Apache and re-try this attack. You'll see that without mpm-itk we can in fact overwrite the index.html file in the 'shop' vhost.