I would like to perform a dictionary attack, or, if it is easier an attack directly in the database with my hashed passwords in order to find out what users of my site are using simple passwords.

I will be implementing some complexity rules when creating passwords but I would love to be able to contact the users who have simple dictionary words and ask them to change their passwords.

The database is MySQL with MD5 hashed passwords. The rest of the site is written in PHP.

My assumption is I need a dictionary file and them an automated way to test each word against each user, but I have over 1000 users to look through and I am sure there are well over 10,000 potential words to test so I have no idea of the best way to automate that type of thing.

Any help or guiders would be extremely appreciated.

+9  A: 

The database is MySQL with MD5 encrypted passwords.

... with MD5 hashed passwords. Hashing != Encryption

The most straightforward way to carry out the attack is to get your dictionary words in a list, say $dict and

foreach ($dict as $word) {
   $hash = md5($word);
   $db->query("SELECT username FROM users WHERE password='$hash'"); 
   // and see if any rows are returned

That being said, you should :

Sorry, of course you are right, that was a mental slip on my part!
SHA1 is also broken but no preimage attacks are yet known (the same goes for MD5). However - more importantly - both MD5 and SHA are designed to be fast algorithms. Fast is exactly what you do not want for hashing passwords. Take a look at BCrypt-hash (standard in PHP 5.3) it is designed to be as slow as needed.
"SHA-1 is broken" means that you need 2**69 operations to generate a collision and not 2**80. This is a great result for researchers but not big deal if you want to store passwords. It doesn't affect password hashing with salt, because the attacker needs the secret salt to compute a collision.
Luther Blissett

Force all users to change their passwords with the new policy. This way is a lot easier.

Easier for me, not for them though. I would get really cheesed off if I got an email asking me to change my perfectly valid/complex password on the whim of the administrator.
If they change their old weak password to a new weak password then what is gained?
@emory: New complexity rules are being put into place to prevent that. The purpose of the dictionary attack is to ensure no weak passwords are grandfathered into the new system.
Edward Mazur
+3  A: 
  1. Get a dictionary
  2. Encode the dictionary words into MD5. Take into account the uppercase and lowercase variations.
  3. Select useremail from the database where password in the set of encoded words.
  4. Send emails to those emails.
+1  A: 

There's shareware and freeware out on the Internet that claims to perform brute force or dictionary attacks on websites.

I hesitate to recommend any, or even suggest that these programs do what they say they do.

If you're going to download one, test it out on an isolated computer.

Gilbert Le Blanc
Yeah I have seen them, none of them look very reputable. I would recommend any suggestions from people who have used some though and had positive experiences. My fear would be software phoning home.
Yeah, years ago I was doing some tinkering with robustness of passwords, and I came across a password-cracking program on a site that advertised itself as a hacker site. And I thought, What idiot would download software from a site that openly boasts that they are trying to hack into as many systems as possible, and then run it on his own computer?
+2  A: 

10,000 words and 1,000 users doesn't sound too bad. Start with something like this:


$words = ... // load dictionary file into array
foreach ($words as $word) {
    $result = mysql_query('
        SELECT name
        FROM users
        WHERE password = MD5(' . $word . ');
    while ($row = mysql_fetch_assoc($result)) {
        print($row['name'] . "\n");
        // send an email, save to a file, etc.

Build an index on password beforehand and you should be good to go.

Edward Mazur
+2  A: 

If the MD5 are unsalted, then you will likely be able to read the weak or only moderately strong user passwords in plaintext by entering the hashes into a online rainbow table, for example:

A dictionary attacks is not needed then.

If you are using unsalted MD5 passwords in your application, then you should be beaten up with a rusty iron rod of course.

Luther Blissett
I know, I know! The salting is coming as part of the updates I am doing but for now they are unsalted. Your idea sounds perfect, I never thought about just giving another service the hashes and working backwards, thanks!
In terms of performance, I'd think that having to send messages across the wire to a web site and get replies back would take longer than hashing each word in a dictionary on a local box.
John the ripper will break a salted password hash, as long as you have the salt. If the password is a dictionary word it will take less than an hour, it doesn't matter what message digest you use. Although md5() is total crap.

Check their passwords when they log in next time. If any password is weak, redirect the user to the change password page, and force him/her/it to change it.