Six Seven
metactf
Task: a custom stream cipher XORs the flag against a deterministic keystream whose only random input is a single byte from os.urandom(1). Solution: brute-force all 256 possible seeds and select the candidate whose decryption starts with the known prefix DawgCTF{.
$ ls tags/ techniques/
Six Seven — metactf (DawgCTF SP26)
Description
I heard something about streaming before in my crypto book, idk what twitch has to do with crypto, but I decided to add my favorite brainrot to it.
Files provided:
chall.py— encryption scriptoutput.txt— ciphertext as hex
Source: https://github.com/UMBCCyberDawgs/dawgctf-sp26/tree/main/Six%20Seven
Challenge Source
from Crypto.Util.strxor import strxor from secrets import flag import os assert flag[:8] == b"DawgCTF{" def gen(start): return (((6 * 7) * (start - 6) * 7) + ((start * 6) - 7) * (start ^ 6)) % 255 def encrypt(message): start = os.urandom(1); key = start; for i in range(1, len(message)): key += gen(key[i-1]).to_bytes(1, "big") return strxor(key, message) ct = encrypt(flag) print("ct =", ct.hex())
Ciphertext (67 bytes):
9f2eadbd998e9ca1aab6bfbba9bf85afa9bf85a9bfb9a8bfaea985b3b485a3b5afa885a9aea8bfbbb785b9b3aab2bfa8a985ece3b8bcbfebe3eebbbceee9bceab9bea7
Summary
The custom stream cipher draws exactly one byte of entropy from os.urandom(1) as the seed. Every subsequent keystream byte is fully determined by the recurrence key[i] = gen(key[i-1]). Because the seed has only 256 possible values, the entire keystream has only 256 possible instantiations. We brute-force all of them and use the known plaintext prefix DawgCTF{ to recognise the correct one.
Recon
Reading chall.py:
- The function
genis the brainrot joke — it packs "six" and "seven" (6, 7, 42) into an arithmetic expression and reduces mod 255. It is deterministic. encryptseeds the key with one random byte and then chainsgento produce as many keystream bytes as the plaintext has.- The plaintext is XORed against that keystream with
strxor.
The cryptographic weakness is immediate: the random seed space is 2^8 = 256, not 2^128 or similar. No matter how complex gen looks, the total entropy of the keystream cannot exceed that of the seed.
...
Permission denied (requires auth)
Sign in to read this free writeup
This writeup is free — just sign in with GitHub to read it.
$ssh [email protected]