DEV Community

rudy_candy
rudy_candy

Posted on • Originally published at alsavaudomila.com

Disk Image Forensics: Why mount Fails and How to Make the Right Call First

CTF Disk Forensics: Why I Wasted 20 Minutes Before Learning the Right mount Workflow

If you've ever stared at a wrong fs type, bad option, bad superblock error and thought "I just need to recalculate the offset" — I've been there. In a CTF forensics challenge, I spent 20 minutes convinced that mount would eventually work if I just got the math right. It wouldn't. The problem wasn't the offset. It was that I skipped the diagnostic step entirely and jumped straight to mounting a disk image I didn't understand yet. This article is about what I should have done first — and how to build a decision tree that actually works under CTF pressure.

The 20-Minute Mistake That Taught Me Everything

The Setup: A 350MB Disk Image That Looked Straightforward

The challenge gave me a single file: disk.img. Running file disk.img returned DOS/MBR boot sector, and I could see ext2 in the output. My brain immediately jumped to: " Okay, it's ext2, I just mount it." That assumption cost me 20 minutes.

$ file disk.img
disk.img: DOS/MBR boot sector; partition 1 : ID=0x83, start-CHS (0x0,33,3), end-CHS (0x4,30,3), startsector 2048, 71680 sectors, code offset 0xb8
Enter fullscreen mode Exit fullscreen mode

I ran mount -o loop disk.img /mnt. Error. I calculated the offset: 2048 × 512 = 1048576. Tried again with -o loop,offset=1048576. Error. I tried different sector sizes. Different offsets. Still the same error.

$ sudo mount -o loop,offset=1048576 disk.img /mnt
mount: /mnt: wrong fs type, bad option, bad superblock on /dev/loop0, missing codepage or helper program, or other error.
Enter fullscreen mode Exit fullscreen mode

Where I Went Wrong: Trusting file Too Much

Here's the thing about file: it identifies format, not integrity. A disk image can look like ext2 and still have a corrupted superblock, a broken partition table, or no actual filesystem data at the expected offset. I was treating file as a green light. It's not. It's just the first clue.

What I should have done — before even thinking about mounting — was check the partition structure with mmls. When I finally ran it, I saw something I hadn't expected: a large unallocated region right after the partition. The partition table wasn't just pointing somewhere I'd miscalculated. It was malformed. No amount of offset math was going to fix that.

The Diagnostic Checklist: What to Do Before Attempting mount

After this experience, I built a habit. Every disk image challenge now starts with the same three steps before I even think about mount.

Step 1 — file: Identify the Format

$ file disk.img
Enter fullscreen mode Exit fullscreen mode

This tells you what you're dealing with — MBR, GPT, qcow2, LUKS, raw ext4, etc. Each one has a different path forward. If file says LUKS encrypted file, you're not mounting anything until you decrypt it. If it says QEMU QCOW Image, you need to convert first.

Step 2 — mmls or fdisk -l: Read the Partition Table

$ mmls disk.img
DOS Partition Table
Offset Sector: 0
Units are in 512-byte sectors

      Slot      Start        End          Length       Description
000:  Meta      0000000000   0000000000   0000000001   Primary Table (#0)
001:  -------   0000000000   0000002047   0000002048   Unallocated
002:  000:000   0000002048   0000073727   0000071680   Linux (0x83)
Enter fullscreen mode Exit fullscreen mode

This is where things get real. mmls shows you the actual partition boundaries and, crucially, any large unallocated regions. A well-designed CTF challenge will often hide data in unallocated space — or damage the partition table just enough to make mount fail while still having valid filesystem data somewhere in the image.

Step 3 — binwalk: Check for Embedded or Hidden Content

$ binwalk disk.img

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
1048576       0x100000        Linux EXT filesystem, blocks count: 71680...
Enter fullscreen mode Exit fullscreen mode

binwalk scans the raw bytes for recognizable signatures. It doesn't care about partition tables. If there's a PNG, a ZIP, or an EXT filesystem header buried anywhere in the image, binwalk will find it. I now always run this before and after mmls, because sometimes the interesting data isn't in the partition — it's in the slack space after it.

The Correct mount Workflow (When Mounting Actually Makes Sense)

After the diagnostic steps confirm the filesystem is structurally intact, mounting becomes straightforward. But two things matter here that beginners often miss.

Calculating the Offset Correctly

The formula is simple: start_sector × sector_size. From the mmls output above, the partition starts at sector 2048 with 512-byte sectors:

$ sudo mount -o loop,offset=$((2048 * 512)),ro disk.img /mnt
$ ls /mnt
lost+found  secret  flag.txt
Enter fullscreen mode Exit fullscreen mode

Using $((2048 * 512)) directly in the shell avoids the mental arithmetic errors I kept making at 2 AM during the competition.

Why -o ro Matters More Than You Think

The ro (read-only) flag felt like an optional best practice the first time I saw it in a Writeup. Then I learned why it's critical: mounting a filesystem read-write updates access timestamps (atime) across every file the OS touches during mounting. In a forensics challenge, those timestamps might be part of the puzzle. Mounting read-write can silently destroy evidence before you even start looking.

Always mount forensics images read-only. Always.

Three Scenarios Where You Should NOT Mount First

This is the part that would have saved me those 20 minutes if I'd known it earlier.

Scenario 1: Broken ext2/ext4 → File Carving with foremost

A challenge that intentionally corrupts the superblock will make mount fail no matter what offset you try. The ext4 superblock contains a magic number (0xEF53) at byte offset 1024 from the partition start. If that's missing or overwritten, the kernel refuses to mount — full stop.

The right tool here is foremost or binwalk -e. These tools don't care about filesystem structure. They carve raw file signatures directly from the binary data:

$ foremost -i disk.img -o ./carved_output
$ binwalk -e disk.img --directory=./extracted
Enter fullscreen mode Exit fullscreen mode

I've seen CTF challenges where the entire filesystem structure is intact except for one zeroed-out byte in the superblock magic. mount fails. foremost recovers every file. The damage was cosmetic, not structural.

Scenario 2: LUKS Encryption → cryptsetup First

If file disk.img returns LUKS encrypted file, ver 1, you're not mounting anything without the passphrase or keyfile. The correct sequence:

$ sudo cryptsetup luksOpen disk.img ctf_volume
Enter passphrase for disk.img:
$ sudo mount /dev/mapper/ctf_volume /mnt -o ro
Enter fullscreen mode Exit fullscreen mode

In CTF challenges with LUKS, the passphrase is usually hidden somewhere else in the challenge — a previous flag, a file in another challenge artifact, or encoded in the challenge description. Don't try to brute force it. Look for the key.

Scenario 3: qcow2 VM Images → Convert to Raw First

QEMU's qcow2 format is a container format. You can't mount it directly as a loop device. Convert to raw first:

$ qemu-img convert -f qcow2 -O raw disk.qcow2 disk_raw.img
$ file disk_raw.img
disk_raw.img: DOS/MBR boot sector ...
$ mmls disk_raw.img

then proceed with normal workflow

Enter fullscreen mode Exit fullscreen mode




Full Trial Process Table

Step Action Command Result Why it failed / succeeded
1 Immediate mount attempt mount -o loop disk.img /mnt ❌ wrong fs type No offset specified; kernel can't find superblock
2 Mount with calculated offset mount -o loop,offset=1048576 disk.img /mnt ❌ wrong fs type Partition table malformed; offset was correct but superblock corrupted
3 Try different sector sizes offset=2048, offset=4096 ❌ still fails Rabbit Hole — the issue wasn't offset math
4 Run mmls to check partition structure mmls disk.img ✅ Found malformed table Revealed the actual problem: broken partition structure
5 Run binwalk to find embedded content binwalk disk.img ✅ Found hidden archive Flag was in a ZIP embedded in unallocated space, not in the filesystem
6 Extract with binwalk binwalk -e disk.img ✅ Flag extracted Correct approach once structure was understood

Beginner Tips: How to Avoid the Rabbit Holes

Common Errors and What They Actually Mean

Error Message What It Usually Means First Thing to Try
wrong fs type, bad superblock Offset wrong OR filesystem corrupted Run mmls to verify offset, then check superblock with debugfs
mount: special device does not exist Loop device exhausted or permissions issue sudo losetup -a to check active loop devices
mount: unknown filesystem type 'LUKS' LUKS encrypted — can't mount directly Use cryptsetup luksOpen first
mount: /mnt: can't read superblock Filesystem integrity issue Try fsck on the loop device, or switch to file carving

The Checklist I Keep Open During Every Disk Challenge

  • Run file first — never assume the format
  • Run mmls before calculating any offsets manually
  • Always use -o ro when mounting forensics images
  • If mount fails twice with different offsets, stop — the problem isn't math
  • Run binwalk on the full image, not just the partition
  • Check unallocated regions — that's where CTF authors hide things

Short Command Reference

Command Purpose When to Use Notes
file disk.img Identify format Always first Doesn't check integrity
mmls disk.img Show partition table and boundaries Before calculating offsets Part of Sleuth Kit
fdisk -l disk.img Alternative partition viewer When mmls isn't available Less forensics-friendly output
binwalk disk.img Scan for embedded file signatures Always, especially when mount fails Finds content regardless of filesystem
binwalk -e disk.img Extract identified content After binwalk identifies targets Creates _disk.img.extracted/ directory
foremost -i disk.img -o ./out Carve files by magic bytes When filesystem is broken Slower but thorough
cryptsetup luksOpen Open LUKS-encrypted volume When file shows LUKS format Requires passphrase or keyfile
qemu-img convert Convert qcow2 to raw When image is qcow2 format Required before any other analysis

What You Learn From This Challenge

The core skill here isn't learning to use mount. It's learning to form a hypothesis about the filesystem state before committing to a tool. mount is a precision instrument — it works perfectly when the filesystem is intact, and fails immediately when it isn't. That's actually useful information.

When mount fails in a CTF, the challenge author usually put it there on purpose. The failure is a signal, not a setback. The question is: what does this failure tell you about the image structure?

In real-world digital forensics, this same mindset applies. Investigators don't mount evidence drives directly — they image them first, verify integrity with hashes, and always work read-only. The CTF challenge is teaching you the same discipline under time pressure.

The next time you see wrong fs type, resist the urge to tweak the offset. Run mmls. Run binwalk. Understand what you're looking at before you decide how to look at it.

Top comments (0)