How to Parallel Programming with OpenMP: Building a SHA-512 Password Cracker
In this article, we will build a parallel password cracker using the techniques explained in the previous part. As SHA-512 is the digest function that Kali (and most modern Linux distributions) use to store our passwords, we will make a SHA-512 password cracker.
I will use Kali version 1 in this article, but I think the code would work on many Linux distributions as the system calls are the same.
I think that OTW has explained /etc/shadow in another article, but let's take a quick look to it. Shadow contains the hashed passwords of each user in the system and information related with account management. An example of a line in that file:
In the above line there are fields separated by ":", those are:
-The username: root.
-In the next field, we have 3 parts separated by "$":
- 6 means the digest function used is SHA-512.
- Ig0456UR Is the salt used in conjunction with the plaintext password to obtain the hash value.
- b9rkoxIDTAue2XocjrtHjOEJxHKTClvjOxJx2agKSdUNb0GVuC2yavlsU42TUUKSP2TDRXFPo60k70nkJMYiu. is the 512 bit hashed password obtained with the salt and the plaintext password.
You can see the next fields in an understandable format by typing:
chage -l <username>
As you see the next fields are information related to account management, I will not focus on them anymore because we don't need them for our purpose here.
I found a simple SHA-512 cracker here and I decided to modify it in order to work with any dictionary file and run simoultaneously on all available CPUs. The modified code is available here and looks like this:
If you compare this code with the original, you'll notice that is very similar. The while loop now is a for loop, variable found is included to control the guess of password, and we can work with any dictionary file. I have also added a function to get the number of words in the dictionary.
I will explain the most important parts of the code, if you have any question, put it on the comment section or send me a message.
- First we include the OpenMP header.
- Convert while loop to a for loop in order to use the constructor "parallel for" (optimized for for loops).
- Variable word is private for each thread, because each thread will attempt to crack a different password (private(word) ).
- Variable found is shared by all threads, because if one of those threads find the password, the program is finished (shared(found)).
Let's test our cracker with a test user and one of the wordlists included in Kali. Compile the program with the following flags:
gcc -fopenmp -lcrypt -std=c99 -o parshacrk parshacrk.c
To execute our program:
./parshacrk 1 2 3
- Dictionary file with one word per line (here I will use rockyou.txt but you can use any wordlist).
- Salt value in the following format: '$6$<salt>$'
- Hash value in the following format: '$6$<salt>$<hash>'
Let's test it with our own password, I'm going to create a new user with username "user" and password "password":
cat /etc/shadow | grep user
Copy the required fields and put them on the parameter section as below (don't forget to add the single quotes on 2nd and 3rd parameter):
./parshacrk /usr/share/wordlists/rockyou.txt '$6$IUUHDOMU$' '$6$IUUHDOMU$hagBbYm9zywgkLFIJQkM4JpskT8xjxbBlhlFjAXVt1t.XfomJUmG/7Hh79uWETekDzbwsbSxLXkXdEc7j7gPz.'
As you see, our cracker has guessed the password correctly. You can set the number of threads typing:
Where X is the number of threads. Be sure to select a correct number of threads (not greater than number of threads that your CPU supports). You can see this information typing:
Or, for more detailed information:
To obtain the maximum number of threads that your CPU support, multiply the number of sockets, number of CPUs per socket, and threads per CPU.
If you have an Intel Core i7, with 2 CPUs per socket, 2 sockets, and support for 2 threads per core, you will have a maximum of 8 threads simoultaneously, be sure to keep the number of threads below or equal the maximum.
This was a simple demonstration of how this kind of tools work. Of course John the Ripper or Hashcat aren't as simple as above, they implement more sophisticated methods to run in GPUs (OpenCL), or to split the wordlist into each thread, generate wordlists with a specific mask at execution time, etc.
- This article.
- Computer Architecture 5th ed. by Hennesy and Patterson.