Description
A disk image holds a flag that strings alone cannot find - it is compressed inside a .gz file buried in a subdirectory. Mount the image and decompress the hidden file to read it.
Setup
Download disko-3.dd.gz from the picoGym challenge page.
Decompress the outer archive, then prepare a mount point.
gunzip disko-3.dd.gzfile disko-3.ddsudo mkdir -p /mnt/disko3Solution
Want to try it yourself first?
The guided walkthrough reveals hints one step at a time.
Step 1Decompress and attempt strings
ObservationThe outer archive is gzip, so decompress before anything else. Then run strings through grep as cheap recon: if the flag is plain text you are done before opening any filesystem tooling.Rungunzipthen trystrings disko-3.dd | grep -i pico. This time nothing useful appears - the flag is not stored as plain text. The image is FAT32 like DISKO 1, but the flag is hidden inside a compressed file.bashgunzip disko-3.dd.gzbashfile disko-3.ddbashstrings disko-3.dd | grep -i picoWhat didn't work first
Tried: Try strings with a wider minimum-length to catch any encoded flag fragments.
Lowering the minimum string length still finds nothing, because the flag is compressed and its bytes carry no printable run at all. All you get is more noise. Mount the image and read the filesystem instead of scanning raw bytes.
Tried: Use binwalk to carve compressed streams directly from the raw image.
binwalk does find and extract the gzip stream, and it drops the result in a generated directory under a numeric offset name that is easy to miss. If it misjudges the boundary, decompression fails on a CRC error. A loop mount gives you the correctly named file directly, with none of the carving artifacts.
Learn more
When
strings | grepreturns nothing, the flag is not stored as raw ASCII in the disk image. It may be compressed (gzip, bzip2, xz), encoded (base64, hex), encrypted, or stored in a format that produces non-printable bytes. This is the moment to mount the image and inspect the actual file structure instead of searching raw bytes.A compressed file stored inside a filesystem appears to
stringsas a burst of random-looking bytes (the compressed data) bookended by a few readable bytes from the gzip header (the magic bytes1f 8band the original filename, if stored). The flag content itself is invisible until decompressed.Step 2Mount the image and navigate the filesystem
ObservationThat search comes back empty, which means the flag is inside a compressed file on a real filesystem rather than sitting as raw bytes. Mount the image with a loop device and browse the tree.Mount the disk image withmount -o loopto browse it as a live filesystem. Navigate to the/log/directory whereflag.gzis located.bashsudo mount -o loop disko-3.dd /mnt/disko3bashls /mnt/disko3/bashls /mnt/disko3/log/What didn't work first
Tried: Mount the image without the loop option, passing the raw filename directly to mount.
Without the loop option, mount reports that it can only mount block devices, because the kernel wants a device rather than a regular file. That option attaches a loop device to the file first and presents it as a virtual block device.
Tried: Use
fdisk -l disko-3.ddto find a partition offset, then mount with-o offset=instead of loop.Computing an offset from a start sector works when the image is partitioned with an MBR. This one is an unpartitioned FAT32 image whose filesystem starts at sector 0, so an explicit offset gives a wrong filesystem type or a garbled listing. Mount it plainly.
Learn more
The
-o loopoption tells the Linux kernel to use a loop device - a virtual block device that maps a regular file as if it were a physical disk. This lets you mount a disk image file exactly like a real drive. The kernel reads the FAT32 superblock from the image and makes the filesystem accessible at the mount point.In professional forensics, images are mounted read-only (add
-o ro,loop) to preserve evidence integrity. A write-enabled mount could update access timestamps, modify journal entries, or trigger filesystem repair operations that alter the evidence. For CTF purposes, a read-only mount is still good practice even though there is no legal chain-of-custody requirement.Once mounted, standard Unix commands (
ls,find,cat) work normally against the filesystem. This is often the most convenient way to browse a disk image when the flag is buried in a directory tree rather than scattered as raw bytes.Step 3Extract and decompress the flag file
ObservationThe mounted image has flag.gz in its log directory. Copy it somewhere writable and decompress it.Copyflag.gzfrom the mounted image to a writable location, then decompress it withgunzipand read it withcat. The flag appears as plain text.bashcp /mnt/disko3/log/flag.gz /tmp/flag.gzbashgunzip /tmp/flag.gzbashcat /tmp/flagbashsudo umount /mnt/disko3What didn't work first
Tried: Decompress flag.gz in place directly on the mounted filesystem instead of copying it out first.
Decompressing in place writes back onto the mounted image, which fails outright on a read-only mount and risks corrupting the evidence on a writable one. Copy the file out first and the source image stays pristine either way.
Tried: Use
zcat /mnt/disko3/log/flag.gzto print the decompressed contents without copying or creating a temp file.zcat works and prints the flag to stdout. If the decompressed content is not text, though, the terminal garbles it, and going straight to the answer hides the fact that you still need to unmount cleanly. Copying, decompressing, and reading as separate steps makes each transformation visible when something goes wrong.
Learn more
Copying the compressed file out of the mounted image before decompressing it is cleaner than decompressing in place on the mounted filesystem - it avoids any risk of writing to the image and keeps the analysis tidy. The
gunzipcommand decompressesflag.gzin place, producing a file namedflag, whichcatthen displays.This challenge pattern - a flag compressed and hidden in a non-obvious subdirectory - is common in CTF forensics. The key skill is knowing when raw-byte techniques like
stringswill not work and switching to filesystem-level exploration. The lesson from the DISKO series as a whole: try the quick approach first (strings | grep), but be ready to mount, navigate, and decompress when the flag is not plaintext.Always unmount (
sudo umount) after analysis. Leaving a loop-mounted image open can cause issues if you later try to delete or move the disk image file, and on some systems the loop device will remain reserved until explicitly released.
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{n3v3r_z1p_2_h1d3...}
Mount the image with `mount -o loop`, find `flag.gz` in the `/log/` directory, gunzip it, and cat the result.