Showing posts with label classic. Show all posts
Showing posts with label classic. Show all posts

Tuesday, December 16, 2008

Classic bug: phpBB 2.0.12 authentication bypass

December is always a very busy month at work, so it has been a while since my last post. Here's another classic bug: the phpBB 2.0.12 authentication bypass. I am not sure who discovered this bug, but the first references to it seem to be from February 2005.

As the title says, this is an authentication bypass bug, which means an attacker can access any account on a vulnerable phpBB version without knowing the password. This is not your typical web application bug though, it has to do with serialization and you could patch it by adding only one byte to the vulnerable code.

So how does it work? A phpBB forum has a ‘remember me’ function, which basically gives you a cookie which automatically logs you in. The cookie looks something like this:

a:2:{s:11:"autologinid";s:32:"96948aad3fcae80c08a35c9b5958cd89";s:6:"userid";s:4:"3207";}

This format is created by the PHP serialize function. Basically, it is a technique to store a complex structure into a string. If we unserialize the above example, we get this (print_r output):

Array
(
[autologinid] => 96948aad3fcae80c08a35c9b5958cd89
[userid] => 3207
)

So our cookie is used to store an array containing two strings: our userid and something called an ‘autologinid’. As it turns out, the autologinid is just an MD5 hash of the phpBB password. Not such a good idea, as this makes phpBB vulnerable to passing-the-hash attacks. phpBB 3 doesn’t use this type of cookie anymore though.

The bug is in this part of the phpBB source code (simplified):

$sessiondata = unserialize(stripslashes($HTTP_COOKIE_VARS[$cookiename]));
if( $sessiondata['autologinid'] == $userdata['user_password'] ){
// autologinid matches password
$login = 1;
}

Doesn’t look that bad does it? After unserializing the data, It simply compared the autologinid in our session with the MD5 of the user’s password. They use the == operator to compare two strings, nothing wrong with that. But what if one of the operands in the comparison is not a string? Take for example the following PHP code:

if(true == ‘96948aad3fcae80c08a35c9b5958cd89’){
echo ‘true!’;
}

You may not expect it, but this piece of code outputs ‘true!’. PHP simply converts the string to a boolean and unless the string is empty or ‘0’ PHP will convert it to ‘true’. So what does this have to do with our vulnerability? Let’s take another look at a part of our serialized cookie:

s:32:"96948aad3fcae80c08a35c9b5958cd89"

Our MD5 hash is prefixed with s:32:, which means this variable is a string with a length of 32. So instead of just specifying the string itself, we also specify its type! The trick is to simply change this part of our cookie to:

b:1

Which makes our cookie:

a:2:{s:11:"autologinid";b:1;s:6:"userid";s:4:"3207";

For the unserialize function, this simply means: the value of autologinid is a boolean with the value ‘true’. The next step is to change our cookie on the forum to this one. The forum will compare the password hash of the user with userid 3207 to ‘true’, tricking phpBB into thinking we have the actual password hash! A logical next step would be to change the userid to '1', which is the userid of the forum administrator user, giving us full control over the forum.

The patch for this vulnerability whas a simple one. The phpBB team simply changed the line:
if( $sessiondata['autologinid'] == $userdata['user_password'] ){
to
if( $sessiondata['autologinid'] === $userdata['user_password'] ){

In other words, they switched from the == to the === operator. The PHP manual has the following description for the === operator: “TRUE if $a is equal to $b, and they are of the same type.”. The fix was this simple, by changing the operator, the two compared types have to be equal, so an attacker can no longer supply a boolean instead of a string and bypass authentication.

The moral of this story? Every piece of input is important, don’t allow users to supply serialized data, unless absolutely necessary!

Tuesday, November 25, 2008

Classic bug: Modem AT command injection

This is the first article in a new series: classic bugs. These are bugs that may not always be recent, but surely are interesting, or just still relevant. I think this first bug is both.

I am talking about a bug which could be read about on the Bugtraq mailing list in 1998. The poster, Max Schau started his e-mail with ‘this is an old exploit’, even then. With this bug, you can tell modems (the old analog 56k kind) to hang up. The problem is that with a modem, the data and the modem commands all go through the same communications channel. Sometimes, modems have hard time distinguishing between the two. So, if you can trick someone into sending a modem command, you can influence their modem.

The classic example is the hang up command (ATH0). If I can trick someone into sending that string (preceded by three plus signs) through their modem, a vulnerable modem will hang up. This is easier than it may sound, many systems respond to ICMP echo (ping) packets, and reply to the packet with the same data. So all I have to do is send a modem user an ICMP echo packet containing an AT command and it will reply to the packet, sending the command through the modem.

This denial of service used to be very popular and the beautiful thing is: it still works! At Fox-IT we still have an analog line we use for war dialing. Today, I hooked up a modem and dialed into one of the free dialup ISPs. Using a simple ping command from the original advisory, I was able trick the modem into hanging up! A couple of sources report some modems will hang up when merely visiting a site with an AT command in it, I was not able to reproduce that behavior with my modem.

I spend about half an hour trying to inject other commands (for example to trick the modem into dialing a given number), but was unsuccessful. With other modems this might work better. In the original advisory, someone mentions it may be possible to get modems to dial 911, which would be a big deal. In today’s world, criminals would most likely use it to get modems to dial their premium-rate telephone numbers.

Fortunately, not all analog modems are vulnerable to this attack. Some modems require a pause before sending commands, which makes this attack impossible (or at least very hard). A way of ‘patching’ your modem is in the original advisory, this involves changing the default escape character (+) in your modem using an ATS2 command. It seems the escape character can only be a single byte, so it would be easy to brute force if you know someone has changed it.