This tool is designed to aid in targeted brute force password cracking attacks. The short summary is that I love using John the Ripper's -incremental mode which incorporates the most sophisticated Markov modeling I've yet to see in a password cracker. JtR uses 2nd order Markov models, (where it models the probability of three letter triplets appearing), and it actually keeps separate probability information for different length words, (aka the probability matrix it uses for a 5 letter word is different from the one it uses for an 8 letter word). To better illustrate this, below are the first 10 guesses JtR will create when running a brute force attack, (using only a lower alpha key-set):
As you can see, it looks a lot like a dictionary attack, but it's actually using brute force. The advantage is that if you let it run long enough it will completely cover the keyspace, aka it will eventually try unlikely guesses such as 'zqzqqqzz' which a normal dictionary attack will never try. The problem is, while Markov models are very efficient at generating guesses that look like human generated words, they still can have trouble cracking any halfway decent password, (due to time constraints). Middle Child is an attempt to apply additional logic to JtR's -incremental option to more efficiently attack stronger passwords.
-Ed note: Yes that is the "short" summary...
So what is the additional logic that Middle Child uses? Mostly just basic modeling of how people create passwords. For example, people often put numbers at the end of a password, and if they bother to hit the shift key, capitalize the first letter. Another optimization is if users incorporate special characters and numbers into their passwords, they generally use a special character followed by a number and not the other way around. Really all Middle Child does is apply word mangling rules to brute force guesses. By applying these rules to the password guess as a whole, it allows and attacker to target what are traditionally considered stronger passwords using a brute force attack. This is important since most input dictionaries will generally only crack around 30-50% of an average password set even in a best case scenario. That number isn't made up, (like 74% of all statistics...). If you are interested, check out my Defcon16 slides for a further explanation of how I came up with that 30-50% range. Note, I haven't tried to run the numbers again with Sebastien Raveau's humongous wikipedia wordlist yet since it was so large it broke my parsing tool. Ok, back on track: Now admittedly when you start to use multiple input dictionaries you can achieve better results, (especially input dictionaries created from previously cracked passwords), but after a certain point that starts to resemble brute force as well. I guess what I'm trying to say is that brute force attacks still play a very important role in password cracking. It just means you have to be smart about how you go about using brute force style attacks.
As its name implies, Middle Child is run between two different instances of John the Ripper. It takes the output of one instance of John the Ripper, running in incremental mode, mangles the input according to the rules specified by the attacker, and then pipes its output into the second instance of John the Ripper that is actually cracking the passwords.
Usage: ./middlechild <options>
-append <values> Appends the values to the end of the input word
-prepend <values> Inserts the values to the front of the input word
-capFirst Capitalizes the input word
-capAll Capitalizes the entire word
-capLast Capitalizes the last letter of the input word
-capAllButFirst Capitalizes all the letters but the first one
-capAllButLast Capitalizes all the letters but the last one
S = symbols, D = digits
Follow values by a number indicating how many of them you want to append/prepend, from 1-9
./john -incremental=alpha -stdout -session=savefile | ./middlechild -capFirst -append D2S1 | ./john -stdin -format=raw-MD5 ./hashlist.txt
Takes an input dictionary, capitalizes the first letter, appends two digits, and then one symbol
It's C++ code, so simply running the included "make" file should compile it for you on your own computer.
Restoring Interrupted Session:
You might have noticed that I used the -session option for the first JtR instance in the previous example. First off, this is because you cannot run two different instances of JtR without giving each one a different session name, (in the above example, the second instance of JtR is using the default session name). The first instance of JtR is the one you would want to restart, since it is the one creating the initial password guesses.
General Programming Notes and Performance Info:
Depending on how processor intensive the password hash you are trying to crack is, the use of Middle Child can dramatically slow down the number of guesses you are making per second. A vast majority of this performance hit comes from the fact that it has to take the input from one program via stdin, and then outputs it via stdout. These aren't cheep operations as the pipe quickly becomes a bottleneck, so if the password hash is very fast to compute, such as one round of MD4, (think Windows NTLM password hashes), it can reduce the number of guesses you are making by around 10-20%, (aka if you are making 20000 Million guesses a second without Middle Child, you probably would make around 17000 Million guesses a second with Middle Child). Even when I took out all the guts of my program and just had it pass the raw input, (aka without using any additional mangling rules), I still saw a majority of this speed reduction. Of course the obvious solution would be to incorporate Middle Child directly into JtR, but I'm hesitant to do so since JtR has been changing quite a bit lately, and I have a feeling most people, understandably so, would be hesitant to patch their copy of John with some random patch that I came up with. If you look at the actual code, you'll notice that I took what begs for a recursive programming solution, and used an overly complicated while loop instead. Once again, this was to try and make it as fast as possible. I know no one cares about that, but I'm putting that disclaimer in just in case any of my former programming professors read my code and then decide to smack me ;)