Verify picoCTF 2024 Solution

Published: April 3, 2024

Description

People keep trying to trick my players with imitation flags. I want to make sure they get the real thing! I'm going to provide the SHA-256 hash and a decrypt script to help you know that my flags are legitimate.

Hash + decrypt

Download/ssh into the drop-in directory and note checksum.txt, decrypt.sh, and files/.

Have sha256sum and openssl available (both are standard on Linux).

bash
wget https://artifacts.picoctf.net/c_rhea/12/challenge.zip && \
unzip challenge.zip && \
cd drop-in
  1. Step 1Identify the correct file
    Hash every file under files/, then grep for the value in checksum.txt. The single line of output names the matching file (files/00011a60 in the canonical drop-in).
    bash
    sha256sum files/* | grep 03b52eabed517324828b9e09cbbf8a7b0911f348f76cf989ba6d51acede6d5d8
    Learn more

    SHA-256 is a cryptographic hash function that takes any input and produces a fixed 256-bit (64 hex character) digest. It has three critical properties: it is deterministic (same input always produces the same hash), collision-resistant (it is computationally infeasible to find two different inputs with the same hash), and one-way (you cannot reverse the hash to find the input).

    Hash verification is the standard method for confirming file integrity. When you download software, operating system images, or forensic evidence files, you compare the downloaded file's hash against the expected value to confirm nothing was tampered with or corrupted in transit. This is called a checksum verification.

    • sha256sum file computes the SHA-256 hash of a file.
    • sha256sum files/* computes hashes for all files in the directory - pipe through grep to find the matching one.
    • Other common hash tools: md5sum (MD5, weak - avoid for security), sha1sum (SHA-1, deprecated), sha512sum (SHA-512, stronger than SHA-256).
  2. Step 2Fix and run the decrypt script
    Open decrypt.sh in a text editor. The script contains a line that prepends /home/ctf-player/drop-in/ (or similar) to the argument, creating an invalid path. Remove or comment out that prefix so the script just receives the filename directly. Then run it with the matched file.
    bash
    cat decrypt.sh
    bash
    ./decrypt.sh files/e018b574

    The decrypted output starts with picoCTF{. If you see a "not a valid file" error, the script is still prepending the broken prefix; edit it and try again.

    Learn more

    openssl enc is OpenSSL's symmetric encryption/decryption command. Breaking down the flags: -d means decrypt, -aes-256-cbc specifies AES-256 in Cipher Block Chaining mode, -pbkdf2 uses the PBKDF2 key derivation function (more secure than the old default), -iter 100000 runs 100,000 iterations of PBKDF2 to slow brute-force attacks, -salt includes a random salt, and -k picoCTF provides the password.

    PBKDF2 (Password-Based Key Derivation Function 2) deliberately makes password-to-key derivation slow and computationally expensive. If an attacker obtains the ciphertext, they cannot quickly brute-force the password because each guess requires 100,000 hash iterations. Modern alternatives include Argon2 and bcrypt.

    The shell script decrypt.sh wraps this command but contains a path-construction bug in this challenge instance. Reading and fixing wrapper scripts is a common CTF skill: the script reveals the exact OpenSSL flags, and removing the broken path prefix is a trivial one-line edit. Always read the provided scripts before running them.

  3. Step 3Alternate brute-force
    Skip the hashing step and just try every file. Suppress stderr (most fail with bad-magic-number errors), pipe through strings to keep only printable runs, then grep for the flag prefix.
    bash
    for f in files/*; do openssl enc -d -aes-256-cbc -pbkdf2 -iter 100000 -salt -in "$f" -k picoCTF 2>/dev/null; done | strings | grep picoCTF
    Learn more

    The for loop iterates over every file matching files/* and attempts to decrypt each with the known password. Only the correct file decrypts to readable plaintext; the others fail with an error or produce garbage. Sending stderr to /dev/null hides the noise so the surviving stdout lines come from the one valid decrypt.

    This brute-force approach trades CPU time for the convenience of skipping the hash computation step. It is a valid strategy when the file count is small. With hundreds of files and slow PBKDF2 iterations the hash-first approach is faster.

    For the broader shell toolkit used here, see the Linux command line guide for CTFs.

Flag

picoCTF{trust_but_verify_0...}

Only the file whose hash matches checksum.txt decrypts to the flag.

Want more picoCTF 2024 writeups?

Useful tools for Forensics

Related reading

What to try next