Dear Diary picoCTF 2024 Solution

Published: April 3, 2024

Description

If you can find the flag on this disk image, we can close the case for good! Download the disk image here.

Disk forensics

Download and decompress the 1 GB disk image.

No GUI forensics tool is required; strings and grep work directly on the raw image.

bash
wget https://artifacts.picoctf.net/c_titan/63/disk.flag.img.gz && \
gunzip disk.flag.img.gz

Solution

Want to try it yourself first?

The guided walkthrough reveals hints one step at a time.

Walk me through it
  1. Step 1
    Explore the image (optional orientation)
    Observation
    I noticed the challenge provided a raw disk image rather than an extracted archive or text file, which suggested that the flag might be hidden in the file system structure itself and that orienting myself with the disk contents was worth doing first.
    Mounting or using a forensics tool reveals files named force-wait.sh, innocuous-file.txt, and a file literally named its-all-in-the-name. That last filename is the hint: the flag is embedded in the name of the innocuous-file.txt entries scattered throughout the disk.
    Learn more

    A disk image (.img) is a sector-by-sector copy of a storage device. The .gz extension means it is gzip-compressed; gunzip decompresses it before analysis. Disk images preserve everything: file contents, metadata, slack space, deleted file remnants, and data in unallocated sectors.

    For orientation you can mount the image (sudo mount -o loop disk.flag.img /mnt) or load it into Autopsy. For the actual flag extraction, neither is needed: strings and grep work directly on the raw image file.

  2. Step 2
    Search the raw image for the flag
    Observation
    I noticed that the file literally named 'its-all-in-the-name' was present on the disk and that filename entries for 'innocuous-file.txt' appeared repeatedly, which suggested the flag characters were embedded in those filename strings and could be extracted with strings and grep on the raw image bytes.
    Run strings with the -a flag (scan every byte, not just initialized sections) on the raw disk image and grep for innocuous to find all the file-name occurrences. The flag characters appear adjacent to those strings. Piping through grep -a ensures binary-safe matching.
    bash
    strings -a disk.flag.img | grep innocuous
    bash
    grep -a innocuous disk.flag.img

    Each hit shows a variant of the filename with flag characters embedded around it. Collect the unique flag segments from adjacent runs and assemble the full picoCTF{...}.

    What didn't work first

    Tried: Mount the image with 'sudo mount -o loop disk.flag.img /mnt' and browse the file system looking for the flag in file contents.

    Mounting only exposes the live file system layer - deleted directory entries and slack space are invisible through the mount point. The flag is embedded in historical filename strings that have been overwritten in the active directory tree but still exist as raw bytes on disk. You need to scan the raw image bytes directly with strings or grep to reach those unallocated regions.

    Tried: Run 'strings disk.flag.img | grep picoCTF' to find the flag directly instead of grepping for 'innocuous'.

    The flag is not stored as a single contiguous picoCTF{...} string anywhere in the image. Its characters are split across multiple directory entry fragments embedded within longer 'innocuous-file.txt' filename strings. Grepping for the flag prefix returns nothing, while grepping for 'innocuous' surfaces all the filename occurrences where the flag segments can be read and assembled.

    Learn more

    strings extracts sequences of printable ASCII characters from any binary file. The -a flag tells it to scan the entire file rather than just the initialized data sections of an ELF. On a raw disk image this is essential: file-system metadata, directory entries, and deleted file names all live in non-ELF regions that the default mode skips.

    grep -a treats the input as text even when binary bytes are present, preventing grep from silently ignoring matches in binary data. The two commands above are equivalent for this purpose; both scan the entire image for occurrences of the string innocuous.

    This technique works because directory entries in ext2/ext3/ext4 file systems store file names as plain ASCII in fixed-size blocks. Deleted entries are not zeroed; the name bytes remain on disk until the block is reused. That is why the flag fragments appear multiple times: each time the file was created, modified, and deleted, the inode was reused but the old directory blocks were left in place.

Interactive tools
  • Hex ViewerView text or raw hex bytes as a xxd-style hex dump with byte offset, hex columns, and ASCII sidebar. Highlights printable characters and null bytes.
  • File Magic IdentifierIdentify file types from magic numbers. Paste hex bytes or drop a file to detect PNG, JPEG, ZIP, PDF, ELF, PCAP, SQLite, and dozens of other formats.
  • 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.

Flag

Reveal flag

picoCTF{1_533_n4m35_80d2...}

The flag characters appear embedded in the innocuous-file.txt name strings scattered across the raw disk image.

Key takeaway

File systems store file names, metadata, and even deleted file records as plaintext bytes in fixed-size directory blocks, and those bytes persist on disk until the sector is reused. The strings and grep tools extract these printable sequences directly from a raw disk image without needing to mount it or parse the file system structure. The same technique is used in real digital forensics to recover evidence of deleted files, browsing history, and credentials long after a user believes the data is gone.

Related reading

Want more picoCTF 2024 writeups?

Useful tools for Forensics

What to try next