Linux:Using Bash to Generate a Wordlist

A few weeks ago my wife forgot her KeePass password. She can remember most of it, but there are certain portions of it she can’t quite get (looks like the muscle memory didn’t stick too well). With that, she asked me if there was a way for me to recover the password to her KeePass database. While the chances are slim, I figured if I could generate a pertinent wordlist, I could save a lot of time over having John incrementally try every possible password all the way up to 22 characters (Which happens to be 3,807,783,932,766,699,862,493,193,563,344,470,016 possibilities totalling about 120,744 septillion years of crack time at 1000 hashes per second).

Inline Array Expansion

To do this, we’re going to use one of bash’s lesser-known functionalities: inline array expansion (I don’t know its official name or if it even has one, so that’s what I’m calling it).

If you’ve ever looked up how to manually create a maildir directory, you’ve likely seen something like this

mkdir -p ./your_dir/\{cur,new,tmp}

At runtime, bash will expand that command to three seperate commands

  • mkdir -p ./your_dir/cur

  • mkdir -p ./your_dir/new

  • mkdir -p ./your_dir/tmp

Another good example of this functionality would be creating a new home directory.

mkdir -p /home/username/\{Desktop,Documents,Downloads,Music,Pictures,Videos}

Generating the Wordlist

Applying this to generating a wordlist is very similar to creating "arrays" of nested directories in a single command. To generate a wordlist, we’ll use the echo command instead of mkdir (of course). We’ll also use varying combinations of arrays in a single line.

Example

Suppose the password you want to work on is something like password1234. However, what we don’t know is the order of the 1234 at the end. We also don’t know if the first letter is capitalized or not, or if the actual password uses 0’s in lieu of o’s, 4’s in lieu of a’s, or 5’s in lieu of s’s. Let’s see what we can do about this.

echo \{p,P}\{4,a,A}\{5,s,S}w\{0,o,O}rd\{1,2,3,4}\{1,2,3,4}\{1,2,3,4}\{1,2,3,4} > possible_passwords

That should produce a file containing roughly 13,000 words. However, due to the way the arrays are processed, newlines are not inserted between each possible password. To remedy this, just do a quick sed expression (or awk if you like)

sed -i 's/ /\n/g' ./possible_passwords

With that, you now have a wordless primed and ready for use with john.