skip.link.title

How to Hack a Password in Python?

  • You can find the source code for this video in my GitHub Repo

Create Python Script to Hack Passwords

In this video, I'll show you a few techniques to crack passwords using Python. There are a lot of tools out there that can help you to decrypt passwords, such as Hydra, John The Ripper, and many others. We will build a simple python script that will help you understand how those more complicated tools work.

  • Let's get started. First, create a hack_password.py file. Through the video, I will copy-paste some code between files just to make it easier to follow.
hack_password.py
import hashlib
from urllib.request import urlopen


def hash(password):
    result = hashlib.sha256(password.encode())
    return result.hexdigest()


def get_wordlist(url):
    try:
        with urlopen(url) as f:
            wordlist = f.read().decode('utf-8').splitlines()
            return wordlist
    except Exception as e:
        print(f'failed to get wordlist: {e}')
        exit(1)


def bruteforce(wordlist, password):
    password_hash = hash(password)
    for guess_password in wordlist:
        if hash(guess_password) == password_hash:
            return guess_password


if __name__ == '__main__':
    WORDLIST_URL = 'https://raw.githubusercontent.com/berzerk0/Probable-Wordlists/2df55facf06c7742f2038a8f6607ea9071596128/Real-Passwords/Top1575-probable-v2.txt'
    MY_PASSWORD = '123123'

    wordlist = get_wordlist(WORDLIST_URL)
    print(f'wordlist contains {len(wordlist)} items')

    password = bruteforce(wordlist, MY_PASSWORD)
    if password is not None:
        print('your password is:', password)
    else:
        print('your password is not in the wordlist')
  • Since we don't rely on any third-party modules, we don't need to create a virtual environment and install those libraries. We can execute the script right away.
    python3 hack_password.py
    

Crack Passwords in Database

  • Let's create a database.csv file that represents the hacked database with users.
database.csv
id,username,password
1,wormweighty,misty1239
2,burlydefeated,banking876
3,ripefuturistic,ddddrrrr
4,angel,qwerty123
5,wightsquare,macleod8756
6,rampallianimpure,sandals123
7,neckedlewd,request345
8,sculliangusty,$gdGD90
9,anton,123123
10,villainmacho,g672fd
  • Create a new file and call it hack_database.py
hack_database.py
import csv
import hashlib
from urllib.request import urlopen


def hash(password):
    result = hashlib.sha256(password.encode())
    return result.hexdigest()


def get_wordlist(url):
    try:
        with urlopen(url) as f:
            wordlist = f.read().decode('utf-8').splitlines()
            return wordlist
    except Exception as e:
        print(f'failed to get wordlist: {e}')
        exit(1)


def get_users(path):
    try:
        result = []
        with open(path) as f:
            reader = csv.DictReader(f, delimiter=',')
            for row in reader:
                result.append(dict(row))
            return result
    except Exception as e:
        print(f'failed to get users: {e}')
        exit(1)


def bruteforce(wordlist, password):
    password_hash = hash(password)
    for guess_password in wordlist:
        if hash(guess_password) == password_hash:
            return guess_password


if __name__ == '__main__':
    WORDLIST_URL = 'https://raw.githubusercontent.com/berzerk0/Probable-Wordlists/2df55facf06c7742f2038a8f6607ea9071596128/Real-Passwords/Top12Thousand-probable-v2.txt'
    DATABASE_PATH = 'database.csv'

    wordlist = get_wordlist(WORDLIST_URL)
    print(f'wordlist contains {len(wordlist)} items')

    users = get_users(DATABASE_PATH)
    for user in users:
        password = bruteforce(wordlist, user['password'])
        if password is not None:
            print(f'username: {user["username"]}, password: {password}')
  • Run the script
    python3 hack_database.py
    

Crack Passwords using Rainbow Table

To improve our script, we can use rainbow tables. A rainbow table is a database that is used to gain authentication by cracking the password hash. It is a precomputed dictionary of plaintext passwords and their corresponding hash values that can be used to find out what plaintext password produces a particular hash.

  • Create a script to create a rainbow table out of wordlist, which we usually use.
create_rainbow_table.py
import csv
import hashlib
from urllib.request import urlopen


def get_wordlist(url):
    try:
        with urlopen(url) as f:
            wordlist = f.read().decode('utf-8').splitlines()
            return wordlist
    except Exception as e:
        print(f'failed to get wordlist: {e}')
        exit(1)


def hash(password):
    result = hashlib.sha256(password.encode())
    return result.hexdigest()


def create_rainbow_table(wordlist_url, rainbow_table_path):
    wordlist = get_wordlist(wordlist_url)
    try:
        with open(rainbow_table_path, 'w') as f:
            writer = csv.writer(f, delimiter=',')
            writer.writerow(['password', 'hash'])
            for word in wordlist:
                writer.writerow([word, hash(word)])

    except Exception as e:
        print(f'failed to create rainbow table: {e}')
        exit(1)


if __name__ == '__main__':
    WORDLIST_URL = 'https://raw.githubusercontent.com/berzerk0/Probable-Wordlists/2df55facf06c7742f2038a8f6607ea9071596128/Real-Passwords/Top1575-probable-v2.txt'
    RAINBOW_TABLE_PATH = 'rainbow_table.csv'

    create_rainbow_table(WORDLIST_URL, RAINBOW_TABLE_PATH)
  • Let's create our last script, hack_database_v2.py. This script is no exception. We will reuse a lot of methods from previous examples.
hack_database_v2.py
import csv
import hashlib
from urllib.request import urlopen


def hash(password):
    result = hashlib.sha256(password.encode())
    return result.hexdigest()


def get_wordlist(url):
    try:
        with urlopen(url) as f:
            wordlist = f.read().decode('utf-8').splitlines()
            return wordlist
    except Exception as e:
        print(f'failed to get wordlist: {e}')
        exit(1)


def get_users(path):
    try:
        result = []
        with open(path) as f:
            reader = csv.DictReader(f, delimiter=',')
            for row in reader:
                result.append(dict(row))
            return result
    except Exception as e:
        print(f'failed to get users: {e}')
        exit(1)


def get_rainbow_table(path):
    try:
        result = []
        with open(path) as f:
            reader = csv.DictReader(f, delimiter=',')
            for row in reader:
                result.append(dict(row))
            return result
    except Exception as e:
        print(f'failed to get rainbow table: {e}')
        exit(1)


def match_hash(users, rainbow_table):
    for user in users:
        password_hash = hash(user['password'])
        for row in rainbow_table:
            if password_hash == row['hash']:
                print(
                    f'username: {user["username"]}, password {row["password"]}')


if __name__ == '__main__':
    WORDLIST_URL = 'https://raw.githubusercontent.com/berzerk0/Probable-Wordlists/2df55facf06c7742f2038a8f6607ea9071596128/Real-Passwords/Top12Thousand-probable-v2.txt'
    DATABASE_PATH = 'database.csv'
    RAINBOW_TABLE_PATH = 'rainbow_table.csv'

    users = get_users(DATABASE_PATH)
    rainbow_table = get_rainbow_table(RAINBOW_TABLE_PATH)
    match_hash(users, rainbow_table)
  • Run the script

    python3 hack_database_v2.py
    

  • These days, more and more systems use proper password storage algorithms such as Bcrypt, Scrypt, or Argon2. Those algorithms are no longer "vulnerable" to rainbow tables: since each hash is unique, even if the passwords are equal, rainbow tables no longer work. That's why rainbow tables are unpopular today.

top.title