Category: Forensics
Difficulty: Medium
Points: 200
Description
A compressed disk image (disk.flag.img.gz) is provided. The flag is stored in a file somewhere on the filesystem. The challenge requires navigating the disk image using The Sleuth Kit without mounting it.
Overview
- The Sleuth Kit (TSK) is a collection of command-line tools for analyzing disk images at the partition and filesystem level.
- The workflow is: decompress the image, list partitions with
mmls, list files withfls, then extract file content withicat. - The flag file is at
/root/my_folder/flag.uni.txt.
Background: The Sleuth Kit
mmlsreads the partition table of a disk image and reports each partition’s starting offset (in sectors).flslists files and directories in a filesystem at a given partition offset, identified by inode number.icatextracts the raw content of a file by its inode number, without needing to mount the image.- The
-oflag on bothflsandicatspecifies the partition start offset so TSK knows where the filesystem begins.
Solution
Step 1: Decompress the Disk Image
run_bash(["gunzip", "disk.flag.img.gz"])
Step 2: List Partitions with mmls
mmlsprints a table of partitions with their start sectors.- The relevant partitions are at rows index 5+ after the header; the third column is the start sector.
out, _ = run_bash(["mmls", "disk.flag.img"])
offsets = [line.split()[2] for line in out.splitlines()[5:]]
Step 3: Find the Root Filesystem
- Iterate over partition offsets and run
flsat each. - The correct partition is the one whose root directory listing contains a
rootentry.
for offset in offsets:
out, _ = run_bash(["fls", "-o", offset, "disk.flag.img"])
if "root" in out:
break
Step 4: Navigate to the Flag File
flsoutput has the formatTYPE INODE: PATH.- Navigate into
/root, then intomy_folder, then locateflag.uni.txtby filtering each listing.
# Get inode of /root directory
root_inum = [row[1] for row in parsed if "root" in row[2]][0]
# List /root
out, _ = run_bash(["fls", "-o", offset, "disk.flag.img", root_inum])
# Get inode of my_folder
folder_inum = [row[1] for row in parsed if "my_folder" in row[2]][0]
# List my_folder
out, _ = run_bash(["fls", "-o", offset, "disk.flag.img", folder_inum])
# Get inode of flag.uni.txt
flag_inum = [row[1] for row in parsed if "flag.uni.txt" in row[2]][0]
Step 5: Extract the File Content with icat
icattakes the offset and the inode number and prints the file contents.
out, _ = run_bash(["icat", "-o", offset, "disk.flag.img", flag_inum])
result = out.strip()
Flag
picoCTF{by73_5urf3r_2f22df38}