DISKO 4 picoCTF 2026 Solution

Published: March 20, 2026

Description

Can you find the flag in this disk image? This time I deleted the file! Let's see you get it now!

Download and decompress the disk image.

The flag file has been deleted.

bash
gunzip disko-4.dd.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
    Decompress the image
    Observation
    I noticed the download is a .dd.gz file, which indicated the raw disk image is wrapped in a gzip archive, and TSK tools like fls and icat require a seekable raw file on disk rather than a compressed stream.
    Extract the raw disk image from the gzip archive.
    bash
    gunzip disko-4.dd.gz
    What didn't work first

    Tried: Trying to mount the .gz file directly with 'sudo mount -o loop disko-4.dd.gz /mnt' before decompressing.

    Mount reads raw block data and expects a filesystem signature at byte 0, but gzip stores a compressed stream there. The kernel returns 'wrong fs type' or 'could not find valid filesystem superblock'. You must gunzip first to get the raw .dd sector layout that mount or TSK tools expect.

    Tried: Using 'zcat disko-4.dd.gz | fls -' or piping gunzip stdout directly into TSK tools.

    TSK tools like fls use lseek internally to jump between filesystem structures at arbitrary byte offsets. They require a seekable file, not a stream, so piping fails with 'unable to open image' or incorrect inode walks. Decompress to a real file first.

    Learn more

    A .dd file (named after the dd Unix utility) is a raw sector-by-sector copy of a disk or partition. Unlike archive formats, it preserves every byte including deleted data, slack space, and filesystem metadata. This makes it the standard format for digital forensics - it captures the disk's complete state at the moment of acquisition.

    gzip is a lossless compression format. gunzip file.gz decompresses and removes the .gz file, leaving the raw image. The resulting .dd file is often several gigabytes even for small disk images, because raw disk images include all sectors whether or not they contain data. Use ls -lh disko-4.dd to check the decompressed size.

    Tools for working with disk images include The Sleuth Kit (TSK) suite (mmls, fls, icat), Autopsy (a GUI frontend to TSK), and mount -o loop for read-only filesystem access. For CTF forensics, the TSK command-line tools are preferred for their scriptability.

  2. Step 2
    List deleted files and find the inode
    Observation
    I noticed the challenge stated the flag file was deleted, which meant the normal filesystem directory tree would not list it, so I needed fls with the -d flag to walk raw inode metadata and surface deallocated entries that still retain their block pointers.
    Use fls -r -d to enumerate deleted files, then grep for the flag filename to map it to its inode number. Alternatively, generate a mactime body file from fls output for full timeline context before picking the target inode.
    bash
    fls -r -d disko-4.dd | grep -i flag
    bash
    # Or generate a body file for timeline analysis:
    bash
    fls -m / disko-4.dd > body.txt
    bash
    # Validate the inode before carving:
    bash
    istat disko-4.dd <inode>

    Expected output

    d/d * 42:	flag.txt
    What didn't work first

    Tried: Running 'fls -r disko-4.dd | grep -i flag' (without the -d flag) to look for deleted files.

    Without -d, fls lists both allocated and deallocated entries. On an image where the deleted file's directory entry has been cleared, the grep finds nothing because the entry is only visible in the metadata layer, not the directory tree. The -d flag tells fls to walk inode structures looking for deallocated inodes rather than traversing live directory entries.

    Tried: Using 'strings disko-4.dd | grep picoCTF' to find the flag without going through TSK.

    Strings scans for printable ASCII sequences and will miss the flag here because the deleted file's content is a gzip-compressed blob. The compressed bytes are binary and do not contain readable ASCII text. You need to recover the inode data with icat first, then decompress it to get the plaintext flag.

    Learn more

    fls (file listing) is a TSK tool that lists files and directories from a filesystem image by reading its metadata structures directly - bypassing the OS. The -d flag shows only deleted files (those with a deallocated inode), and -r recurses into subdirectories. The output includes the inode number, which is needed for the next step.

    When a file is deleted in most filesystems (ext2/3/4, FAT, NTFS), the OS marks the inode as free and removes the directory entry, but does not zero out the data blocks. The file's data persists on disk until those blocks are reallocated for a new file. This is why forensic tools can recover deleted files - the data is still physically present, just invisible to the normal filesystem layer.

    The ext4 filesystem specifically marks inodes with a deletion time (dtime) when they are unlinked. fls -d finds inodes where the deletion time is set. On some filesystems (NTFS), the MFT (Master File Table) retains entries for deleted files until the MFT slot is reused, providing additional metadata like original file name and timestamps.

    Run istat disko-4.dd <inode> before carving to validate the recovery is worth attempting. istat shows the deletion timestamp, file size, and the list of direct/indirect block pointers. If the block pointers are zeroed (some kernels clear them on unlink) or pointing to obviously reallocated blocks, icat will return zeros or garbage and you should switch to file carving (foremost, scalpel) instead.

  3. Step 3
    Recover the deleted file
    Observation
    I noticed fls output gave me the inode number for flag.txt, which meant the inode and its block pointers were still intact, so icat could read the raw data blocks directly and reconstruct the file content without needing a file carver.
    Save the icat output to a file, then check its type. The recovered inode is itself a gzip-compressed file, so you must decompress it before you can read the flag.
    bash
    icat disko-4.dd <inode> > recovered.gz
    bash
    gunzip recovered.gz
    bash
    cat recovered
    What didn't work first

    Tried: Running 'icat disko-4.dd 42 > recovered' and immediately catting the file without checking its type first.

    The recovered data is gzip-compressed, so catting it raw prints binary garbage to the terminal. Running 'file recovered' first reveals 'gzip compressed data', which tells you to rename it to .gz and run gunzip before reading. Skipping this step wastes time chasing garbled output.

    Tried: Using 'foremost -i disko-4.dd -o carved/' or photorec to carve the deleted file instead of using the inode number.

    File carvers scan for magic byte signatures and can recover content when inode block pointers are zeroed. However, in this challenge the inode is intact and fls already gives you the exact inode number, so carving is unnecessary overhead. Carvers also may recover many false-positive fragments; the direct icat approach is faster and more precise when the inode is valid.

    Learn more

    icat (inode concatenate) is a TSK tool that reads the data blocks pointed to by an inode and outputs them to stdout. Even for deleted files where the directory entry is gone, the inode may still contain valid block pointers if the blocks have not been overwritten. Running icat disko-4.dd 42 recovers the data of inode 42 regardless of its deletion status.

    The reliability of recovery depends on what happened after deletion. If the disk was idle after the file was deleted (as in most CTF challenges), all original data blocks are intact. If the system continued to run and create files, some blocks may have been reallocated and overwritten. In that case, partial recovery is possible using file carving tools like foremost or photorec, which scan raw disk data for file format signatures (magic bytes).

    This technique is used in real digital forensics investigations to recover evidence after suspects attempt to delete it. Simply deleting files, even emptying the recycle bin, is insufficient to destroy evidence. Full disk overwriting (multiple passes of random data, as specified by the DoD 5220.22-M standard) or physical destruction is required for secure deletion - and even then, forensic labs sometimes recover data from damaged drives using electron microscopy.

    For more on the surrounding command-line forensic workflow, see the Linux CLI for CTF post.

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{d3l_d0n7_h1d3_w3ll_...}

Recovered via icat disko-4.dd 532021 > recovered.gz, then gunzip.

Key takeaway

Most filesystems (ext4, NTFS, FAT) implement deletion by marking an inode as free and removing its directory entry, but they do not immediately overwrite the data blocks. The file content remains on disk until those blocks are reallocated to a new file, which means forensic tools that read raw inode metadata can retrieve the data without going through the normal filesystem path. This is the fundamental reason why 'delete' does not mean 'destroy' and why secure deletion requires explicit overwriting, full-disk encryption whose key is then discarded, or physical media destruction.

Related reading

Want more picoCTF 2026 writeups?

Useful tools for Forensics

What to try next