DISKO 2 picoGym Exclusive Solution

Published: March 5, 2024

Description

A disk image contains multiple partitions. The flag is hidden inside the Linux partition - you need to identify where it starts and extract it before searching.

Download disko-2.dd.gz from the picoGym challenge page.

Decompress the image, then inspect the partition table.

bash
gunzip disko-2.dd.gz
bash
fdisk -l disko-2.dd

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 and read the partition table
    Observation
    I noticed the challenge description mentioned multiple partitions and that the flag lives specifically inside the Linux partition, which suggested I needed to read the partition table first to identify exactly where the Linux partition starts before attempting any search.
    Run gunzip then fdisk -l disko-2.dd to display the partition table. The output shows at least two partitions. The Linux partition starts at sector 2048 and spans 51200 sectors (each sector is 512 bytes).
    bash
    gunzip disko-2.dd.gz
    bash
    fdisk -l disko-2.dd
    What didn't work first

    Tried: Run strings disko-2.dd | grep -i pico on the whole undecompressed image before reading the partition table.

    The image contains multiple partitions and the strings output mixes data from all of them, making the flag hard to locate or returning false positives from unrelated regions. Reading the partition table first with fdisk -l tells you exactly which partition is Linux so you can isolate it before searching.

    Tried: Use file disko-2.dd to identify the disk layout instead of fdisk.

    file reports the top-level format (e.g. DOS/MBR boot sector) but does not enumerate individual partitions or their start sectors. fdisk -l is required because it parses the full MBR partition table and prints each entry's start sector, size, and filesystem type code, which are the values needed for the dd extraction step.

    Learn more

    A partition table maps a physical disk into logical regions called partitions, each holding an independent filesystem. The traditional MBR (Master Boot Record) layout stores up to four primary partitions in a 64-byte table at the very start of the disk. Each entry records the starting LBA (Logical Block Address) sector, the size in sectors, and a type byte that identifies the filesystem type (0x83 = Linux ext, 0x0B/0x0C = FAT32, 0x82 = Linux swap).

    fdisk -l reads the partition table and displays each partition's start sector, end sector, size, and type. This is the essential first command when you receive any disk image with multiple partitions, because strings on the whole image would find text from all partitions mixed together - you need to isolate the right partition first.

    The sector size is almost always 512 bytes for images from CTF challenges. Multiplying the start sector by 512 gives you the byte offset to pass to dd's skip option. Multiplying the sector count by 512 gives you the byte size to pass to count.

  2. Step 2
    Extract the Linux partition with dd
    Observation
    I noticed fdisk reported the Linux partition starts at sector 2048 and spans 51200 sectors, which gave me the exact skip and count values needed to carve it into a standalone file with dd before running any text search.
    Use dd to carve out just the Linux partition bytes into a new file. Skip the first 2048 sectors (the MBR and any preceding data) and copy 51200 sectors worth of data.
    bash
    dd if=disko-2.dd of=linux-part.dd bs=512 skip=2048 count=51200
    What didn't work first

    Tried: Use dd with skip=2048 but omit count=51200, copying to the end of the image instead.

    Without count, dd copies from sector 2048 all the way to the end of the image, including any subsequent partitions. The extracted file is oversized and contains data from the wrong partitions, which can confuse filesystem tools and inflate strings output with irrelevant results. The count value from fdisk output must be used to capture exactly the Linux partition and nothing more.

    Tried: Use bs=1 with a byte-level skip offset calculated as 2048 times 512 equals 1048576, instead of bs=512 skip=2048.

    While mathematically equivalent, bs=1 makes dd read and write one byte at a time, which is extremely slow on a multi-megabyte partition image. Using bs=512 skip=2048 is the standard approach: it reads in 512-byte sector-sized blocks and the skip/count counts refer to those blocks, matching the sector geometry reported by fdisk.

    Learn more

    dd (disk dump) copies raw bytes between files or devices with precise control over block size, offset, and count. The options used here: if = input file, of = output file, bs=512 = block size in bytes (matching the sector size), skip=2048 = skip the first 2048 blocks from the input (jumping to the Linux partition start), count=51200 = copy exactly 51200 blocks.

    This technique of extracting a partition with dd is fundamental in forensics. It produces a new raw image of just that partition, which you can then pass to any filesystem-aware tool. Without the isolation step, searching the whole disk image would return results from the wrong partition or mix data from multiple locations, making it harder to interpret.

    Alternatively, mount -o loop,offset=$((512*2048)) disko-2.dd /mnt/part can mount the partition directly without extracting it, but using dd to isolate it first is cleaner and avoids any risk of the mount modifying timestamps on the filesystem.

  3. Step 3
    Find the flag with strings
    Observation
    I noticed the flag is described as plain text embedded in the Linux filesystem, and having isolated the partition into its own file with dd, running strings with a grep filter was the fastest way to surface the picoCTF pattern without needing root access to mount the image.
    Run strings linux-part.dd | grep -i pico on the extracted partition file. The flag is stored as plain text inside the Linux filesystem and appears immediately.
    bash
    strings linux-part.dd | grep -i pico
    What didn't work first

    Tried: Mount the extracted partition with mount linux-part.dd /mnt/part and then use find /mnt/part -type f to manually browse files looking for the flag.

    Mounting requires root privileges and a loop device, and browsing the directory tree manually is slow compared to strings | grep. More critically, ext2/ext3/ext4 flags stored in deleted inodes or unallocated blocks are invisible to the filesystem layer but still visible to strings, so mounting can miss the flag entirely if it was written to a file that was subsequently deleted.

    Tried: Run grep -r 'picoCTF' /mnt/part after mounting instead of using strings.

    grep -r only reads the content of live files the filesystem exposes. If the flag resides in a deleted file's inode data or in raw unallocated space within the partition, grep on the mounted filesystem will not find it. strings linux-part.dd reads the raw image bytes directly, surfacing printable sequences regardless of whether the filesystem considers them allocated.

    Learn more

    With the Linux partition isolated, strings | grep searches only the relevant filesystem. The flag is embedded as plaintext in the ext2/ext3/ext4 inode or file data area, so it appears in the strings output without needing to mount the partition or navigate its directory tree.

    This challenge teaches the core partition analysis workflow used in real disk forensics: identify the partition layout (fdisk -l or mmls), extract the relevant partition (dd or targeted mount), then apply analysis tools. The same workflow applies whether you are looking for a CTF flag, malware artifacts, or evidence of data exfiltration on a compromised machine.

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{4_P4Rt_1t_i5...}

Isolate the Linux partition with dd (skip=2048, count=51200), then `strings linux-part.dd | grep pico` reveals the flag.

Key takeaway

Disk images are not monolithic blobs of data; they are structured into partitions that each hold an independent filesystem. Reading the partition table first (with fdisk or mmls) tells you where each region starts and how large it is, so you can carve it out precisely with dd rather than searching the entire image and getting noise from the wrong partition. This triage workflow is the foundation of disk forensics and applies equally to seized hard drives, VM snapshots, and memory card images in incident response and malware analysis.

Related reading

Want more picoGym Exclusive writeups?

Useful tools for Forensics

What to try next