Taking on a student challenge, creating a linux password cracker with built-in python modules!
import string # Provides Easy Access to Character Sets import random # Used for Picking Characters out of a list or string import time # Used to time how long the password cracking functions are taking import subprocess # Used to send commands to the underlying shell import crypt # Used to generate Sha512 hash for Linux password cracking import itertools # Used to Calculate Permutations try:from IPython.display import clear_output # Used make time updates dynamic without scrolling except:pass # Module Not a Hard Requeirment
char_set = string.ascii_letters + string.digits + '!@#$%^&*()'
print('char_set =', char_set)
char_set = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()
print(len(char_set))
72
def gen_password(length, char_set=None): if char_set == None: char_set = string.ascii_letters + string.digits + '!@#$%^&*()' password = '' for i in range(length): x = random.choice(char_set) password = password + x return password
my_pass = gen_password(8) print(f'Generated password = {my_pass}') print(f'Generated password = {gen_password(8)}') print(f'Generated password = {gen_password(8)}')
Generated password = PY5GDlsT
Generated password = OO#EM@lT
Generated password = L474abUC
password_to_crack = '4721'
count = 1 start_time = time.time() show = False while True: attempt = gen_password(len(password_to_crack), string.digits) if attempt == password_to_crack: print(f'Cracked Password "{attempt}" on Try {count:,} and took {time.time()-start_time:.4f} seconds') break else: pass try: if show: clear_output(wait=True) print(f'Guess = {attempt} Attempt Number = {count:,} Time Taken = {time.time()-start_time:.4f} seconds') except:pass count = count+1
Cracked Password "4721" on Try 6,377 and took 0.0431 seconds
Formula:
For example a 4 digit PIN:
char_set_len = 72 length = 8 print(f'Possilbe Permutations {char_set_len**length:,}')
Possilbe Permutations 722,204,136,308,736
def crack_pass(password_to_crack, start_length=1, up_to_length=12, char_set=None, show=False): if char_set == None: char_set = string.ascii_letters + string.digits + '!@#$%^&*()' print(f''' Attempting to crack password up to {up_to_length} characters long using these characters: {char_set} ''') cracked = False count = 1 start_time = time.time() for length in range(start_length, up_to_length+1): if cracked != True: print(f'\tTrying with Password Length of {length} @ {time.time()-start_time:.4f} seconds') for i in itertools.product(char_set, repeat=length): attempt = ''.join(i) if attempt == password_to_crack: print(f'\tCracked Password "{attempt}" on Try {count:,} and took {time.time()-start_time:.4f} seconds') cracked = True break else: pass if show: try: clear_output(wait=True) print(f'Guess = {attempt} Attempt Number = {count:,} Time Taken = {time.time()-start_time:.4f} seconds') except:pass count = count+1 if cracked: return 'Crack Success' else: return 'Crack Failed'
password_to_crack = 'C@t5e' # password_to_crack = 'T2' password_to_crack
'C@t5e'
crack_pass(password_to_crack, show=False)
Attempting to crack password up to 12 characters long using these characters:
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()
Trying with Password Length of 1 @ 0.0000 seconds
Trying with Password Length of 2 @ 0.0005 seconds
Trying with Password Length of 3 @ 0.0044 seconds
Trying with Password Length of 4 @ 0.1146 seconds
Trying with Password Length of 5 @ 6.3737 seconds
Cracked Password "C@t5e" on Try 803,337,557 and took 199.8704 seconds
'Crack Success'
sudo useradd testuser
sudo passwd testuser
def find_user(user): '''Find a user in /etc/shadow and return the salt and the hash''' try: output = subprocess.run('sudo cat /etc/shadow'.split(), capture_output=True) for line in output.stdout.decode().split('\n'): if user in line: print(f'-> Found User "{user}"') print(line) break salt = line.split(':')[1].split('$')[2] hashed = line.split(':')[1].split('$')[3] #print('\n',salt, hashed) return salt,hashed except: print(f'Could not find user {user} in /etc/shadow') return None,None
def gen_hash_sha512(password, salt): '''Generate our Hash Output for Password with given Salt''' sha512_hash = crypt.crypt(password, f'$6${salt}') return sha512_hash
def crack_hashed_pass(password_hash, salt, up_to_length=13, char_set=None, show=False): if char_set == None: char_set = string.ascii_letters + string.digits + '!@#$%^&*()' print(f''' Attempting to crack password up to {up_to_length} characters long using these charecters: {char_set} ''') cracked = False count = 1 start_time = time.time() for length in range(up_to_length): if cracked != True: print(f'\tTrying with Password Length of {length} @ {time.time()-start_time:.4f} seconds') for i in itertools.product(char_set, repeat=length): attempt = ''.join(i) # Pass Attempt to gen_hash_sha512 function hashed_attempt = gen_hash_sha512(attempt, salt) if show: clear_output(wait=True) print(f'Input Salt = {salt}') print(f'Input Hash = {password_hash}') print(f'Guess = {attempt} Attempt Number = {count:,} Time Taken = {time.time()-start_time:.4f} seconds') print(f'Guess Hash = {hashed_attempt}') if hashed_attempt == password_hash: print(f'\tCracked Password "{attempt}" on Try {count:,} and took {time.time()-start_time:.4f} seconds') cracked = True break count = count+1 if cracked: return ('Crack Success', attempt) else: return 'Crack Failed'
def crack_linux_password(username, show=False): # Find Encrypted Password Line in /etc/shadow salt, hashed = find_user(username) if salt == None:return complete = f'$6${salt}${hashed}' print(f'\nSalt = {salt}\nHash = {hashed}') # Pass Salt and Hashed Password into crack_hashed_pass function result = crack_hashed_pass(complete, salt, up_to_length=13, char_set=None, show=show) return result
crack_linux_password('testuser', show=False)
-> Found User "testuser"
testuser:$6$1dNTqlbUe9LEUoys$G9cOXl6lmtllKjSyQZDM12ftHWiSdiBsIuEv3aMN2akBALB16CxHVZoytT7EUBsBZjK8b81EFJ693s7geISts/:18962:0:99999:7:::
Salt = 1dNTqlbUe9LEUoys
Hash = G9cOXl6lmtllKjSyQZDM12ftHWiSdiBsIuEv3aMN2akBALB16CxHVZoytT7EUBsBZjK8b81EFJ693s7geISts/
Attempting to crack password up to 13 characters long using these charecters:
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()
Trying with Password Length of 0 @ 0.0000 seconds
Trying with Password Length of 1 @ 0.0035 seconds
Trying with Password Length of 2 @ 0.2601 seconds
Trying with Password Length of 3 @ 16.1270 seconds
Trying with Password Length of 4 @ 1186.9620 seconds
Cracked Password "aP3x" on Try 595,033 and took 1865.6601 seconds
('Crack Success', 'aP3x')
sudo userdel testuser