As the sysadmin for your college, you're responsible for overseeing the security of all the clubs. One of the on campus organizations is a breakfast club with their own personal website that the leader assured you was "unhackable". He was so sure of this, that he sent you an example of how hashes are stored in the database, something about "changing the hash type multiple times for each password" or something like that. Can you crack the password and prove him wrong?
Initial Impressions
Looking at the txt file, we see multiple hashes with differentt formats.
Putting the first few hashes into crackstation, we get part of the flag PCTF{H@5H
Solve
To crack most of the SHA3 + BlAKE hashes, we can make use of the tool HashExploit. Seeing that the flag recovered so far is made up of printable ASCII characters, I used this wordlist to generate our rainbow table.
import os
# List of hashes to loop through
hashes = [
"d22e03747b83667e3e84c78e9fb49f7c9376334b9cb337addbdf3ff9",
"d14a329a1924592faf2d4ba6dc727d59af6afae983a0c208bf980237b63a5a6a",
"3bd4e7dcad9d3c02adfa7aa5388727d346278a9a7b007f497b48a4fa2a12b9545c820df150854a8f8c494275bd6fd941",
"2d44da53f305ab94b6365837b9803627ab098c41a6013694f9b468bccb9c13e95b3900365eb58924de7158a54467e984efcfdabdbcc9af9a940d49c51455b04c",
"5abf6b1a79dee98ea32a98195c61a667c29a3674e79c82e43f0d19b0efa4b6f7",
"7ae26253cfd42a3a090c44023c234ec63d0ffe63f8ad40b7913f3f646503b7a7cb8ac571d42a311ef71508344de72f30b57e5c100b402130060ebc947e07a59b"
]
# Generate Rainbow Table
generate_table = "py .\\HashExploit.py -f printableASCII"
os.system(generate_table)
# Define the HashExploit.py command
exploit_command = "py .\\HashExploit.py -H"
# Iterate through the list of hashes and run the command for each hash
for hash_value in hashes:
command = f"{exploit_command} {hash_value}"
print(os.system(command))
#Truncated Output
C:\Users\Admin\Downloads\HashExploit>py ./crack.py
word => " _ " hash ALGORITHM sha3_224 d22e03747b83667e3e84c78e9fb49f7c9376334b9cb337addbdf3ff9
Not Found
word => " R " hash ALGORITHM sha3_384 3bd4e7dcad9d3c02adfa7aa5388727d346278a9a7b007f497b48a4fa2a12b9545c820df150854a8f8c494275bd6fd941
word => " 0 " hash ALGORITHM sha3_512 2d44da53f305ab94b6365837b9803627ab098c41a6013694f9b468bccb9c13e95b3900365eb58924de7158a54467e984efcfdabdbcc9af9a940d49c51455b04c
word => " S " hash ALGORITHM blake2s 5abf6b1a79dee98ea32a98195c61a667c29a3674e79c82e43f0d19b0efa4b6f7
word => " } " hash ALGORITHM blake2b 7ae26253cfd42a3a090c44023c234ec63d0ffe63f8ad40b7913f3f646503b7a7cb8ac571d42a311ef71508344de72f30b57e5c100b402130060ebc947e07a59b
We were not able to get the results for the SHA3_256 hash d14a329a1924592faf2d4ba6dc727d59af6afae983a0c208bf980237b63a5a6a, but we can easily crack it using hashcat.
This combines to the partial flag, PCTF{H@5H_8R0??S} with the ? being the last two TupleHashes.
With a quick google search, we see that pycryptodome actually has an implementation of those hashes. We can use the same approach to hash each entry in the printableASCII wordlist and compare them to the hash that we want to crack, printing out the correct matches.
from Crypto.Hash import TupleHash256, TupleHash128
hash_to_crack_128 = "aed477850ed48df54054e9d3e7b8cae7e1764d949adb68fe4f24802ec464cb6c334ef97cc0453471fac5faf0118265bc9388062ccb704d5ac4010489bee201da"
hash_to_crack_256 = "a130e4df9144790d9c8824f90f4c1220a3eb5aa0cb296ab1f4f41f23f3ed0800f2ac3fad4f235a4ee601a8ca8bf0be394e06e53e2f789a6272f1bc54c4901d0c"
input_file = "./printableASCII" # Change this to the path of your input file
# Open the input and output files
with open(input_file, "r") as infile:
# Iterate through each line (character) in the input file
for line in infile:
hd = TupleHash128.new()
# Remove any leading/trailing whitespace or newline characters
line = line.strip()
# Update the hash object with the current character
hd.update(line.encode()) # Convert the character to bytes and update the hash object
if hd.hexdigest() == hash_to_crack_128 :
print("Found Match for {} : {}".format(hash_to_crack_128, line))
# Open the input and output files
with open(input_file, "r") as infile:
# Iterate through each line (character) in the input file
for line in infile:
hd = TupleHash256.new()
# Remove any leading/trailing whitespace or newline characters
line = line.strip()
# Update the hash object with the current character
hd.update(line.encode()) # Convert the character to bytes and update the hash object
if hd.hexdigest() == hash_to_crack_256 :
print("Found Match for {} : {}".format(hash_to_crack_256, line))
โโโ(kaliใฟkali)-[~/Desktop/CTF/PatriotCtf/BreakfastClub]
โโ$ python3 tuple_hashcrack.py
Found Match for aed477850ed48df54054e9d3e7b8cae7e1764d949adb68fe4f24802ec464cb6c334ef97cc0453471fac5faf0118265bc9388062ccb704d5ac4010489bee201da : W
Found Match for a130e4df9144790d9c8824f90f4c1220a3eb5aa0cb296ab1f4f41f23f3ed0800f2ac3fad4f235a4ee601a8ca8bf0be394e06e53e2f789a6272f1bc54c4901d0c : N