I was talking with my wife a few days ago, and the subject of password security came up. Now, we all know that we're supposed to pick a secure password, use at least 8 characters and never to pick a word from the dictionary. But then she asked how long it would take to brute-force a password using a dictionary attack, and I had to admit I had no idea. I knew it would only be a matter of minutes, but wanted to give it a try.
So, For anyone who is interested, I knocked up a quick BASH script to compare a MD5 hashed password against the contents of /usr/share/dict/words, which on a Red Hat 5.3 system contains 479,623 words. The script is as follows :
#!/bin/bash
TARGET_HASH=$1
while read WORD; do
WORD_HASH=$(echo $WORD | md5sum | awk '{print $1}')
if [ "$WORD_HASH" == "$TARGET_HASH" ]; then
echo "Found match!"
echo "Password is : $WORD"
exit
fi
done < /usr/share/dict/words
Now, this was just a quick hack to satisfy my curiosity, and only something I threw together after a few seconds. Of particular relevance is the fact that it's a shell script, and uses a lot of forking to generate the MD5 hashes of the dictionary. If I wrote it in C, I'm sure it would be faster by an order of magnitude.
But anyway, on to the test - I created a MD5 phrase for it to crack, and timed it :
# time ./crack.sh 3a783fb2aa3a2318499f0a60d7ef6078
Found match!
Password is : hedgehog
real 8m43.432s
user 1m48.410s
sys 8m27.030s
Not bad - just under 9 minutes. Obviously, that'd take longer if I used a word starting with "x" or "z"! I then realised it would be a lot faster if I generated a "compiled" version of the dictionary file with the MD5 hashes preprepared :
while read WORD; do echo "$WORD:$(echo $WORD | md5sum | awk '{print $1}')"; done < /usr/share/dict/words > md5.txt
Obviously, I could then generate compiled dictionary files for each hashing algorithm I wanted to crack (assuming that they are non-Salted algorithms). This took around 30 minutes, but now I don't have to generate the hashes again, all I need to do is check against the second column of the file for a match. It is also irrelevant whether the word lies near the start or end of the file, it now takes about the same time to find a match :
# time grep ac23b37db0039dda62896bb21f312755 md5.txt | cut -d':' -f1
aardvark
real 0m0.019s
user 0m0.008s
sys 0m0.011s
# time grep 981fe627ab4906b677ce9d3e6eff499f md5.txt | cut -d':' -f1
zoology
real 0m0.019s
user 0m0.006s
sys 0m0.014s
So there you have it. It was an interesting way to spend a few minutes, and I now have an answer whenever someone asks "how long would it take to crack a password based on a dictionary word": Assuming you have the compiled hash files, around 0.019 seconds.
Friday, April 17. 2009 at 16:30 (Link) (Reply)
But this is why salted hashes are a lot better for storing passwords. The number of variations this generates for each password is enough to make rainbow tables useless, or for the attacker to have to recompute them if the salt is available.
Friday, April 17. 2009 at 22:18 (Reply)
I've always wondered, given the right software and a few spare computers, how much effort it would really take to brute-force a few hashes. I know Milw0rm and a few other sites have a cracking service, but it's something I'd like to play with myself some time. Perhaps a project for another rainy day
Thursday, May 21. 2009 at 00:14 (Link) (Reply)
An index lookup in a database is generally 0 time / cpu as far as the database is concerned.