MyBB account hijacking

Embed Size (px)

Citation preview

Hijacking MyBB accounts

Not so random random?

Before we start:

The source codes are from MyBB 1.6.9

MyBB 1.6.10 is most likely vulnerable to these weaknesses too.

The presentation is for educational purpose. I'm strongly against any illegal activity. Every weakness that I find is reported to MyBB developers.


How to access an account without a password?

Session hijack?

Steal a cookie?

Password re-set?

Session hijacking Where is the session?

Global.php =>

inc/class_session.php :

Session can't be stolen remotely, because we have a different IP :(


Once again.
How to access an account without a password?

Session hijack

Steal a cookie?

Password re-set?

Stealing a cookie >:)

inc/class_session.php :

So how does a cookie like this look like?From the load_user function we know, that it is saved as 'loginkey' in the DB:

Stealing a cookie >:)

Because of its name and nature, it might be set while login.

The login process can be found in member.php file.

member.php :

So we know the first part: User ID. How about the $user['loginkey' ] ?

member.php includes an interesting file called functions_user.php

member.php :

Stealing a cookie >:)

The loginkey is always part of $user variable (or similar). The newly discovered file could then have some more information about the loginkey.

inc/functions_user.php :

So the cookie looks like this: [user_id]_[string]

Stealing a cookie >:)

To find out more about our mysterious string, let's have a look at the 'random_str()' function. Because this looks like a regular function, it might be in the 'inc/functions.php' file.

inc/functions.php :

The array has these characters: a-z, A-Z, 1-9

Stealing a cookie >:)

As you can see, the argument at 'random_str()' is number of characters in the returned string. In our case 50. So an example string could be: 1_98n6GS6F7xIyf74cI44FXIJHCfyyeEFjGyFKW678265btWzy2k imagine brute-forcing that.

Stealing a cookie >:)

The characters for the random string are chosen by 'my_rand()' function ==>

Stealing a cookie >:)

Stealing a cookie >:)

As you can see, the final return is counted this way:

$min + (($distance + 1) * (mt_rand() ^ $obfuscator) / (mt_getrandmax() + 1))

Known variables:

$min = 0

$distance = 60

mt_getrandmax() = 2147483647 (seriously, test it for yourself. 32-bit and 64-bit systems give out the same number)

Updated formula:

0 + ((60 + 1) * (mt_rand() ^ $obfuscator) / ( 2147483647 + 1))And it gets better!

Stealing a cookie >:)

'my_rand()' function uses 'secure_seed_rng()' to seed the 'mt_rand()' function that is being used for output. ==>

Stealing a cookie >:)

Stealing a cookie >:)

If PHP can read the dev/urandom file, we might have a problem

But if the forum runs on Windows server or uses cPanel (and possibly other control panels), it might not be allowed to read this file and the seed will be counted from 'microtime()' function and process ID.

'microtime()':

format => msec sec

example => 0.89574000 1366899417

Stealing a cookie >:)

Back to 'my_rand()' function. We figured out how the seed is computed, but re-counting it for each character could take time.

inc/functions.php :

Because of the static variables, the seed is counted only once => We need to brute-force the seed just once and then just re-use it.

Stealing a cookie >:)

However, 50 characters is still enough and we don't know the exact time.

So how to make this even easier?

Password re-set

When recovering a password, user has to enter a verification code that is sent to his e-mail.

This code is generated by 'random_str()' function.

member.php :inc/functions.php :

The activation link looks like:

www.example.ext/member.php?action=resetpassword&uid=[userID]&code=[activation code]We know the exact time of the generation, so all we have to brute-force is the microseconds.

Password re-set

After using correct activation code, the random password is generated:

member.php :

MyBB registration page:

Password length will always be equal or bigger than 8

Because we know the time when it was generated, it is easy to brute-force

How to fix this?

Use new seed for every character in string.

Use 'openssl_random_pseudo_bytes()' instead of 'mt_rand()'

Make the seed a bit longer or random lengths

The end

Thank you for coming!

Visit: www.1llusion.info and www.HackCommunity.com for more security related material.

And visit www.MyBB.com for MyBB software.

Have a great day!