Skip to main content

UnforgottenBits picoCTF 2023 Solution

Dig into a forensic disk image hiding secrets across multiple formats and layers of encoding.

Published: April 26, 2023Updated: August 25, 2026

Description

A forensic disk image contains IRC logs, gallery BMPs, notes, and deleted emails. Follow the breadcrumbs through steghide, a cracked password derived from League of Legends champions, slack-space analysis, and two rounds of AES decryption to reach the flag.

Download and gunzip the disk image, then open it in Autopsy (sudo autopsy → http://localhost:9999/autopsy). Select image 4 (the primary partition; vol3 is the swap partition and is empty) and click Analyze → File Analysis.

Expand directories and browse to /vol4/home/yone/ to review IRC logs and gallery files.

bash
wget https://artifacts.picoctf.net/c/485/disk.flag.img.gz
bash
gunzip disk.flag.img.gz
bash
sudo autopsy

Solution

Want to try it yourself first?

The guided walkthrough reveals hints one step at a time.

Walk me through it
  1. Step 1Read the IRC logs
    Observation
    The disk image has a home directory for user 'yone' with an irclogs folder. Plain-text chat logs are the first place credentials and crypto parameters leak.
    Open /vol4/home/yone/irclogs/01/04/#avidreader13.log in Autopsy. It reveals the steghide password akalibardzyratrundle and the AES-256-CBC parameters: salt=0f3fa17eeacd53a9, key=58593a...d508, iv=7a12fd...91.
    Learn more

    Autopsy is an open-source digital forensics platform built on top of The Sleuth Kit (TSK). It provides a graphical interface for analyzing disk images - browsing the file system, recovering deleted files, viewing file metadata, searching for keywords, and examining timeline data. It's widely used by law enforcement and security researchers for forensic investigations.

    IRC (Internet Relay Chat) logs are plain-text records of chat conversations stored on the user's machine. IRC was the dominant real-time text communication protocol before Slack, Discord, and similar platforms. IRC clients like WeeChat and irssi store logs in structured directory trees organized by server, channel, and date - exactly the path structure seen here (irclogs/01/04/).

    Finding credentials in communication logs is a classic forensic technique. People often share passwords, keys, or other sensitive data in private chats, assuming the conversation is ephemeral. In reality, IRC clients log everything by default, and those logs persist on disk - even after the user thinks they've "deleted" the conversation.

  2. Step 2Extract from 1.bmp, 2.bmp, 3.bmp (steghide)
    Observation
    The log hands over the passphrase 'akalibardzyratrundle' and mentions the BMP gallery. steghide is the standard tool for BMP and JPEG steganography when you already know the passphrase.
    Export the four BMPs from /vol4/home/yone/gallery/ and run steghide on each. 1.bmp, 2.bmp, and 3.bmp yield frankenstein.txt.enc, dracula.txt.enc, and les-mis.txt.enc. Decrypt each with the IRC-provided AES params - these are red herrings; they contain classic literature, not the flag.
    bash
    steghide extract -sf 1.bmp -p akalibardzyratrundle
    bash
    steghide extract -sf 2.bmp -p akalibardzyratrundle
    bash
    steghide extract -sf 3.bmp -p akalibardzyratrundle
    bash
    openssl enc -aes-256-cbc -d -S 0f3fa17eeacd53a9 -K 58593a7522257f2a95cce9a68886ff78546784ad7db4473dbd91aecd9eefd508 -iv 7a12fd4dc1898efcd997a1b9496e7591 -in frankenstein.txt.enc -out frankenstein.txt

    Expected output

    wrote extracted data to "frankenstein.txt.enc".
    wrote extracted data to "dracula.txt.enc".
    wrote extracted data to "les-mis.txt.enc".
    What didn't work first

    Tried: Run stegcracker on 1.bmp, 2.bmp, and 3.bmp without first checking the IRC logs for the known passphrase

    A generic wordlist like rockyou.txt burns through millions of guesses and never reaches 'akalibardzyratrundle', which is a run of champion names rather than a dictionary word. The IRC log already gave you the passphrase, so extract with it directly and skip the brute force.

    Tried: Assume the decrypted .enc files contain the flag and spend time examining frankenstein.txt, dracula.txt, and les-mis.txt for hidden content

    It decrypts, and the output is readable text from a classic novel, which feels like progress. Those files are deliberate decoys. The path forward is 7.bmp, whose passphrase you do not have yet.

    Learn more

    steghide is a steganography tool that hides data inside image and audio files. It embeds secret data in the least significant bits of pixel values (for BMP/JPEG) or audio samples (for WAV/AU), optionally encrypting the hidden data with a passphrase. The host image's visual appearance is imperceptibly altered. steghide uses AES-128 encryption internally to protect the embedded data, in addition to the image-level hiding.

    Red herrings are deliberate distractions in CTF challenges - they look like progress but don't lead to the flag. The encrypted classic literature files here are designed to consume time and make you question whether you have the right password or decryption parameters. Recognizing red herrings requires methodically tracking what you've tried and what the challenge description actually says to find.

    AES-256-CBC (Advanced Encryption Standard, 256-bit key, Cipher Block Chaining mode) is one of the most common symmetric encryption configurations. The openssl enc command performs both encryption and decryption using standard algorithms. The key and IV given here fully specify the decryption and both must be exactly right; the salt is quoted alongside them by the challenge but plays no part once -K and -iv are supplied.

  3. Step 3Find the partial password in notes
    Observation
    7.bmp is still untouched, and the notes directory has not been looked at yet. That is the natural place to find the hint that unlocks it.
    Browse /vol4/home/yone/notes/. 3.txt reads: "I keep forgetting this, but it starts like: yasuoaatrox...". This is the beginning of the steghide password for 7.bmp - yasuo and aatrox are two League of Legends champions.
    Learn more

    Notes files on a user's machine are goldmines for forensic investigators. People frequently write down passwords, reminder hints, or partial credentials in plain-text notes, to-do files, or sticky note applications. Even a partial password like "it starts like: yasuoaatrox..." dramatically reduces the search space for a brute-force attack.

    This clue reveals that the password follows the XKCD #936 "correct horse battery staple" philosophy - using multiple common words concatenated together. The words are League of Legends champion names, which the user apparently knows by heart and uses as a memorable but complex password. The challenge design cleverly ties the user's hobby (gaming) to their password strategy, which is realistic forensic behavior.

  4. Step 4Email forensics - recover the password strategy
    Observation
    The note says the password 'starts like: yasuoaatrox' and stops there. Autopsy can recover deleted files, so search for yone786@ and look for an email that says how many champion names get concatenated.
    Use Autopsy's Keyword Search for yone786@ to surface deleted emails. An email chain between yone786@gmail.com and azerite17@gmail.com references the XKCD #936 password philosophy (four strong words from a favorite game). Since the IRC logs show Yone loves League of Legends, the full password is yasuoaatrox + two more LoL champion names.
    Learn more

    Deleted file recovery is a cornerstone of digital forensics. When a file is "deleted," the operating system typically just marks the space as available - the actual data remains on disk until overwritten. Forensic tools like Autopsy, FTK, and Recuva can recover these "deleted" files by scanning for intact file system metadata or known file headers.

    Email forensics on a disk image involves searching for email client database files (Thunderbird's .mbox and .sqlite files, Outlook's .pst/.ost, Evolution's local mail store). Email metadata - sender, recipient, timestamp, subject - often survives even when the body is partially overwritten. Keyword searching for email addresses like yone786@ can surface relevant messages quickly.

    XKCD #936("Password Strength") is the famous comic arguing that four random common words concatenated (like "correct horse battery staple") provide more entropy and memorability than complex passwords with symbols substituting letters. The math checks out - but as this challenge shows, the strategy fails if the word universe is small (only ~160 LoL champions) and the attacker knows your interests.

  5. Step 5Generate a wordlist and stegcrack 7.bmp
    Observation
    The recovered email describes a four-champion concatenation, and the note pins the prefix at 'yasuoaatrox'. Generate every pair of champion names onto that prefix and feed the list to stegcracker.
    Build a Python script that prepends yasuoaatrox to every pair of lowercase champion names and writes the combos to output.txt. Feed that list into stegcracker. After ~1259 attempts it finds the password yasuoaatroxashecassiopeia and extracts 7.bmp.out.
    python
    python3 - <<'PY'
    arr = open('leagueOfLegendsChampions.txt').readlines()
    with open('output.txt', 'w') as f:
        for i in arr:
            for j in arr:
                f.write('yasuoaatrox' + i.strip() + j.strip() + '\n')
    PY
    bash
    stegcracker 7.bmp output.txt
    What didn't work first

    Tried: Feed stegcracker a generic wordlist like rockyou.txt instead of generating the custom champion-combo list

    rockyou.txt holds over 14 million passwords, none of them champion-name runs like 'yasuoaatroxashecassiopeia'. The tool exhausts the list and reports nothing. The notes and the recovered email exist to give you the word universe and the prefix, so generate the list yourself.

    Tried: Generate the wordlist with only one champion appended (prefix + one name) instead of two

    The note trails off after 'yasuoaatrox', and the recovered email spells out a four-word password built from champion names. A single-suffix list of 160 entries cannot reach the two-name tail, so stegcracker finds nothing. The nested loop over all 160x160 pairs is what covers it.

    Learn more

    stegcracker is a brute-force tool for steghide that tries passwords from a wordlist. It automates what would otherwise be a tedious manual process of running steghide extract repeatedly. The key insight here is that the password space - while large in theory - is severely constrained by the known prefix (yasuoaatrox) and the known word universe (LoL champion names), reducing it to approximately 160 × 160 = 25,600 combinations.

    Custom wordlist generation is often more effective than generic wordlists like rockyou.txt when the attacker has information about the target's interests or habits. The nested loop approach here generates all pairwise combinations of champion names - a form of combinatorial generation. Real-world tools like CeWL (Custom Word List generator) scrape websites related to a target to build tailored wordlists for password attacks.

    The fact that only ~1259 attempts are needed (out of 25,600) follows from the loop order: ashe sits near the front of the champion list, so the outer loop only makes a handful of full passes before the pair ashe + cassiopeia comes up. This illustrates why password cracking with a targeted wordlist is far more efficient than brute-force: domain knowledge dramatically reduces the search space.

  6. Step 6Locate the second key in slack space
    Observation
    stegcracker produces 7.bmp.out, but the AES parameters from the IRC log only decrypt the red herrings. Browser history on the disk mentions golden-ratio-base encoding, so look in file slack space for a second key written that way.
    Open the disk in the Windows version of Autopsy (or any tool that exposes slack space). Under Settings → Hide slack files, uncheck both boxes. Inspect 1.txt-slack - it contains encoded data. The browser history in the disk shows research into Golden Ratio Base (φ-base) encoding. Decode the slack data using a golden-ratio-base decoder to obtain a new salt, key, and iv.
    Learn more

    Slack space (also called file slack) is unused space within the last cluster allocated to a file. File systems allocate disk space in fixed-size clusters (e.g., 4096 bytes). If a file is 100 bytes, the entire 4096-byte cluster is still allocated, but 3996 bytes go unused - this gap is the slack space. Data previously written to those sectors may remain there even after the file is overwritten, making slack space a rich source of forensic evidence.

    Golden Ratio Base (Phinary / φ-base) is a non-integer positional numeral system using the golden ratio φ ≈ 1.618 as its base. Every positive integer has a unique representation in this base using only 0s and 1s with no two adjacent 1s, the base-phi analogue of the Zeckendorf representation in Fibonacci base. It's a highly unusual encoding with no practical cryptographic purpose, but its obscurity makes it a clever CTF clue - the browser history pointing to research on "golden ratio base" is the key hint that tells you which decoder to use.

    The challenge design here exemplifies multi-layer forensic investigation: you must find data hidden in slack space, recognize an unusual encoding from a contextual clue (browser history), decode it to recover crypto parameters, and then use those parameters in another decryption step. Each layer builds on the previous one, requiring both technical skills and careful attention to the narrative clues embedded throughout the disk.

  7. Step 7Final AES decryption
    Observation
    The slack space of 1.txt decodes to a different salt, key, and IV. Run 7.bmp.out through openssl with those AES-256-CBC parameters and the flag comes out.
    Decrypt 7.bmp.out with the second set of AES parameters recovered from the slack space. Run cat finallyReleased.txt to read the flag.
    bash
    openssl enc -aes-256-cbc -d -S 2350e88cbeaf16c9 -K a9f86b874bd927057a05408d274ee3a88a83ad972217b81fdc2bb8e8ca8736da -iv 908458e48fc8db1c5a46f18f0feb119f -in 7.bmp.out -out finallyReleased.txt
    bash
    grep picoCTF finallyReleased.txt
    What didn't work first

    Tried: Reuse the first set of AES parameters from the IRC logs (salt=0f3fa17eeacd53a9, key=58593a..., iv=7a12fd...) to decrypt 7.bmp.out

    openssl exits cleanly, because CBC decryption cannot tell a wrong key from a right one; it just emits garbage. You get unreadable binary instead of a flag. The working key and IV come from the golden-ratio-base data in the slack space of 1.txt, and they are not the first pair.

    Tried: Recover only the key and IV from the slack space and skip the salt, or vice versa

    With -K and -iv given directly, OpenSSL skips password-based key derivation entirely and ignores -S, so the salt alone gets you nowhere and dropping it changes nothing. What actually has to be right is the 32-byte key and the 16-byte IV; decode the slack data carefully enough to get both, since a single wrong nibble in either turns the output into noise.

    Learn more

    AES-256-CBC with an explicit key and IV (as used here with -K and -iv) bypasses the password-based key derivation step that -pass would use. This means the key material must match exactly - not just the password, but the raw hex key bytes. The -S flag specifies the salt used during key derivation, so when -K and -iv are supplied directly it is ignored outright: passing it or leaving it off produces byte-identical output. It is quoted here only because the challenge hands the salt to you alongside the key and IV.

    CBC (Cipher Block Chaining) mode processes data in fixed-size blocks (16 bytes for AES). Each plaintext block is XORed with the previous ciphertext block before encryption, chaining them together. The IV (Initialization Vector) is used as the "previous block" for the first block, ensuring that identical plaintexts with the same key but different IVs produce different ciphertexts. Without a random IV, AES-CBC leaks information about repeated message prefixes.

    The grep picoCTF at the end accounts for the possibility that finallyReleased.txt contains a lot of text (the decrypted content might be a long document). Piping to grep quickly isolates the flag line. This "needle in a haystack" pattern - decrypting a large file and then searching it - is a common forensics pattern when the flag is embedded in a larger document.

Interactive tools
  • Password Steg (Encrypt & Decrypt)Password-protect a message with AES-GCM and PBKDF2-derived keys. Encode produces a base64 ciphertext you can hide in any carrier; decode recovers the original with the same password. Runs entirely in the browser.

Flag

Reveal flag

picoCTF{f473_53413d_de...}

Every clue lives on the disk: IRC logs expose the first AES key, deleted emails reveal the LoL-champion password strategy, and slack space hides the second AES key in golden-ratio-base encoding.

Key takeaway

Disk forensics works because deleting a file edits metadata rather than erasing data: the content stays until something overwrites it. Filesystems leak in other ways too, through slack space at the tail of a cluster, swap, browser history, and chat logs nobody remembers are plain text. A layered challenge chains those artifacts, each one holding part of the credential that opens the next. Incident response works the same way, because attackers leave traces in exactly these places.

Related reading

Tools used in this challenge

Where to go next