IP.Board password hashing is no longer secure

54 posts in this topic

Thanks to an unfortunate series of events, we recently had our entire user database stolen. In the two weeks since, we have had numerous lists published containing that information as well as thousands of their cracked, plaintext passwords.

I don't know how they are cracking the hashes, but it doesn't much matter. It seems clear that IP.Board's password hashing system is no longer entirely adequate for widespread and conscientious use.

I implore IPS to investigate moving to a new password hashing scheme. Perhaps that means making use of newer and stronger technologies than MD5. Perhaps that simply means changing to a more lengthy and complex hashing process. Whatever the case, something needs to change.

When everything else has gone wrong, password hashes should be the one thing that doesn't.

Share this post

Link to post

Share on other sites

In the meantime, you should inform your members that their accounts have been compromised so that they can take active steps to change their passwords on other sites since it's likely some of them are using the same passwords on multiple sites. Are the accounts related to your old forum? http://forum.sublimism.com

Share this post

Link to post

Share on other sites

Hashing doesn't be come 'less secure' computers just become faster.
With todays GPUs people are able to bruteforce millions (Good once can near a billion) of passwords per second.

There is nothing IPS can do to protect against someone brute forcing your passwords while they have the database. IPS already implements salts in attempt to make sure your hashes won't show up in a precompiled list however, your salts are no more secret then the hashes. They only way to make sure your passwords remain safe even after a compromise is to have the original passwords be secure passwords that won't show up in a basic dictionary attack.

That said. I would highly suggest checking your han_login file for a back door. If any of the passwords they are dumping have any sort of complexity at all this is likely how they are getting the plain text passwords. If all the passwords are 'abc123' then it is brute force.

Here is a table of a popular cuda base cracker containing cracking speeds. With speeds like this there is no way IPS can secure your password after you have been compromised other then keep all your passwords for you.

Share this post

Link to post

Share on other sites

Thanks to an unfortunate series of events, we recently had our entire user database stolen. In the two weeks since, we have had numerous lists published containing that information as well as thousands of their cracked, plaintext passwords.

I don't know how they are cracking the hashes, but it doesn't much matter. It seems clear that IP.Board's password hashing system is no longer entirely adequate for widespread and conscientious use.

I implore IPS to investigate moving to a new password hashing scheme. Perhaps that means making use of newer and stronger technologies than MD5. Perhaps that simply means changing to a more lengthy and complex hashing process. Whatever the case, something needs to change.

When everything else has gone wrong, password hashes should be the one thing that doesn't.

The hashing system is still fine, the main problem are weak passwords, and as others have said, more processing power.

The problem is (and we know this all too well ourselves), when the DB is leaked, the salts come with it, and once you have the salt, IPB's hashing method adds a couple more MD5 calculations to the process which does slow things down a little, but ultimately it's down to how secure the user's password is.

I believe the hashing method for IPB is:

md5(md5($salt) . md5($password))

So there's 3 MD5s to calculate but you can presume if they're trying to get a specific user's password, they will precalculate the hash of the salt and then all they have to do is plug that in to one of the multiple MD5 crackers out there and wait for it to get brute forced.

One thing that might help is to store a salt somewhere in a config file and use that salt *as well as* a salt stored in the database. More experienced users could modify the value in their config to something custom (and huge) and it would make cracking the passwords pretty much impossible without also getting hold of the config file with the other salt in when they stole your database (which means compromising the server as well as just stealing the DB).

The other problem apart from brute forcing is of course dictionary attacks... and then back to brute forcing... just look how cheaply you can rent an Amazon EC2 Instance with a bunch of nVidia GPUs in it, one single graphics card in one of those things can crack at least 1B hashes/sec each (probably more, now I feel like testing it).

Share this post

Link to post

Share on other sites

It might help to limit the number of login try over a specified time range. 1 minute => 15 Logins , 15 minutes => 100 Logins (from the same computer)

You only have 15 logins in 1 minute but if they do 15 logins in a minute they are still over the limit of 100 logins after ~7 minutes an will be looked. You could go on with this limiting things.

Now I would like to here something of the developers in this community would my idea help to increase security a little bit?

Attempted logins are already limited, this is an entirely different issue.

Currently when a member registers or changes their password, IPB generates what's called a "salt". In IPB's case I believe this is a random string of 5 characters (if I remember correctly), such as jH~8l.

Now, the reason it makes a salt is to try and make passwords more secure. The reason for this is that if your password is dog then without a salt, it would be hashed into MD5 and stored in the database as 06d80eb0c50b49a509b49f2424e8c805. If someone steals the database they get this hash, and then they start trying every password until they generate that hash, at which point they know the password which corresponds to your account. (It would take way less than a second to crack that password, by the way.)

With salting, the password and salt are put together to try and make this process more difficult.

With IPB's current method, as I said, a salt such as jH~8l is generated, and hashed into MD5 which produces bf9cd0333f55d404453c41811716019d, but what IPB then does is concatenate the hashed salt and hashed password (bf9cd0333f55d404453c41811716019d and 06d80eb0c50b49a509b49f2424e8c805 respectively), and then hashes that, which results in 924fdfd327f3153accc18b383dd0192a, a completely different hash which is a lot more difficult to brute force directly.

The problem with this method of hashing is that it offers very little protection if the database is compromised, because the salt is stored with the password hash in the database, so once an attacker has that database, they have pretty much all the information they need to make it so that they're cracking "dog" again rather than the much more complex salted password.

With my idea about an additional salt in a config file, this salt would be the same for everyone (unlike the salt stored in the database which is different for each user), except that it could be used alongside the database salt, and that way, if the database was stolen, the attacker still wouldn't have the additional salt unless they also managed to get further into the server to steal the config file.

Share this post

Link to post

Share on other sites

Thanks to an unfortunate series of events, we recently had our entire user database stolen. In the two weeks since, we have had numerous lists published containing that information as well as thousands of their cracked, plaintext passwords.

I don't know how they are cracking the hashes, but it doesn't much matter. It seems clear that IP.Board's password hashing system is no longer entirely adequate for widespread and conscientious use.

I implore IPS to investigate moving to a new password hashing scheme. Perhaps that means making use of newer and stronger technologies than MD5. Perhaps that simply means changing to a more lengthy and complex hashing process. Whatever the case, something needs to change.

When everything else has gone wrong, password hashes should be the one thing that doesn't.

Open up a ticket and speak to them and let them know what up.

Share this post

Link to post

Share on other sites

What I think the ideal solution would to be having a function that "translates" the salt into something else before the hash is created. By default just do a rot13 or something but allow admins to define their own unique function so the hash will be of a string that isn't stored in the database but it will still be easily generated.

Share this post

Link to post

Share on other sites

This isn't really necessary. There is no security exploit here, just discussion of possible ways to improve password hashing. We are aware of the limitations described above.

What I think the ideal solution would to be having a function that "translates" the salt into something else before the hash is created. By default just do a rot13 or something but allow admins to define their own unique function so the hash will be of a string that isn't stored in the database but it will still be easily generated.

Would most admins *actually* do this though? Probably not. So you're left in the same position for 99.9% of installs.

Share this post

Link to post

Share on other sites

What I think the ideal solution would to be having a function that "translates" the salt into something else before the hash is created. By default just do a rot13 or something but allow admins to define their own unique function so the hash will be of a string that isn't stored in the database but it will still be easily generated.

That could also work as a solution as well. But whatever the method is, it should be defined *in a config file somewhere*, NOT in the database.

Share this post

Link to post

Share on other sites

Would most admins *actually* do this though? Probably not. So you're left in the same position for 99.9% of installs.

I agree, most admins probably wouldn't, and it could just be issued with a default hash that does it (or my solution with a default additional salt). I personally prefer my solution as there's only a limited number of hashing functions but an admin-set salt could be anything. You can always recommend that users change it to a random string during installation, and I agree with you, most won't, but they will only then be left in the same situation we are now anyway, whereas the more experienced among us can gain some additional security.

Share this post

Link to post

Share on other sites

This isn't really necessary. There is no security exploit here, just discussion of possible ways to improve password hashing. We are aware of the limitations described above.

Would most admins *actually* do this though? Probably not. So you're left in the same position for 99.9% of installs.

Well then can't you generate a unique function each time a board is installed. Maybe a random string to map the characters in the alphabet to? This would definitely make ipb the most secure forum software password hashing wise.

Share this post

Link to post

Share on other sites

In the meantime, you should inform your members that their accounts have been compromised so that they can take active steps to change their passwords on other sites since it's likely some of them are using the same passwords on multiple sites. Are the accounts related to your old forum?

No, it was a different [and unfortunately far larger] site. We did make a public announcement and warning shortly after we determined what had happened, though. Thanks.

Hashing doesn't be come 'less secure' computers just become faster.

With todays GPUs people are able to bruteforce millions (Good once can near a billion) of passwords per second.

There is nothing IPS can do to protect against someone brute forcing your passwords while they have the database. IPS already implements salts in attempt to make sure your hashes won't show up in a precompiled list however, your salts are no more secret then the hashes. They only way to make sure your passwords remain safe even after a compromise is to have the original passwords be secure passwords that won't show up in a basic dictionary attack.

That said. I would highly suggest checking your han_login file for a back door. If any of the passwords they are dumping have any sort of complexity at all this is likely how they are getting the plain text passwords. If all the passwords are 'abc123' then it is brute force.

It hadn't occurred to me that GPUs might be used in that way... that's very unfortunate. I've actually been working with CUDA myself in the past week, though toward a very different end. [Fun fact: A 96-SPU 8800 GTS can generate ~500 million random numbers per second.]

After the attack, I did a sweep of our templates and language and everything else. Just double checked login handlers [thanks], but surprisingly I don't think they left any backdoors behind. Just a couple hundred retired staff members giving possible social engineering attack vectors. I do wish everything were logged more fully.

Clearly bruteforcing is a larger problem than it used to be, even more than I'd imagined--but surely there must be some viable scheme such that all the requisite information can't be pulled straight from the database and plugged into a stock cracking program. If nothing else, use a larger hashing method and key size so there are 2^n+256 or whatever additional inputs to check.

In response to whoever asked, yes, the passwords that have been found so far are fairly simple, something I've always been harping on people to avoid. Rather more complex than I was expecting, though--alphanumerics as long as 12 characters, and including special characters, 6 or less. [Why are passwords of 6 or less even allowed?] That was as of a week ago, so probably worse by this point.

Peter: Storing something in config wouldn't be bulletproof either. All it takes is knowing that it's there, and some code to print $this->settings in the templates or a system setting would reveal it.

Share this post

Link to post

Share on other sites

Peter: Storing something in config wouldn't be bulletproof either. All it takes is knowing that it's there, and some code to print $this->settings in the templates or a system setting would reveal it.

While that's true, it's certainly a start. Ideally it would need to be something that isn't findable by one of those methods (like a variable within the login handler class) or something, which does mean file edits but also adds security.

Share this post

Link to post

Share on other sites

I didn't really think about the fact you can use PHP in skin bits before but now that it's been brought up, I suppose there isn't really a foolproof way to implement this since anyone already in the Admin CP can just add some PHP to a skin bit to fopen() and print the file.

Share this post

Link to post

Share on other sites

I was thinking the same thing as the only ultimate solution. Use Zend Guard or ionCube to encode the PHP file with the details in (except the author of the mod would have to do that before sending it out for each different user).

Share this post

Link to post

Share on other sites

Websites that require a minimum eight characters, a capital letter, a lower case letter, and a special character are evil.

No, I totally agree--arbitrary requirements are horrible. ...But they're also more secure.

As far as I can tell, the primary method for mitigating bruteforce attacks is simply to use a cipher that is ... slow. Some mechanism for separating part of the vital data from the database would be an improvement, but as noted earlier, it doesn't seem like there's any method that would actually be infallible. [Any standard location means it's just another thing to pull out, unless you can prevent access to it by any of the means of using PHP in the ACP.]