Wednesday, October 31, 2012

Salt your passwords = Existing accounts password reset

This one is just a simple conclusion that I drew when a customer had MD5 hashed passwords in his database and we recommended them to salt them instead and use PBKDF as the algorithm of choice.

Now the customer added code in, but left the old code in as well which did the simple hash comparisons. So I asked them why and they said..for old users. I started thinking about it and it made sense. Here's why:

Think of it. I have a MD5 password in the database. Say I add a new column for 'salt' , generate 1000 random for each user..and add a new column. I then change the code to query the DB for the 'salt' as well, when a person logs in and run the user's password through the PBKDF function before comparing it with the hash. Looks good?

Sure. Except that no one will be able to login. Why? It's super secure now :). No one can find any more vulnerabilities inside. Jokes apart, what's happening here? Lets say the user's original password was abc123 and it had a 32 bit MD5 hash XYZ. Now when the user logs in something like MD5(user entered password) runs..hashes what he entered and compares it to the stored hash. Match? Login successful.

Now there's the salt. So when the user logs in, the new 'salt+pbkdf' code is triggered. So PBKDF(userpwd + salt) is calculated and compared to ..what? The stored MD5 hash. Is there ever going to be a match? Largely no. Because..there is no way you can predict the salt for a particular hash..BEFORE you store it in the DB. Remember those 1000 salts you generated? All random? Did you check if they'd give you the user's password after "decryption"? Nope.

So since there's no way to get the "right salt" for each user ID, the easiest solution is to force a password reset across users. The next time they login everything will automatically fall into place.

Thursday, October 25, 2012

Incremental code review - MD5 hashes

This one is a reasonably obvious tip to be frank. I was recently doing a code review retest for a Java app. Now I don't know too much Java so I was finding it hard stepping through code.

One thing I knew though was that if you have the previous code base and the current one and are "re-testing" it's helpful to see which files have changed. Now anyone with a little Linux experience or programming experience will immediately say 'diff'. And yeah..diff is fine..but that will give you a very detailed listing in a slightly cryptic form. Its readable enough if you go slow, but it's not the first step IMO. I'd like a slightly more high level view first. That's how I stumpled upon md5deep.

So I go into the first root directory of the old code and run md5deep -rl > old_list there. Then I change directories to the new code and run md5deep -rl -X old_list > changes over here. Basically all it means is that I compared the new list against the old. Once I have my changes, I know that any fixes they made MUST be in some of those files.

Now I can run diff on each of those file combinations to search a little bit slowly. It's the same really..but it gives me a little more control over the process.

A tip here to further reduce changes is to use md5deep with grep to filter your results out. So I knew I was looking only for java file I could either do something like:

md5deep -rl -X old_list| egrep -i '.java$'


md5deep -rl * -X ~/list_md5_old |egrep -v ".doc$|.DS_Store|.js|xml|changed_files|hibernate" > changed_files;wc -l changed_files

I used the 2nd one :) coz I knew what all I didn't want. If you don't know that..start with what you know and filter on from there.

There's a million ways of doing this of course; I just dropped in what I did :). Here's the blog post which saved me some time..