tyrel.cloud


All posts tagged:


Cracking a Linux Password!

Updated by Tyrel on 2021-12-01

Summary

Taking on a student challenge, creating a linux password cracker with built-in python modules!

T2

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

Password Generator

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/PIN Cracker

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

Calculating Permutations with Repetition

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

Sequential Cracking Method

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'

Cracking a Linux Password

Add a User and Change their Password

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')

Delete the user when finished

sudo userdel testuser


Feel like I missed something? Let me know in the comments!