Bruteforcing an encrypted APFS drive

March 21, 2020

This week I did something embarrassing. I forgot the password of one of my external USB-drives.

Normally I save passwords like these in one of my password-managers, but not for this particular drive. Not all passwords belong in a password-manager, and this is was one of them.

However, I did have some idea of what the password was, and I was able to narrow it down to a few hundred thousand alternatives. So, I figured I should be able to just bruteforce the disk open.

Using some simple scripting, I made a list of all the alternatives. I will leave this job to you, my dear reader. Since creating the list of different passwords to try is actually the most difficult part of bruteforcing anything, I’m afraid this tiny blogpost isn’t extremely helpful. But, I will show you how use your list to run through the different passwords.

This is on macOS Catalina (10.15.3).

Once you have a list of different passwords to try, save it as list.txt. Then save the script below as mount.sh.

#!/usr/bin/env bash

while read -r line
do
  echo $line | tee -a used.txt | diskutil apfs UnlockVolume $1 -stdinpassphrase && break
done < list.txt

Give the script executable permissions by running chmod +x mount.sh. Now you just need to find the device of your external drive, and then we can run the script.

You can find the device in Disk Utility (just select your drive, and check out the device name in the information box. Or, you can click the information-button in the top right corner, and use the “BSD device node”. Alternatively, you can run diskutil apfs list, and find your device in that list.

Once you have the device name, you can run your script using ./mount.sh device-name. For me, I just ran ./mount.sh disk3s1.

The script will run through your list of passwords line by line, and try each password. Before it tries a password, it will output it to a file named used.txt. When it finds a password that works, the script will abort. The password that works for your drive will then be the last password that was output to used.txt.

It is not a particularly fast process. I was able to try around 2000 passwords every hour, so it took me a few days to find the right one. But I did manage to find the right one!