Description
Someone encrypted a message using AES in ECB mode but they weren't very careful with their key. Turns out it's derived from something as simple as the current time! Download the encrypted message: message.txt and the encryption script: encryption.py .
Setup
Download message.txt and encryption.py.
Read encryption.py to understand exactly how the key is derived from the timestamp.
cat encryption.py
cat message.txt
Solution
- Step 1Understand the key derivationThe AES key is SHA-256(unix_timestamp), where the timestamp is the integer number of seconds since the Unix epoch at encryption time. The ciphertext in message.txt has a timestamp embedded or is from a known time window.
- Step 2Determine the encryption time windowCheck message.txt for any timestamps or metadata. The encryption happened around the time the challenge was released. Narrow the search window to a few hours or days around the challenge start date.
- Step 3Brute-force the timestampTry all Unix timestamps in the target window, derive the AES key as SHA-256(timestamp), and attempt to decrypt. Check if the result starts with 'picoCTF{'.python3 << 'EOF' import hashlib from Crypto.Cipher import AES from Crypto.Util.Padding import unpad ct = bytes.fromhex(open("message.txt").read().strip()) # The server provides a timestamp hint -- search ±1000 seconds around it hint_ts = YOUR_HINT_TIMESTAMP # read from the challenge instance start = hint_ts - 1000 end = hint_ts + 1000 for ts in range(start, end): key = hashlib.sha256(str(ts).encode()).digest()[:16] try: cipher = AES.new(key, AES.MODE_ECB) pt = unpad(cipher.decrypt(ct), 16) if b"picoCTF{" in pt: print(f"Timestamp: {ts}") print(pt) break except Exception: pass EOF
Flag
picoCTF{t1m3st4mp_k3y_...}
Deriving an AES key from the current Unix timestamp creates only ~86400 candidates per day -- trivially brute-forceable.