A disk image (.img) is provided. With mmls we locate the partition table and the starting offset, then fls lists the files in the file system (including deleted ones), and icat lets us extract a file's content via its inode number — revealing the hidden flag.
| Platform | picoGym |
| Category | Forensics |
| Points | 200 pts |
| Difficulty | Intermediate |
| Tools | mmls fls icat The Sleuth Kit |
The challenge provides a single file, disk.img, with no other indication about its contents:
"We've got a suspect's disk image, but they've tried to hide something. Can you find it?"
A disk image is a raw (bit-for-bit) copy of a storage device — USB drive, hard disk, SD card. It contains a partition table and one or more file systems, exactly like a real disk. To explore it without mounting it, we use the The Sleuth Kit (TSK) tool suite, the reference toolkit for digital forensic investigation.
The first step when facing any disk image is figuring out how it's structured: how many partitions it contains and at what offset (in sectors) each one starts. That's the job of mmls (media management list):
$ 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 0000206847 0000204800 Linux (0x83)
003: ------- 0000206848 0000206847 0000000000 Unallocated
We spot a single Linux partition (type 0x83), starting at sector 2048. This offset is what needs to be passed to every following tool.
fls (file listing) lists every file and directory in a file system, including those that have been deleted but whose metadata is still present on the disk:
$ fls -o 2048 disk.img
d/d 11: lost+found
r/r 12: notes.txt
r/r 13: vacation_photo.jpg
r/r * 15: secret.txt
d/d 16: Documents
The -o 2048 option tells fls the offset (in sectors) where the partition found with mmls starts. Each line shows an entry type (r for regular file, d for directory), the inode number, and the file name.
The asterisk * next to inode 15 (secret.txt) is the crucial detail: it means this file has been deleted — its entry in the file system table has been marked as free, but its physical content probably hasn't been overwritten on disk yet.
On such a small disk, two things immediately stand out: the name secret.txt is explicit, and the fact that it's marked as deleted (*) suggests someone tried to cover their tracks after writing something to it. This is exactly the kind of anomaly a forensic investigator looks to recover.
We note its inode number: 15. This reference is what will let us extract its content directly, without going through the file path (which, technically, no longer exists in the table).
icat (inode cat) displays a file's content from its inode number, reading directly from the associated data blocks — whether or not the file is still referenced in a directory:
$ icat -o 2048 disk.img 15
picoCTF{***}
The deleted file's content shows up directly in the terminal — the flag had remained physically present on the disk, despite the logical deletion of its entry.
Summary of the full tool chain used:
# 1. Partition table -> find the offset
$ mmls disk.img
# 2. List files (including deleted ones) at that offset
$ fls -o 2048 disk.img
# 3. Extract the suspicious file's content via its inode
$ icat -o 2048 disk.img 15
The flag is deliberately hidden — follow the method, you've earned it. 💪
This challenge is an excellent introduction to the basics of disk forensics:
mmls → fls → icat chain is the go-to reflex for exploring any raw disk image without having to mount itExtracting a flag sent in plaintext over an HTTP stream captured with Wireshark.
Discuss this writeup with the community on the CTFdojo Discord.
Join the Discord →