John the Ripped – Steak and French Fries With Salt and Pepper Sauce for Hungry Password Crackers
by Thireus on May.20, 2012, under Crack1ng, Guides and tutorials, Hack1ng. 9,951 views

John the Ripper into its latest community enhanced version (John the Ripper 1.7.9-jumbo-5) has many advanced features. Most of them are without any doubt very useful and appreciated such as MD5 hash cracking.
Four days to come before Hack In The Box Amsterdam 2012 security conferences. Excitement is at its top level, bags are already packed and iOS Hacker’s Handbook is left open on the beside table. But because it is always time for challenges, I decided to face one that I have in mind for years…
Cracking a custom hash algorithm and making your own password cracking cluster would be great huh… ?
Well you know what? You can do it with John the Ripper jumbo version
Updates: (subscribe to my twitter to get notified)
- 11/16/2012 – Note about run/dynamic.conf file. No need to recompile, much more easier to edit!
- 11/16/2012 – Note dynamic function names up to 999 are reserved!
- 11/16/2012 – Added “–subformat=LIST” tip.
Prepare salt and pepper sauce… the French Cuisine
Most of the time, hashed passwords are salted and combined with different famous hash algorithms. For example, administrators who have a little sensibility with security will hash user passwords with different combinations, i.e. sha1(md5($salt.$password).”HelloWorld”). This kind of classic enhanced security to store hashed passwords makes the job harder for password crackers.
First of all the attacker needs to know how passwords were hashed. Reverse engineering is always a good start but the easiest way is to get the sources. The second point and the one I’ld like to talk in the first part of this article is to implement and use your own hash algorithm for cracking purpose.
- First go to http://www.openwall.com/john/, and download the latest jumbo ”community enhanced” version. When I write this article the latest stable release was 1.7.9-jumbo-5
$ wget http://www.openwall.com/john/g/john-1.7.9-jumbo-5.tar.gz $ tar -xvzf john-1.7.9-jumbo-5.tar.gz
- Let’s see what we have here…
$ cd john-1.7.9-jumbo-5/src/
Before changing anything, we’ld like to check if it compiles well.
- The make command will list all available compilation modes. This time I’m gonna compile john on MacOS X Lion 10.7.3. Choose the one you prefer…
john-1.7.9-jumbo-5/src$ make john-1.7.9-jumbo-5/src$ make macosx-x86-64
- If everything is ok you should see john binaries and configuration files into the run directory
john-1.7.9-jumbo-5/src$ cd ../run/ john-1.7.9-jumbo-5/run$ ./john --test
- Now go back to the src directory
john-1.7.9-jumbo-5/run$ cd ../src/
In the introduction I talked about a custom hash algorithm such as sha1(md5($salt.$password).”HelloWorld”). So let’s take this one as example.
Note: A similar procedure can also be applied directly to the run/dynamic.conf file, where you can add your own dynamic functions ([List.Generic:dynamic_XXXX]) without the need to recompile.
What we’ll need to modify is dynamic_preloads.c. This is where we can create our custom algorithm under the name of dynamic_1666. Names up to dynamic_999 are reserved, so make sure to use a number which is not already in use by another dynamic function. Use the command “./john –subformat=LIST” to check available numbers.
Additionally, you’ll find into this file many example of classic dynamic subformats such as md5(md5($password)). I advice you to understand by your own how things work before doing anything.
- When you are ready, open dynamic_preloads.c and add these new lines
//dynamic_1666 --> sha1(md5($s.$p)."HelloWorld") BY THIREUS
static DYNAMIC_primitive_funcp _Funcs_1666[] =
{
DynamicFunc__clean_input,
DynamicFunc__append_salt,
DynamicFunc__append_keys,
DynamicFunc__crypt,
DynamicFunc__SSEtoX86_switch_output1,
DynamicFunc__clean_input2,
DynamicFunc__append_from_last_output_to_input2_as_base16,
DynamicFunc__append_input2_from_CONST1,
DynamicFunc__SHA1_crypt_input2_to_output1_FINAL,
NULL
};
static struct fmt_tests _Preloads_1666[] =
{
{"$dynamic_1666$e964aa651052d2bbd64aea60756d7705634187f6$admin","password"}, // salt=admin, password=password
{"$dynamic_1666$4a573951007f7d23eb411c066e2cfb8a175a76d2$123456789","heydude"},
{"$dynamic_1666$fee9c8708b2e1a177acd350513c14ce0e9900609$salted","test123"},
{"$dynamic_1666$d8e18f5f1035ce486dd3a08911a4205d78fc7f49$bonjour","awesome"},
{NULL}
};
static DYNAMIC_Constants _Const_1666[] =
{
{"HelloWorld"},
{NULL}
};
If you are curious about how to declare DynamicFunc__ actions and optimise your function, you’ll find all you need in dynamic_parser.c and dynamic_fmt.c
- Finally at the end of the file, we need to specify hashes format
{ "dynamic_1666: sha1($s.md5($p).\"HelloWorld\")", _Funcs_1666,_Preloads_1666,_Const_1666, MGF_SALTED|MGF_SHA1_40_BYTE_FINISH, MGF_NO_FLAG },
- Once everything is in place, we have to clean and compile again.
john-1.7.9-jumbo-5/src$ make clean john-1.7.9-jumbo-5/src$ make macosx-x86-64
- You should see john binaries and configuration files into the run directory. And you can run the –test option of John the Ripper.
john-1.7.9-jumbo-5/src$ cd ../run/ john-1.7.9-jumbo-5/run$ ./john --test
New lines should appear to display benchmark scores for your function.
Benchmarking: dynamic_1666: sha1($s.md5($p)."HelloWorld") [SSE2i 10x4x3]... DONE Many salts: 1855K c/s real, 1995K c/s virtual Only one salt: 1741K c/s real, 1852K c/s virtual Benchmarking: dynamic_1666: sha1($s.md5($p)."HelloWorld") [64x2 (MD5_Body)]... DONE Many salts: 1373K c/s real, 1509K c/s virtual Only one salt: 1283K c/s real, 1410K c/s virtual
john-1.7.9-jumbo-5/run$ ./john --subformat=LIST
Tests fails?
There are many reasons why tests can fail. The main reasons are due to a bad use of DynamicFunc__ actions, bad order or bad implementation. This will result into a verbose fail of John before starting any tests.
Another common issue, could be that your fmt_tests are broken, meaning bad format for example, this results into a FAILED (valid) error during the tests.
And one last point, if you hash long strings using SSE mode your tests will automatically fail! That’s the reason why you have to switch between SSE and X86 mode using functions such as DynamicFunc__ToX86 or DynamicFunc__SSEtoX86_switch_output1.
- You should now be ready to crack these passwords
lydia:$dynamic_1666$72d4d61b4e5db9ef8704d1af81284c67eea640dd$skyrim admin:$dynamic_1666$70ea6b7f633305f04521683226ecabd0537e90ec$example.com user123:$dynamic_1666$907c7df1d7e349e98184d74fb7486c77eaf76d60$example.com Thireus:$dynamic_1666$e41c041fda28b3615b63acddb6407cf74b354d66$CestLaFeteAlouette
- Put them into a hash.txt file, and crack them all
john-1.7.9-jumbo-5/run$ ./john hash.txt
Step by step instructions for grilling the perfect steak… with MPI enabled barbecue
Few months ago I wrote an article that explains how to compile John the Ripper with OpenMP enable to take advantage of Multiple Cores. Crack Passwords using John the Ripper with Multiple CPU Cores (OpenMP). OpenMP is good for algorithms such as DES which can be used by default with this awesome feature. The bad news is that not all algorithms are compatible with OpenMP, such as MD5 or SHA1. Fortunately there is one good news
we can use the MPI (Message Passing Interface) feature of John the Ripper, to take advantage of all our CPU cores with any algorithm!
Before going any further, some packages are required. You have to install OpenMPI.
- Under MacOS you can do it via MacPorts using the “sudo port install openmpi” command.
- Under Linux you can get everything with “sudo apt-get install libopenmpi-dev openmpi-bin openmpi-doc“.
Make sure your have the mpirun command available.
- Now what you have to do is to open John’s Makefile and edit two lines
$ cd john-1.7.9-jumbo-5/src/ john-1.7.9-jumbo-5/src$ nano Makefile
- Locate the following lines
#CC = mpicc -DHAVE_MPI -DJOHN_MPI_BARRIER -DJOHN_MPI_ABORT #MPIOBJ = john-mpi.o
- Uncomment MPI flags
CC = mpicc -DHAVE_MPI -DJOHN_MPI_BARRIER -DJOHN_MPI_ABORT MPIOBJ = john-mpi.o
- Once everything is in place, we have to clean and compile again
john-1.7.9-jumbo-5/src$ make clean john-1.7.9-jumbo-5/src$ make macosx-x86-64
Under Linux, compilation should work out of the box. Under MacOS users will face this issue:
john-mpi.c:6:10: fatal error: 'omp.h' file not found
#include <omp.h>
^
1 error generated.
make[1]: *** [john-mpi.o] Error 1
make: *** [macosx-x86-64] Error 2
To fix it, just open the john-mpi.c file and comment omp.h file inclusion (which is not needed and must not be used under MacOS X)
#include "john-mpi.h" #include <string.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> //#include <omp.h>
Now it should compile and run fine with mpirun
john-1.7.9-jumbo-5/run$ mpirun -n 8 ./john hash.txt
You need to adjust the number of cores depending on your CPU
. With the previous command the work is now split in 8 sub-processes, one per core on my i7-8600K. Isn’t that great?
Warning: Once the number of cores has been fixed for a session, don’t change it unless you know what you are doing. Because for sure it can break your work
Note that you can use sessions, and similar options that can be associated with mpirun. For example, if you want to know the state of a session:
john-1.7.9-jumbo-5/run$ mpirun -n 8 ./john --status=mysavedsession
This will read for you all the “mysavedsession.%d.rec” where %d is a number between 0 and 7 in this case. One last thing, sessions are saved every 10 minutes, so don’t be scared if the status command displays null stats for the first 10 minutes
Cook some French fries for your steak
So you have many computers in your room, and want to take advantage of all CPUs? As promised, I’ll talk about clustering here for advanced users only
Before going any further, some packages are required. You have to install OpenMPI and mpich2.
- Under MacOS you can do it via MacPorts using the “sudo port install openmpi mpich2” command.
- Under Linux you can get everything with “sudo apt-get install libopenmpi-dev openmpi-bin openmpi-doc mpich2“
Make sure your have the mpirun command available and hydra_pmi_proxy.
hydra_pmi_proxy is the binary file which is used to talk between computers. It is located under “/opt/local/bin/hydra_pmi_proxy” on MacOS X and “/usr/local/bin/hydra_pmi_proxy” under Linux.
What you need to know now is that any systems must run the same John the Ripper version, in the same directory and use the same version of mpich2. If this is not the case you can manually compile and install mpich2 and also create symbolic links with “ln -s” command.
For example, to talk between MacOS and Linux I had to make sure hydra_pmi_proxy can be reached using the same path on both systems.
ln -s /usr/local/bin/hydra_pmi_proxy /opt/local/bin/hydra_pmi_proxy
Now that all your computers are ready, make sure you can reach them via ssh, because this is the way used by MPI messages. So I advice you to create SSH key pairs. Once done, create a nodes.txt file, containing ip addresses of the computers you want to use.
toto@192.168.1.145 localhost localhost localhost localhost mike@192.168.4.12 mike@192.168.4.12 mike@192.168.4.12 mike@192.168.4.12 192.168.5.5 192.168.5.5 paul@mydomain.com paul@mydomain.com
You can now use this file to invoke commands on other systems. Let’s start with “john-1.7.9-jumbo-5/run/john –test”.
mpirun -f nodes.txt -n 18 john-1.7.9-jumbo-5/run/john --test
You may have noticed that I’m not using 18 processes (18 CPU cores). Because once the end of the nodes.txt file is reached, mpirun will start again at the beginning of the file, making loops. toto@192.168.1.145 will thus be used twice, as well as the 4 localhost. You should now be ready to play with your own password cracking cluster

Ready to serve. Bon appétit !
Incoming search terms:
21 Comments for this entry
2 Trackbacks / Pingbacks for this entry
-
This is the story about how I cracked 122 million* password hashes with John the Ripper and oclHashcat-plus. | *.blog.internetz.me
December 13th, 2012 on 1:37 pm[...] John the Ripped – Steak and French Fries With Salt and Pepper Sauce for Hungry Password Crackers [...]
-
Crack passwords using John the Ripper (JTR) using multiple CPU cores
May 22nd, 2013 on 12:16 pm[...] Another good article by same author on password cracking using JTR + MPI. Thanks to him for his good work and sharing. John the Ripped [...]
September 28th, 2012 on 2:57 am
If I’m creating a cluster, my secondary machines (those networked to the main machine) don’t need big hard drives at all, do they?
September 28th, 2012 on 9:30 pm
“Any systems must run the same John the Ripper version, in the same directory and use the same version of mpich2″
From the article!
You can still attempt to install john on your secondary machine without hard drive using a Live CD or using USB/SD Card.
September 28th, 2012 on 9:24 pm
Ok, I’ve installed the jumbo, and I’ve installed OpenMPI, but John can’t find it. I’m googling, googling.
September 28th, 2012 on 9:33 pm
Probably because the Makefile can’t find it. What is the reported error?
September 28th, 2012 on 9:39 pm
make[1]: mpicc: No such file or directory
make[1]: *** [john-mpi.o] Error 1
make: *** [macosx-x86-64] Error 2
The OpenMPI instructions said to install it at / so I did, in a folder called /OpenMPI/
Currently John is in my user folder, so /Users/me/john-1.7.9-jumbo-7/
September 28th, 2012 on 9:43 pm
Alright. Make sure “/opt/local/bin/mpicc” exists and that you have “/opt/local/bin” in your $PATH.
September 28th, 2012 on 10:34 pm
mpicc is in /OpenMpi/bin/mpicc, and /opt/local/bin/ does not have it.
I really appreciate your help, would you prefer we took it off your blog? Or would you like these noob replies of mine to mitigate further noobs hassling you?
September 28th, 2012 on 10:46 pm
Sean, you must follow my tutorial carefully, line after line, everything is explained in the article.
For your information, you must install OpenMP using MacPort! This is pointed in the article! If you don’t follow correctly the guide, for sure you will face many issues.
“Under MacOS you can do it via MacPorts using the “sudo port install openmpi mpich2” command.”
September 28th, 2012 on 11:40 pm
Thireus,
Thank you! I’ve finally got it working on my 8 cores on my Mac. Now that I’m a bit more comfortable with it, I’m going to start building a cluster next week.
Last question — what setting in this jumbo version do I need to change so I can hit enter and see the current status, time elapsed, c/s guesses, etc?
September 28th, 2012 on 11:47 pm
This is a pretty good question! I face the same issue and unfortunately I think there’s no way to press a key to show status when using mpirun.
BUT there are some solutions, the first I have in mind is request –status combining mpirun and john. You can still manually check status for each saved sessions without the need of mpirun.
There should be some other and proper solutions around… let me ask this to the john devs.
September 29th, 2012 on 6:58 pm
Alright, magnum replied with a solution. The idea is to send a USR1 signal to the mpirun PID.
To get the pid:
ps | grep mpirunSend the USR1 signal:
pkill -USR1 mpirunOR
kill -USR1 MPIRUN_PID # (Under Mac OS there are no such pkill command.)September 29th, 2012 on 1:14 am
Sorry, another question. I’m finding rules and things I want to use, and wordlists I want to combine with my big list. When I cluster the machines, do they all need the same wordlist and rules, or does the main machine provide what’s needed?
September 29th, 2012 on 7:05 pm
Yes, they need to have all required files in the same directory path. MPIRUN is just a tool that executes a same and unique command on all clustered computers, the only difference is that each process is told to be #N/#M_TOTAL (understand process number N over a total of M). So each john process knows exactly which part of the wordlist/bruteforce space it will have to deal with. But still, mpirun is not that magic, this is just a command that splits the work but run the same john command on each computer/core.
So yes your wordlist has to be duplicated at the exact same location on every single computer of your cluster. Same thing for every other files used by john (same version, configuration, specific tools/commands, etc.).
November 16th, 2012 on 3:43 am
Thireus, i want to use JTR for cracking custom hash in a php application –> crypt(md5(plain),salt)… in the documentation i only found SHA1 and MD5 dynamic func primitives. does JTR support dynamic function for traditional DES crypt ?
November 16th, 2012 on 4:26 am
Hi agan, John The Ripper does
notimplementanysome (a)symetric cryptographic functions like DES. But none of them are implemented as dynamic functions.But first of all you need to make sure that the crypt() function used for your hashes is the old implementation that uses DES, in your case because of the salt I assume it is CRYPT_EXT_DES (c.f. http://php.net/manual/en/function.crypt.php). If that’s the case you’ll need better tools to reverse the crypt function (c.f. https://en.wikipedia.org/wiki/Data_Encryption_Standard#Brute_force_attack) and lot of money because it will cost you about $10,000… Let’s suppose you have the money and know the salt used by the crypt function, it will only take between 1 and 2 weeks to complete all key space.
You can have a look at this http://3.14.by/forum/viewtopic.php?f=8&t=1095, I’m not sure if you can use it in your case. But remember… be extremely cautious when you download Russian files/exec!
If you achieve the reverse part for the crypt() function then you’ll still be able to use the wonderful JtR for md5(plain).
November 16th, 2012 on 9:20 am
i’m sure that the crypt in my case is old DES crypt, 13 byte long with the first 2 bytes as salt, so the hash is valid old unix DES crypt of md5(password). i already made simple dictionary based brute forcer in php just for poc, but i need more powerful engine like JTR.
the case is, i already know the hash (and its salt of course), i want to use JTR to brute that hash. i know JTR can brute old unix DES crypt(), and md5(), i want to combine those two to brute crypt(md5(p),salt)… do you know where in JTR src i should look at ?
November 16th, 2012 on 2:29 pm
I had a closer look at the latest JtR sources, and in fact DES IS implemented. xD So, sorry my first reply was wrong. Unfortunately, it will not be easy for you to combine it with md5… You can have a look at the latest Jumbo version of JtR, you’ll see DES_*.c sources. You can also try the JtR dev version where some good devs already implemented an opencl version opencl_DES_*.c.
I think the best way to ask for this kind of functionalities would be directly on JtR mailing lists.
Some links that might help you:
http://pentestmonkey.net/cheat-sheet/john-the-ripper-hash-formats
http://www.openwall.com/john/#lists
I’m also updating this article with new stuffs.
November 17th, 2012 on 12:41 am
Thank you for your helpful reply Thireus, i’m going to join JTR lists as you suggested
December 12th, 2012 on 2:33 am
The MPI stuff for cracking MD5 on multiple cores works great! Thank you so much!
The only thing is I noticed some of the found passwords are repeated (i.e. one of MD5 hashes works out to, say, password “Chicago” and I get 3 reports about it). I wonder if the 4 of my cores are being used by four processes to do the same stuff, or whether they are doing different thing, and it’s just the repeated passwords happened to match multiple things the dictionary (note: I have no clue how JiR works).
December 12th, 2012 on 2:42 am
Something must be wrong with your john. You know when MPI is enabled when you get a message like “MPI: each node processing 1/X of YYYYY rules. (even split)” for X subprocess… For example:
Loaded 9344766 password hashes with no different salts (Raw MD5 [128/128 AVX intrinsics 12x])Remaining 4404349 password hashes with no different salts
MPI: each node processing 1/2 of 6200 rules. (even split)
If you don’t have this message, then you know that MPI is not activated. Follow the steps once more to compile john the ripper with MPI enabled and everything should be fine.
Regards,
Thi.
December 12th, 2012 on 3:39 am
Hm. I get these messages:
Loaded 199 password hashes with no different salts (Raw MD5 [128/128 SSE2 intrinsics 12x])
MPI: each node processing 1/4 of 1081 rules. (uneven split)
… some found passwords are shown here…
MPI: each node loaded 1/4 of wordfile to memory (about 6 KB/node)
After the passwords that are found in the first… second of running, I get some found passwords but I don’t get any more repeats. All 4 cores are working at 100%, so I think everything is working great.
Thanks again.