Want to code faster? Our Python Code Generator lets you create Python scripts with just a few clicks. Try it now!
Cryptographic hashes are a fundamental part of modern cybersecurity. They are used to securely store and verify data, especially passwords. However, understanding how they can be compromised is also essential for protecting systems.
In this tutorial, we'll explore a simple Python script that demonstrates a brute-force approach to cracking cryptographic hashes with a wordlist using the hashlib library in Python. The technique tries all possible words from a list to find the original input that produced the hash.
Please note that this tutorial is for educational purposes only and should not be used for malicious activities. Understanding these concepts is crucial for building secure systems, but misuse of this information can lead to legal consequences.
Build 39 Ethical Hacking Scripts & Tools with Python EBook
To get started, let's install the tqdm
library for showing progress bars:
$ pip install tqdm
Open up a new Python file named crack_hashes.py
for instance, and add the following:
import hashlib
from tqdm import tqdm
# List of supported hash types
hash_names = [
'blake2b',
'blake2s',
'md5',
'sha1',
'sha224',
'sha256',
'sha384',
'sha3_224',
'sha3_256',
'sha3_384',
'sha3_512',
'sha512',
]
We defined a list of hashing algorithms that are supported by hashlib
. Now let's make the cracking function:
def crack_hash(hash, wordlist, hash_type=None):
"""Crack a hash using a wordlist.
Args:
hash (str): The hash to crack.
wordlist (str): The path to the wordlist.
Returns:
str: The cracked hash."""
hash_fn = getattr(hashlib, hash_type, None)
if hash_fn is None or hash_type not in hash_names:
# not supported hash type
raise ValueError(f'[!] Invalid hash type: {hash_type}, supported are {hash_names}')
# Count the number of lines in the wordlist to set the total
total_lines = sum(1 for line in open(wordlist, 'r'))
print(f"[*] Cracking hash {hash} using {hash_type} with a list of {total_lines} words.")
# open the wordlist
with open(wordlist, 'r') as f:
# iterate over each line
for line in tqdm(f, desc='Cracking hash', total=total_lines):
if hash_fn(line.strip().encode()).hexdigest() == hash:
return line
The above function takes three parameters: The actual target hash
to crack, the wordlist
filename, and the hash type (whether it's MD5, SHA-1, SHA256, etc.):
hash_type
is supported by hashlib
and within our list. If it is supported, then hash_fn
will contain the hashing function. If not, we simply raise a ValueError
indicating that the hash type is invalid.total_lines
variable so we can pass it to the total
parameter in tqdm()
.tqdm
for printing the progress bar), and hash each line to compare it with the target hash. If it's equal, we return that word (and so we have found the password).Master Ethical Hacking with Python by building 35+ Tools from scratch. Get your copy now!
Download EBookNow that we have the responsible function, let's use argparse
to parse the command-line arguments passed by the user:
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description='Crack a hash using a wordlist.')
parser.add_argument('hash', help='The hash to crack.')
parser.add_argument('wordlist', help='The path to the wordlist.')
parser.add_argument('--hash-type', help='The hash type to use.', default='md5')
args = parser.parse_args()
print()
print("[+] Found password:", crack_hash(args.hash, args.wordlist, args.hash_type))
So hash
and wordlist
are required parameters, and --hash-type
is set to MD5 by default (if nothing is passed).
Before we run the script, let's make up a target hash to crack. I'm doing that in an interactive Python shell:
>>> import hashlib
>>> hashlib.sha256(b"abc123")
<sha256 _hashlib.HASH object @ 0x00000123B881FF50>
>>> hashlib.sha256(b"abc123").hexdigest()
'6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090'
>>> exit()
The hashing function returns a hash object, so we need to call hexdigest()
function to get it as str
.
I'm also using the RockYou wordlist (about 135MB) which contains more than 14 million passwords, I've also moved my toy abc123
password to the end of the file. You can use any wordlist you want.
Let's run the script now:
$ python crack_hashes.py 6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090 rockyou.txt --hash-type sha256
[*] Cracking hash 6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090 using sha256 with a list of 14344394 words.
Cracking hash: 96%|███████████████████████████████████████████████████████████████████████████████████████████▉ | 13735317/14344394 [00:20<00:00, 664400.58it/s]
[+] Found password: abc123
Notice I passed the hash first, then the wordlist name, then the hash type. Amazing! It took about 20 seconds to run through the RockYou password list and finally found it! The speed is quite impressive (about ~660,000 iterations per second) given that it's Python and only one laptop CPU core.
For more information about hashes, I suggest you check this tutorial of ours.
Alright, we're done with this quick tutorial, where we provided a simple and educational insight into the world of cryptographic hashes and how we can perform brute-force on them. While this is a basic example, it is a good starting point for understanding the principles of hashing and security.
Finally, in our Ethical Hacking with Python EBook, we've built more than 39 hacking tools and scripts from scratch using Python! Check it out here if you're interested! Also, if you're more into cryptography, we have a detailed eBook about that as well; check it out here.
Learn also: How to Use Hashing Algorithms in Python
Happy coding ♥
Finished reading? Keep the learning going with our AI-powered Code Explainer. Try it now!
View Full Code Explain My Code
Got a coding query or need some guidance before you comment? Check out this Python Code Assistant for expert advice and handy tips. It's like having a coding tutor right in your fingertips!