Crack your mac password
2 min readMay 15, 2023
In the rare case that you have access to your Mac but forgot your password you can use this script to brute force some close combinations of the password using some heuristic character dropping and replacement using nearest keys on the keyboard.
This came in handy for me when I setup up a new Macbook but realized I mistyped my password when I created the account but was already logged in.
import getpass
import os
import subprocess
import sys
def check_password(password):
print(f'checking: {password}')
result = subprocess.run(['sudo', '-k', '-S', 'true'],
input=password.encode(), stderr=subprocess.PIPE)
if result.returncode == 0:
print("Password is correct.")
return True
else:
print("Password is incorrect.")
return False
def replace_char(original_string, index, char):
if index < len(original_string):
modified_string = original_string[:index] + char + original_string[index + 1:]
return modified_string
else:
return "Index out of range"
def get_keys_around(key):
key = key.lower()
print(f'finding nearby keys {key}')
lines = '~1234567890-=', 'qwertyuiop', 'asdfghjkl;', 'zxcvbnm,./'
line_index, index = [(i, l.find(key)) for i, l in enumerate(lines) if key in l][0]
lines = lines[line_index-1: line_index+2] if line_index else lines[0: 2]
return [
line[index + i] for line in lines for i in [-1, 0, 1]
if len(line) > index + i and line[index + i] != key and index + i >= 0]
if __name__ == "__main__":
# Replace 'username' with the actual username
basepass = getpass.getpass("Enter your best guess for the password: ")
guess_num = 0
if check_password(basepass):
sys.exit(0)
while True:
print(guess_num)
if guess_num < len(basepass):
idx = guess_num
guess_pass = basepass[:guess_num] + basepass[guess_num+1:]
if check_password(guess_pass):
break
char_to_replace = basepass[guess_num]
char_to_replace = char_to_replace.capitalize () if char_to_replace.islower() else char_to_replace.lower()
guess_pass = replace_char(basepass, idx, char_to_replace)
if not guess_pass == basepass:
if check_password(guess_pass):
break
keyz = get_keys_around(basepass[idx])
print(f'{basepass[idx]} -> {keyz}')
for k in keyz:
guess_pass = replace_char(basepass, idx, k)
if check_password(guess_pass):
sys.exit(0)
else:
break
guess_num += 1
The public github gist is here: https://gist.github.com/tadeegan/bbe5ee581ac656b8a279b7fcf8a4dd3b