Description
A monoalphabetic cipher includes its key at the top of the file. Once you map each ciphertext letter back through the key, the hidden flag drops out immediately.
Setup
Open the file; its first line contains the substitution key (e.g., ZGSOCXPQUYHMILERVTBWNAFJDK).
Extract the ciphertext (the characters between `picoCTF{` and the closing brace) and run a simple script to map each letter back to the plain alphabet.
python3 - <<'PY'
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
key = "ZGSOCXPQUYHMILERVTBWNAFJDK"
enc = "5NG5717N710L_3A0MN710L_357GX9XX"
flag = "picoCTF{" + ''.join(alphabet[key.index(c)] if c.isalpha() else c for c in enc) + "}"
print(flag)
PYSolution
- Step 1Derive the mappingBecause the key lists ciphertext letters in order of plaintext A-Z, you simply look up each encrypted character's index in the key and pull the corresponding letter from the alphabet.
Learn more
A monoalphabetic substitution cipher replaces each letter with a fixed substitute throughout the entire message. The key is a permutation of the alphabet - a mapping from each plaintext letter to a unique ciphertext letter. With 26 letters, there are 26! (about 4 × 10^26) possible keys, making brute force impractical.
However, monoalphabetic ciphers are completely broken by frequency analysis: in English, "E" appears roughly 12.7% of the time, "T" at 9.1%, "A" at 8.2%, etc. By counting letter frequencies in the ciphertext and matching them to known English frequencies, an attacker can recover the key without knowing it. This attack was described by Al-Kindi in the 9th century - making monoalphabetic ciphers over 1000 years old and broken. Our Frequency Analysis tool automates this: paste the ciphertext and it builds an interactive decryption mapping ranked by frequency.
In this specific challenge, the key is provided in the file, so no analysis is needed - it's purely an exercise in applying the mapping. The Python one-liner uses
key.index(c)to find where ciphertext lettercappears in the key (which corresponds to its plaintext position), then maps it back to the correct alphabet letter. - Step 2Assemble the flagHandle underscores/digits literally, wrap the decoded string with picoCTF{...}, and you have the final flag.
Learn more
The substitution cipher only affects alphabetic characters - digits, underscores, spaces, and punctuation pass through unchanged. This is a deliberate design choice in classical ciphers (and in the picoCTF flag format, where
_and digits are common).The Python approach (
alphabet[key.index(c)] if c.isalpha() else c) cleanly handles this: for alphabetic characters, perform the reverse substitution; for everything else, output the character as-is. This is the standard pattern for implementing classical cipher decoders.Historical context: the Caesar cipher is a special case of monoalphabetic substitution where the key is a rotation of the alphabet (ROT-13 is Caesar with a shift of 13). The Vigenère cipher extends this to use different substitutions at different positions, making frequency analysis harder but not impossible via Kasiski examination and index of coincidence analysis.
Alternate Solution
The provided substitution key maps directly to a standard alphabet - apply the mapping by hand or paste the ciphertext into the Frequency Analysis tool to quickly confirm which letters substitute for which. Since the key is given, this is more of a manual mapping exercise than a full cryptanalysis.
Flag
picoCTF{5UB5717U710N_3V0LU710N_357...}
This challenge is intentionally straightforward, so no frequency analysis is required once the key is provided.