HackTheBox SPG Challenge
https://app.hackthebox.com/challenges/619
Description
After successfully joining the academy, there is a process where you have to log in to eclass in order to access notes in each class and get the current updates for the ongoing prank labs. When you attempt to log in, though, your browser crashes, and all your files get encrypted. This is yet another prank for the newcomers. The only thing provided is the password generator script. Can you crack it, unlock your files, and log in to the spooky platform?
Source
output.txt
Your Password : t*!zGnf#LKO~drVQc@n%oFFZyvhvGZq8zbfXKvE1#*R%uh*$M6c$zrxWedrAENFJB7xz0ps4zh94EwZOnVT9&h
Encrypted Flag : GKLlVVw9uz/QzqKiBPAvdLA+QyRqyctsPJ/tx8Ac2hIUl8/kJaEvHthHUuwFDRCs
server.py
from hashlib import sha256
import string, random
from secret import MASTER_KEY, FLAG
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from base64 import b64encode
ALPHABET = string.ascii_letters + string.digits + '~!@#$%^&*'
def generate_password():
master_key = int.from_bytes(MASTER_KEY, 'little')
password = ''
while master_key:
bit = master_key & 1
if bit:
password += random.choice(ALPHABET[:len(ALPHABET)//2])
else:
password += random.choice(ALPHABET[len(ALPHABET)//2:])
master_key >>= 1
return password
def main():
password = generate_password()
encryption_key = sha256(MASTER_KEY).digest()
cipher = AES.new(encryption_key, AES.MODE_ECB)
ciphertext = cipher.encrypt(pad(FLAG, 16))
with open('output.txt', 'w') as f:
f.write(f'Your Password : {password}\nEncrypted Flag : {b64encode(ciphertext).decode()}')
if __name__ == '__main__':
main()
Exploitation
#!/usr/bin/python3
from hashlib import sha256
from Crypto.Cipher import AES
from base64 import b64decode
import string
password = "t*!zGnf#LKO~drVQc@n%oFFZyvhvGZq8zbfXKvE1#*R%uh*$M6c$zrxWedrAENFJB7xz0ps4zh94EwZOnVT9&h"
encrypted_flag = "GKLlVVw9uz/QzqKiBPAvdLA+QyRqyctsPJ/tx8Ac2hIUl8/kJaEvHthHUuwFDRCs"
ALPHABET = string.ascii_letters + string.digits + '~!@#$%^&*'
first_half = ALPHABET[:len(ALPHABET)//2]
second_half = ALPHABET[len(ALPHABET)//2:]
master_key_bits = []
for char in password:
if char in first_half:
master_key_bits.append(1)
else:
master_key_bits.append(0)
master_key = 0
for bit in reversed(master_key_bits):
master_key = (master_key << 1) | bit
MASTER_KEY = master_key.to_bytes((master_key.bit_length() + 7) // 8, 'little')
encryption_key = sha256(MASTER_KEY).digest()
cipher = AES.new(encryption_key, AES.MODE_ECB)
ciphertext = b64decode(encrypted_flag)
flag = cipher.decrypt(ciphertext)
print(f"Recovered MASTER_KEY (hex): {MASTER_KEY.hex()}")
print(f"Flag: {flag.decode()}")
Summary
SPG: reconstruct the generator state, derive the AES material, and decrypt the final ciphertext.