A few months ago I bought a new hard-drive. When you encrypt a drive, you need to set a password – but the trick here is to remember the password. Your hard-drive won't send you a "forgot password?" email. So you set that password, enter it, the drive mounts and then you work away happily for weeks without rebooting your machine.

Then you reboot... and you need to re-enter that password.

You slowly realize that those weeks ago you set a new unique password for that bloody hard-drive that you don't remember for the love of god... What to do? Well one, don't be a complete idiot like me – remember the password. But if you do, here is what to do? [Spoiler alert: I failed to recover the password but it's a pretty interesting ride...]

The new Ubuntu 16.04 comes with this handy too called 'bruteforce-luks', here are some scenarios. Note you have to use it as root.

"I remember the start/end of the password and I sort of know what's in the middle"

Here is what you can try, where the -b and -e are the starts and end of the password are known. -t is the number of CPU threads to use. -l and -m are the lower and maximum length of the password. -s is the set of characters you wanna use to crack.

sudo bruteforce-luks -b SomeStart -t 4 -l 9 -m 14 -s 0123456789  /dev/sdc1

sudo bruteforce-luks -e SomeEnd -t 4 -l 9 -m 14 -s 0123456789  /dev/sdc1

The device /dev/sdc1 maybe different in your case. To check progress of this brute-force scan use

pkill -USR1 -f bruteforce-luks

"I have no idea what the password is but my passwords are usually made up of some tokens"

Worry not! That actually drastically reduces the search space and gives you a fair chance of success! Let's assume your tokens are: cats, dogs, elephants. We're gonna generate a list of all the permutations of those with a simple python script

import itertools

tokens = ["cats", "dogs", "elephants"]

results = []

for L in range(0, 6):
        for subset in itertools.permutations(tokens, L):
                results.append(subset)

with open("bruteforce-luks.txt", "w") as f:
    lines = ["".join(r) for r in results][1:]

    f.write("\n".join(lines))

Here is how this file looks like

$ python bruteforce-luks.py
$ head bruteforce-luks.txt 
cats
dogs
elephants
catsdogs
catselephants
dogscats
dogselephants
elephantscats
elephantsdogs
catsdogselephants

With that list of possible passwords you can then 

sudo bruteforce-luks -t 6 -f bruteforce-luks.txt /dev/sdc1

-f passes the file list, -t tell how many CPU threads to use. The device /dev/sdc1 maybe different in your case. To check progress of this brute-force scan use

pkill -USR1 -f bruteforce-luks

Epilog

While I ultimately failed to recover the hard-drive, I hope this guide will help some people get out a little disaster like that.