Skip to main content

Codebook Beginner picoMini 2022 Solution

Run a Python script that decodes the flag using a provided codebook lookup table.

Published: April 2, 2026Updated: August 13, 2026

Description

Run code.py using the codebook.txt file to get the flag.

Download both code.py and codebook.txt from the challenge page.

Place both files in the same directory before running.

Solution

Want to try it yourself first?

The guided walkthrough reveals hints one step at a time.

Walk me through it
  1. Step 1Run the script with codebook.txt present
    Observation
    The challenge gives two files, code.py and codebook.txt, and says to run one with the other. So the script reads the codebook at runtime rather than carrying the key inline.
    Execute code.py from the directory that also contains codebook.txt. The script reads the codebook, decodes the flag, and prints it automatically.
    python
    python3 code.py

    Expected output

    picoCTF{...}
    What didn't work first

    Tried: Run python3 code.py from a different directory, such as your home folder, after downloading the files to ~/Downloads.

    Python resolves open("codebook.txt") against the current working directory, not the script's location, so running from elsewhere gives a FileNotFoundError. cd into the folder holding both files first, so code.py and codebook.txt share a working directory.

    Tried: Download only code.py and try to run it without codebook.txt, assuming the script has the key embedded.

    The script has no inline fallback; it reads the codebook at runtime through open(). Without codebook.txt present, execution stops with a FileNotFoundError before any decoding runs. Download both files from the challenge page and keep them in one directory.

    Learn more

    A codebook is a lookup table that maps one set of symbols to another. In this challenge, code.py reads codebook.txt to translate encoded values back into the readable flag. This pattern mirrors historical encryption methods like one-time pads or stream ciphers, where a separate key document was required for decryption.

    The critical lesson here is about relative file paths. When Python opens a file with open("codebook.txt"), it looks in the current working directory - whichever directory your terminal session is in when you run the command, not necessarily where the script lives. Running the script from the wrong directory causes a FileNotFoundError.

    In real-world development and security contexts, this dependency between files is usually documented or handled programmatically (e.g., using os.path.dirname(__file__) to locate the codebook relative to the script). Always check whether a script expects companion files and confirm your working directory before running.

    Codebook-style ciphers have a long history in cryptography. Before modern algorithms, nations and militaries used physical codebooks where each word or phrase was assigned a numeric code group. The receiver looked up each incoming number in their copy of the same codebook to decode the message. The security of the system depended entirely on keeping the codebook secret - if an adversary captured a codebook, every past and future message encrypted with it was compromised. This is fundamentally different from modern public-key cryptography, where the algorithm is public but the key remains private.

    In this challenge, the XOR key assembled from specific positions in codebook.txt acts as a simple symmetric key: whoever has the file can decode the flag, and whoever lacks it cannot. This mirrors real-world scenarios where configuration files, key files, or credential files must accompany an application. Security misconfigurations often arise when these companion files are accidentally committed to version control, left world-readable on a server, or bundled inside a Docker image.

    When analyzing unfamiliar scripts in CTF or malware research, a useful first step is to scan for all open() calls and import statements to understand what external resources the script depends on. In Python, open() reveals file dependencies, while imports like requests or socket indicate network activity. Mapping these dependencies before running the script gives you a complete picture of what it expects from the environment and what it might do.

    More advanced codebook-style challenges may obfuscate the lookup mechanism - for example, computing a hash of each character and comparing it against precomputed values, or encoding the codebook itself in base64 within the script. The core technique of reading the script, identifying its decoding logic, and supplying the required key material remains the same regardless of how the obfuscation is layered on top.

Interactive tools
  • Strings ExtractorPull printable text from any binary, library, or image. ASCII and UTF-16 detection, configurable minimum length, flag-like highlight, no command line needed.
  • Regex TesterTest regular expressions against a string with live match highlighting, flag toggles, and common CTF pattern shortcuts.
  • Base64 & Base32 DecoderDecode Base64 and Base32 strings with auto-detection. Multi-layer mode unwraps nested encodings automatically.

Flag

Reveal flag

picoCTF{c0d3b00k_455157_...}

The script requires both files to be in the same directory - a common pitfall for beginners who only download one file or run the script from a different working directory.

Key takeaway

Python's open() resolves paths against the current working directory, not the script's location, so a script that needs a companion file only works when you launch it from the directory holding both. Codebook ciphers pair a decoding function with a key document, and the whole scheme's security rests on keeping that document secret, exactly as historical military codebooks had to be guarded physically.

Related reading

Useful tools for General Skills

Where to go next