|
Message-ID: <4CC5F34F.2030304@16systems.com> Date: Mon, 25 Oct 2010 17:14:55 -0400 From: Brad Tilley <brad@...ystems.com> To: john-users@...ts.openwall.com Subject: Re: Solution to this 'l33t' rules problem? Charles Weir wrote: > This is a really interesting problem since it's certainly a needed > attack type to target more advanced passwords. As Brad pointed out, > the posted suggestion by Solar and Rich to generate replacement rules > can get really nasty when multiple replace types are implemented at > the same time, such as 'p@...ord'. I spent a little bit of time > trying to write a script to auto-generate a JtR config file that would > contain those thousands, (if not more), of potential replacement rules > but I eventually ended up dropping that approach and instead decided > to make use of JtR's -stdin option. > > On a side note, JtR's -stdin option is one of the main reasons I use > John. If you can think of a way to generate guesses, even if JtR's > built in mangling rules doesn't support it, you can always write your > own program/script to generate the guesses and still use JtR on the > back-end to handle all of the hashing. > > To that end I wrote the program 'noobify', which is available at the > following link: > > http://sites.google.com/site/reusablesec/Home/password-cracking-tools/noobify > > Yes the name is a play on l33tify ;) > > I tried to make it as customizable as possible. Below is an > explanation of a couple of the design choices: > > 1) As the name implies, it will apply every possible replacement rule > to an input word and then output it for JtR to hash. Aka the word > 'noobify' could generate n0obify, n00bify, n00b1fy, n0ob1fy, no0bify, > no0b1fy, noob1fy ... > > 2) It reads in the replacements to use from a tab separated text file, > (the default file is replacements.txt). This allows the user to > specify the specific replacements they want to use, vs hard-coding > them in. For example, you can also do things like uppercase vowels if > you want by replacing 'a' with 'A', etc. This also allows the user to > have multiple replacement profiles for use in different cracking > sessions. > > 3) It replaces substrings instead of characters. This allows for > multi-character replacements. The most common 'l33t' example would be > replacing 'f' with 'ph', but it actually opens up a bunch of other > options as well. For example you can replace '2009' with '2010', or > 'monday' with 'tuesday'. The replacements do not have to be the same > size. > > 4) Currently it works a lot like middlechild, > http://sites.google.com/site/reusablesec/Home/password-cracking-tools/middle-child > in that it will take input from stdin, and then output it to stdout. > Probably the most common use of it would be: > > cat <input_dictionary> | ./noobify | ./john -stdin -format=<hashtype> > <target_hashes> > > 5) Currently it doesn't apply any other mangling rules. If you want to > apply additional mangling rules you do have a couple of different > options available to you. The first is to use noobify to generate a > custom input dictionary instead of piping the output directly into > John. Then you can use that input dictionary with all of your existing > JtR mangling rules. The second option is to chain the output into a > second mangling program like middlechild. For example, the below > command would also capitalize the first letter and append two digits > followed by one special character: > > cat <input_dictionary> | ./noobify | ./middlechild -capFirst -append > D2S1 | ./john -stdin -format=<hashtype> <target_hashes> > > The advantage of this approach is that it works for much larger input > dictionaries, since you don't have to save the mangled results to > file. The downside though is that it applies EVERY mangling rule to > each word before moving on to the next one. When you use John's rules > you can optimize it a lot more to try high probability rules first, > which will usually result in you cracking passwords much sooner in > your cracking session. > > 6) I practice "agile development", which is a nicer way of saying that > I try to get a proof of concept working before I focus on making it > 'good'. Currently there's a lot of inefficiencies in the code that > make it run fairly slow compared to most other mangling rules, (the > biggest probably being in how I currently identify replacements in the > actual word). I should be able to fix some of them fairly soon, but > even in it's current state, at least you can make guesses which were > difficult to generate beforehand. Also as stated above, you can always > save the results to file, making the running time of this tool only a > one time cost. > > 7) I just realized I forgot to test it, but theoretically the tool > supports deletions as well, (in the replacement file just have the > value you want to delete followed by a tab and then a return). This > way you can do things like remove spaces and punctuation from a > passphrase input dictionary. If it crashes horribly when you try to do > this I should have a fix soon ;) > > 8) Yes the code is C++ so you will have to compile it. I realize I > should have written it as a script to make it easier to use, but I > like writing in C++. The code is GPL'd so feel free to modify it. > > 9) The default replacement file I included is just a proof of concept. > Aka I got tired after entering the different replacements in for > 'january', aka january->february, etc, so I didn't do any of the other > months ;) > > 10) As an addendum to the previous point, be careful when you a > copying and pasting replacement rules, since many editors will paste > spaces instead of tabs. > > As always, if you have any questions/comments/suggestions, please let me know. > > Matt Weir > http://reusablesec.blogspot.com That's interesting Matt. I hard-coded a Cartesian product solution using nested for loops. It's fast, but it does not scale as well as your mangleGuess function would. Here's an example with 2 char passwords... nest one more level for each additional char: ------------- std::string one = "nN"; std::string two = "oO0@"; std::string attempt; std::string::const_iterator it1_end (one.end()), it2_end (two.end()); for ( it1 = one.begin(); it1 != it1_end; ++it1 ) { attempt.push_back(*it1); for ( it2 = two.begin(); it2 != it2_end; ++it2 ) { attempt.push_back(*it2); std::cout << attempt; attempt.resize(1); } attempt.clear(); } ------------- I'm guessing this would work with JTR's stdin option. I'll try it. Brad
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.