UofTCTF'24: repeat
This was a standard XOR challenge, where we are given the ciphertext and the encryption algorithm. We then need to get the plaintext, i.e. the flag.
The Challenge
I'm a known repeat offender when it comes to bad encryption habits. But the secrets module is secure, so you'll never be able to guess my key!
We are given two files: gen.py
and flag.enc
.
gen.py
:
import os
import secrets
flag = "REDACATED"
xor_key = secrets.token_bytes(8)
def xor(message, key):
return bytes([message[i] ^ key[i % len(key)] for i in range(len(message))])
encrypted_flag = xor(flag.encode(), xor_key).hex()
with open("flag.enc", "w") as f:
f.write("Flag: "+encrypted_flag)
flag.enc
:
Flag: 982a9290d6d4bf88957586bbdcda8681de33c796c691bb9fde1a83d582c886988375838aead0e8c7dc2bc3d7cd97a4
The Analysis
We know a few things:
- The flag is encrypted using XOR.
- XOR can be reversed by XORing the ciphertext with the key to get the plaintext.
- The key is a random 8-byte string.
- The flag likely starts with
uoftctf{
.
The Solution
To solve this challenge, we need to:
- Get the key.
Knowing that the starting plaintext of the flag, and that the key is 8 bytes long, we can get all 8 bytes of the key by XORing the first 8 bytes of the ciphertext with
uoftctf{
. - Decrypt the ciphertext.
With the key, we can XOR the ciphertext with the key to get the plaintext.
To simplify the process, I wrote a python script to do the above steps.
def xor_key(known, encrypted_part):
return bytes([known[i] ^ encrypted_part[i] for i in range(len(known))])
def decrypt(cipher, xor_key):
encrypted_bytes = bytes.fromhex(cipher)
decrypted_bytes = bytes([encrypted_bytes[i] ^ xor_key[i % len(xor_key)] for i in range(len(encrypted_bytes))])
return decrypted_bytes.decode()
known = "uoftctf{"
with open("flag.enc", "r") as f:
cipher = f.read().split(" ")[1]
key_length = len(known)
known_encrypted_part = cipher[:key_length * 2]
xor_key = xor_key(known.encode(), bytes.fromhex(known_encrypted_part))
pt = decrypt(cipher, xor_key)
print(pt)
While not the most elegant solution, it can nicely solve the challenge.
uoftctf{x0r_iz_r3v3rs1bl3_w17h_kn0wn_p141n73x7}