A simple solution to Crack crypt password files with mpi4py

Computer Science Department - University of Puerto Rico

Prepared by: José R. Ortiz-Ubarri

What is a password file?

A password file contains the password of the users of a system.

Examples are the OS shadow file, database password file, apache password file

What is crypt?

man crypt

The crypt() function performs password encryption, based on the NBS Data Encryption Standard (DES).

Why crack password files?

For Good:

For Bad:

Password Cracking

John the Ripper password cracker

John the Ripper is a fast password cracker, currently available for many flavors of Unix, Windows, DOS, BeOS, and OpenVMS. Its primary purpose is to detect weak Unix passwords. Besides several crypt(3) password hash types most commonly found on various Unix systems, supported out of the box are Windows LM hashes, plus lots of other hashes and ciphers in the community-enhanced version.

http://www.openwall.com/john/

Cracking dictionary passwords

The eassiest passwords to crack are dictionary passwords.

Is it easy to find a dictionary of words?

Yes it is.

Check your
/usr/share/dict/words

file in your Unix or garden of Unix machines.

Otherwise google for it.

The one we will use has 479,623 words.

How dictionary passwords are cracked in crypt shadow files?

Simply test the crypted password of each user against a crypted version of each word in the dictionary.

In python use the crypt function.


import crypt

crypt.crypt(cleartextpasswd, salt or cryptedpasswd)

will return the clear text password crypted.

Example of a shadow file

root:$1$TKuJpECV$h2VaRm0dzYHe4W3TuErqj/:14882:0:99999:7:::
jortiz:$1$gzN9bqPH$NYUvr/GzmQOQYDTXWtpUG/:14915:0:99999:7:::
mysql:!!:15724::::::
bill:$1$EUDeA5rZ$eUZf1JdTwYkbKW6XIhgag1:15876:0:99999:7:::
juan:$1$pNZcxGAV$UXzkOMRDdNEA5TfLIjGce0:15876:0:99999:7:::
ramon:$1$C93hlZvi$Ekc.7ADTlFm3xqeRmUAvF/:15876:0:99999:7:::
felipe:$1$jUWA/Uz0$pvAecsNoesrw.lv9eM7Sn0:15876:0:99999:7:::
maria:$1$M.6iuNRQ$qQpbYXe/vQE/xJPaG2SjK0:15876:0:99999:7:::
victor:!!:15876:0:99999:7:::

Splitting each line of this file would return a list with: username in position 0 and the crypted password in position 1.

A simple algorithm to crack crypted shadow files.

Very light version.... Very....


shadow_lines = readShadow(sys.argv[1])
word_lines = readWords(sys.argv[2])

for i in range(len(word_lines)):
    word = word_lines[i].strip()
    for user in shadow_lines:
        user = user.split(":")
        if crypt.crypt(word, user[1]) == user[1]:
            print "User %s, password %s" % (user[0], word)

Note user[0] is the username and user[1] contains the crypted password.

How long would it take to crack a password file?

It will depend on the number of users in the password file and the number of words in the dictionary file.

Our algorithm will take O(|shadow_lines| x |word_lines|)

The example we will use would take around half an hour to finish.

Not that long, if the results are worth...

A simple parallel implementation.

So we have 479,623 words.

A small cluster with 12 cores.

A password file with passwords <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< words

So lets divide the dictionary among the cluster cores and have each core check the portion of the dictionary assigned against each password.

A simple parallel implementation with mpi4py


if rank == 0:
    shadow_lines = readShadow(sys.argv[1])
else:
    shadow_lines = None

shadow_lines = comm.bcast(shadow_lines, root=0)

n1, n2 = computeIndices(len(word_lines), num_procs, rank)

# Shrink words from memory.  Trust in the GC
word_lines = word_lines[n1:n2]

for word  in word_lines:
    word = word.strip()
    for user in shadow_lines:
        user = user.split(":")
        if crypt.crypt(word, user[1]) == user[1]:
            print "User %s, password %s" % (user[0], word)

Implementation notes.

Note that I am taking advantage of having a shared file system to have each process read the dictionary file.

This would not work if the FS is not shared among all nodes of the cluster.

I just simply do not want to send a list of 479,623 words to each node.

Note that I did read the password file in one of the processes (rank==0) and send it to the all the other processes. Just because I can :).

So lets crack our shadow files!!!

References

Python, http://www.python.org

MPI4py, http://mpi4py.scipy.org/

John the Ripper, http://www.openwall.com/john/