Skip to content

Forgotten LUKS passphrase?

mittman edited this page Sep 25, 2018 · 1 revision

Encrypted drives are great until they are not. How to recover when something goes wrong?

note: I've painfully gone through each of these scenarios with different drives; remember to backup your data and also to backup your backups (copy the LUKS header, master key and passphrase)

Scenario A - have dump of master key (and LUKS header intact)

$ sudo cryptsetup --dump-master-key luksDump /dev/sdX

WARNING!
========
Header dump with volume key is sensitive information
which allows access to encrypted partition without passphrase.
This dump should be always stored encrypted on safe place.

Are you sure? (Type uppercase yes): LUKS header information for /dev/sdX
Cipher name:   	aes
Cipher mode:   	xts-plain64
Payload offset:	4096
UUID:          	50930e91-42fd-4a8b-8381-bb00163ec899
MK bits:       	256
MK dump:	e3 b0 c4 42 98 fc 1c 14 9a fb f4 c8 99 6f b9 24 
		27 ae 41 e4 64 9b 93 4c a4 95 99 1b 78 52 b8 55

note: This information should be stored somewhere safe

First verify the UUID above matches the drive you are attempting to unlock

$ sudo blkid /dev/sdX
/dev/sdX: UUID="50930e91-42fd-4a8b-8381-bb00163ec899" TYPE="crypto_LUKS"

The master key is a randomly generated sha256 hash, the MK dump value (without the spaces). Convert it to a binary file and use that to unlock and mount the drive.

$ echo "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" > key.txt
$ xxd -r -p key.txt key.bin
$ sudo cryptsetup --master-key-file key.bin luksOpen /dev/sdX foobar
$ sudo mount /dev/mapper/foobar /mnt/

Scenario B - partial passphrase (and LUKS header intact)

Assuming you have some idea of the passphrase, for example the words but not the order or case-sensitivity.

dict.txt

Lorem
LOREM
lorem
Ipsum
IPSUM
ipsum
Foobar
FOOBAR
foobar
1234
000
[...]
dvorak

Sample python code to generate permutations

#!/usr/bin/env python2
import itertools

with open("dict.txt") as f:
	content = f.readlines()
	content = [x.strip() for x in content]

	res = itertools.permutations(content, 2)
	for i in res: 
		print ''.join(i)

Save output

permutations.txt

LoremLOREM
Loremlorem
LoremIpsum
LoremIPSUM
Loremipsum
LoremFoobar
LoremFOOBAR
Loremfoobar
Lorem1234
Lorem000
LOREMLorem
LOREMlorem
LOREMIpsum
LOREMIPSUM
[...]
000ipsum
000Foobar
000FOOBAR
000foobar
0001234
[...]
dvorakDVORAK

Save off the header (first 2MB) and store somewhere safe

$ sudo dd if=/dev/sdX of=$HOME/sdX.luks bs=512 count=4097

note: if header is corrupted you will not be able to access the drive without a backup.

LUKS is designed to be slow to bruteforce, so let's try GPU acceleration with hashcat

$ hashcat -m 14600 -a 0 -w 3 ~/sdX.luks permutations.txt -o pass.txt
hashcat (v4.2.1) starting...

* Device #1: This hardware has outdated CUDA compute capability.

OpenCL Platform #1: NVIDIA Corporation
======================================
* Device #1: GeForce GTX ###, 499/1998 MB allocatable, 2MCU

Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1

Applicable optimizers:
* Zero-Byte
* Single-Hash
* Single-Salt
* Slow-Hash-SIMD-LOOP

Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 256

Watchdog: Temperature abort trigger set to 90c

Dictionary cache hit:
* Filename..: permutations.txt
* Passwords.: 812
* Bytes.....: 10112
* Keyspace..: 812

The wordlist or mask that you are using is too small.
This means that hashcat cannot use the full parallel power of your device(s).
Unless you supply more work, your cracking speed will drop.
For tips on supplying more work, see: https://hashcat.net/faq/morework

Approaching final keyspace - workload adjusted.  

Cracking performance lower than expected?        

* Update your OpenCL runtime / driver the right way:
  https://hashcat.net/faq/wrongdriver

  * Create more work items to make use of your parallelization power:
https://hashcat.net/faq/morework

[s]tatus [p]ause [b]ypass [c]heckpoint [q]uit => s

Session..........: hashcat
Status...........: Running
Hash.Type........: LUKS
Hash.Target......: ~/sdX.luks
Time.Started.....: Sun Sep 25 09:46:13 2018 (13 secs)
Time.Estimated...: Sun Sep 25 09:47:49 2018 (1 min, 23 secs)
Guess.Base.......: File (permutations.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.Dev.#1.....:       10 H/s (10.24ms) @ Accel:2 Loops:256 Thr:1024 Vec:1
Recovered........: 0/1 (0.00%) Digests, 0/1 (0.00%) Salts
Progress.........: 0/812 (0.00%)
Rejected.........: 0/0 (0.00%)
Restore.Point....: 0/812 (0.00%)
Candidates.#1....: LoremLOREM -> dvorakDVORAK
HWMon.Dev.#1.....: Temp: 41c Fan: 40%

Session..........: hashcat
Status...........: Cracked
Hash.Type........: LUKS
Hash.Target......: ~/sdX.luks
Time.Started.....: Sun Sep 25 09:46:13 2018 (1 min, 23 secs)
Time.Estimated...: Sun Sep 25 09:47:36 2018 (0 secs)
Guess.Base.......: File (permutations.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.Dev.#1.....:       10 H/s (10.18ms) @ Accel:2 Loops:256 Thr:1024 Vec:1
Recovered........: 1/1 (100.00%) Digests, 1/1 (100.00%) Salts
Progress.........: 812/812 (100.00%)
Rejected.........: 0/812 (0.00%)
Restore.Point....: 0/812 (0.00%)
Candidates.#1....: LoremLOREM -> dvorakDVORAK
HWMon.Dev.#1.....: Temp: 46c Fan: 40%

Started: Sun Sep 25 09:45:57 2018
Stopped: Sun Sep 25 09:47:37 2018

Lucky for us, the passphrase was one of the permutations. Status is cracked, check the output file:

$ cat pass.txt
FOOipsum

Mount as usual

$ sudo cryptsetup luksOpen /dev/sdX foobar
$ mount /dev/mapper/foobar /mnt/

Scenario C - corrupt LUKS header (no backup)

Power outage and the known passphrase no longer works. If no backup for the drive header (first 2MB), now have a paperweight.