$ cat writeup.md…
$ cat writeup.md…
hackthebox
Task: ChaCha20 stream cipher encrypts a known message and a flag using the same key and nonce. Solution: Recover keystream by XORing known plaintext with its ciphertext, then decrypt the flag.
$ cat /etc/rate-limit
Rate limit reached (20 reads/hour per IP). Showing preview only — full content returns at the next hour roll-over.
The challenge provides a Python script that encrypts a known message and a secret flag using the ChaCha20 stream cipher. Both encryptions use the same key and the same nonce.
ChaCha20 is a stream cipher. It generates a keystream based on a key and a nonce. The ciphertext is produced by XORing the plaintext with this keystream:
C = P ⊕ KS
If the same key and nonce are used to encrypt two different messages ($P_1$ and $P_2$), the same keystream ($KS$) is generated for both:
Since we know $P_1$ (the known message) and $C_1$ (its ciphertext), we can recover the keystream: $KS = C_1 ⊕ P_1$
Once we have the keystream, we can decrypt the flag ($P_2$) using its ciphertext ($C_2$): $P_2 = C_2 ⊕ KS$
from Crypto.Cipher import ChaCha20 from secret import FLAG import os def encryptMessage(message, key, nonce): cipher = ChaCha20.new(key=key, nonce=iv) ciphertext = cipher.encrypt(message) return ciphertext if __name__ == "__main__": message = b"Our counter agencies have intercepted your messages and a lot " message += b"of your agent's identities have been exposed. In a matter of " message += b"days all of them will be captured" key, iv = os.urandom(32), os.urandom(12) encrypted_message = encryptMessage(message, key, iv) encrypted_flag = encryptMessage(FLAG, key, iv) data = iv.hex() + "\n" + encrypted_message.hex() + "\n" + encrypted_flag.hex() # ... write to out.txt
#!/usr/bin/env python3 def xor(a, b): return bytes([x ^ y for x, y in zip(a, b)]) ...
$ grep --similar