13 picoCTF 2019 Solution

Published: April 2, 2026

Description

Cryptography can be easy, do you know what ROT13 is? Decrypt: cvpbPGS{abg_gbb_onq_bs_n_ceboyrz}

Solution

Want to try it yourself first?

The guided walkthrough reveals hints one step at a time.

Walk me through it
  1. Step 1
    Apply ROT13 using tr
    Observation
    I noticed the ciphertext 'cvpbPGS{abg_gbb_onq_bs_n_ceboyrz}' starts with 'cvpbPGS', which is exactly 7 characters matching 'picoCTF' shifted by 13 positions, suggesting ROT13 was used to obscure a standard picoCTF flag.
    ROT13 rotates each letter 13 positions in the alphabet. The tr command maps A-Z to N-ZA-M and a-z to n-za-m, effectively applying ROT13. Note that 'cvpbPGS' ROT13-decodes to 'picoCTF', confirming the cipher.
    bash
    echo "cvpbPGS{abg_gbb_onq_bs_n_ceboyrz}" | tr 'A-Za-z' 'N-ZA-Mn-za-m'

    Expected output

    picoCTF{not_too_bad_of_a_problem}
    What didn't work first

    Tried: Trying ROT13 with only the lowercase mapping: echo '...' | tr 'a-z' 'n-za-m'

    Omitting the uppercase range 'A-Za-z' -> 'N-ZA-Mn-za-m' leaves uppercase letters untouched, so 'PGS' stays as 'PGS' instead of becoming 'CTF'. The ciphertext mixes cases, so both ranges must be included in a single tr invocation for the flag to decode correctly.

    Tried: Trying a Caesar shift of 3 instead of 13, since Caesar's cipher used shift 3

    ROT3 on 'cvpbPGS' produces 'fyseSJV', which is not a readable flag prefix. The challenge uses shift 13 specifically because ROT13 is self-inverse on a 26-letter alphabet. Caesar shift 3 is a different cipher and produces garbage here; the giveaway is that ROT13('cvpbPGS') = 'picoCTF' perfectly, confirming 13 is the correct shift.

    Learn more

    ROT13 (Rotate by 13) is a simple letter substitution cipher that shifts every letter forward by 13 positions in the alphabet. Because the English alphabet has 26 letters, shifting by 13 twice returns the original text - making ROT13 its own inverse. You encrypt and decrypt with the exact same operation.

    The tr command (translate) is a Unix utility that replaces or deletes characters based on a mapping. The pattern 'A-Za-z' 'N-ZA-Mn-za-m' maps every uppercase letter to the one 13 positions ahead (wrapping A-M to N-Z and N-Z to A-M), and does the same for lowercase. This is far faster than writing a Python loop and works natively in any Unix shell.

    ROT13 has no cryptographic security - it was historically used in Usenet groups to hide spoilers or offensive content so readers had to opt-in to see it. In CTFs it appears frequently as a trivial obfuscation layer. Recognizing the pattern cvpbPGS as ROT13 for picoCTF is a useful reflex to develop when you see apparent nonsense text that almost has the right length for a flag.

    Related tools worth knowing: rot13 command (available on some systems), CyberChef's ROT13 operation, and the codecs module in Python (str.encode("rot_13")). Any substitution cipher with a shift of 13 on a 26-character alphabet is equivalent to ROT13.

    Caesar cipher generalization: ROT13 is a special case of the Caesar cipher, where the shift is 13. A Caesar cipher with shift N replaces each letter with the one N positions later in the alphabet (wrapping around). Julius Caesar reportedly used a shift of 3 in military communications. To brute-force a Caesar cipher, there are only 25 possible shifts to try - try all of them and pick the one that produces readable text. The tr pattern generalizes: for shift N, build the character class manually or write a short Python loop with chr((ord(c) - ord('A') + N) % 26 + ord('A')).

    Frequency analysis is the standard attack against monoalphabetic substitution ciphers (where each letter always maps to the same cipher letter, like ROT13 and Caesar). In English text, the letter E is most frequent (~13%), followed by T, A, O, I, N. By counting the frequency of each character in a ciphertext and mapping the most frequent ciphertext character to E (and working down the list), the plaintext can often be reconstructed without knowing the key. This attack is why substitution ciphers provide no modern security - even the Vigenere cipher, which was considered unbreakable for centuries, was cracked using the Kasiski test and index of coincidence.

    In CTF challenges, ROT13 is sometimes layered with other encodings to add trivial complexity: Base64-encode the string, then ROT13 the result, for example. The right approach is to recognize each layer and peel them off one at a time. CyberChef's "Magic" operation can automatically detect and chain common encodings and ciphers, which is useful when you are unsure what transformations were applied to produce the ciphertext. Developing an intuition for what encoded or obfuscated text "looks like" is a core skill that separates experienced CTF players from beginners.

Interactive tools
  • Cipher Identifier & Auto-DecoderPaste any ciphertext and the tool auto-runs every common decoder (base64, hex, Morse, ROT, Atbash, Bacon, binary, decimal, URL) and ranks the results by English-likeness.
Alternate Solution

No terminal? You can decode the ciphertext directly in your browser using the ROT Cipher tool built into this site.

Paste cvpbPGS{abg_gbb_onq_bs_n_ceboyrz} into the input, set the shift to 13, and the flag appears instantly.

Flag

Reveal flag

picoCTF{not_too_bad_of_a_problem}

ROT13 is its own inverse - applying it twice returns the original. The alphabet has 26 letters so rotating by 13 twice completes a full cycle.

Key takeaway

Monoalphabetic substitution ciphers like Caesar and ROT13 map each letter to exactly one other letter, making them trivially vulnerable to frequency analysis because the statistical distribution of the plaintext is preserved in the ciphertext. ROT13 is especially weak because the shift of 13 on a 26-letter alphabet makes encryption and decryption identical operations. Recognizing common encodings and cipher patterns, such as 'cvpbPGS' as ROT13 for 'picoCTF', is a foundational CTF skill that applies any time obfuscated or encoded text is encountered.

Related reading

Want more picoCTF 2019 writeups?

Tools used in this challenge

What to try next