Description
All we know is the file is called 'down-at-the-bottom.txt'. Use Sleuth Kit inode tools on dds2-alpine.flag.img.gz to find and read it.
Setup
Download and decompress the disk image.
wget <url>/dds2-alpine.flag.img.gzgunzip dds2-alpine.flag.img.gzSolution
Want to try it yourself first?
The guided walkthrough reveals hints one step at a time.
Step 1Find the partition offset with mmls
ObservationThe challenge provides a raw disk image, not a bare filesystem, so there is a partition table in front. Find where the target partition starts before any Sleuth Kit tool can read it.Run mmls to print the partition table. The Linux partition's starting sector is what you'll feed to -o on the next commands.bashmmls dds2-alpine.flag.imgWhat didn't work first
Tried: Run fls directly on the raw image without the -o offset, e.g. fls dds2-alpine.flag.img
Without -o, fls reads the very start of the image as a filesystem superblock and finds the MBR partition table instead, so it returns no entries or an error about not determining the file system type. The ext2 filesystem starts at sector 2048, not sector 0, and mmls is what tells you that.
Tried: Skip mmls and guess the offset by trying common values like -o 63 or -o 512
Older MBR-partitioned disks put the first partition at a 63-sector offset, but modern images, this one included, align to 2048-sector boundaries. -o 63 gives an invalid superblock error. Read the offset from the partition table with mmls rather than assuming it.
Learn more
Sample mmls output on this image:
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 0000262143 0000260096 Linux (0x83)The Linux partition starts at sector 2048, so every subsequent TSK command needs
-o 2048.Step 2Find the file's inode number with fls
ObservationThe challenge names the target file, down-at-the-bottom.txt, but gives no path and no inode. fls can list every filesystem entry recursively from the partition offset, and grepping that output produces the inode.Use fls to list filesystem entries in the image. The -r flag recurses, -p prints full paths, -o 2048 is the partition offset from mmls. Grep for the filename and read the inode column.bashfls -r -p -o 2048 dds2-alpine.flag.img | grep down-at-the-bottomWhat didn't work first
Tried: Mount the disk image with mount -o loop,offset=1048576 and then use find to locate the file
Computing the byte offset, 2048 sectors times 512 bytes, and mounting does work on a live system with root. But forensic practice avoids mounting evidence images, because the OS may write access-time updates or journal entries and alter the image. fls reads the filesystem structures directly, read-only.
Tried: Run fls without -r and manually navigate directories by inode, passing each directory inode back to fls
fls without -r lists one directory at a time, leaving you to descend into each subdirectory by hand. The -r flag recurses on its own, and piping to grep is far faster. The manual route also needs the root inode, usually 2 on ext2, which is another step.
Learn more
Reading fls output. A typical line looks like this; the inode number is the second column:
r/r 18582: root/down-at-the-bottom.txt ^ ^ ^ | | path (full because of -p) | inode (this is what you pass to icat) type (regular file / regular file)Inodes are the data structures in Unix filesystems (ext2/3/4, UFS) that store file metadata: permissions, timestamps, owner, and pointers to the data blocks. Every file and directory has an inode number. The filename is stored in the directory entry, which maps names to inode numbers.
fls (file listing) from The Sleuth Kit lists directory entries directly from the raw disk image without mounting it. The partition offset
-o 2048tells TSK where the filesystem starts within the disk image (in 512-byte sectors), exactly the value mmls reported.Step 3Extract the file contents with icat
Observationfls returns the inode number, and the prompt asks for Sleuth Kit inode tools. icat is the one that reads a file's data blocks straight out of the raw image given nothing but that inode.Use icat with the inode number found in the previous step to extract and print the file contents. icat reads file data blocks directly from the raw image given just the inode number.bashicat -o 2048 dds2-alpine.flag.img <inode_number>What didn't work first
Tried: Use icat without -o 2048, running icat dds2-alpine.flag.img <inode_number>
Without the partition offset, icat reads the start of the raw image as a filesystem, but that region is the MBR, not ext2. It either errors out or returns garbage data blocks rather than the file. Every TSK command touching files inside the partition needs -o 2048.
Tried: Copy the inode number from the fls column but accidentally use the file type prefix digits instead
The fls line reads 'r/r 18582: root/down-at-the-bottom.txt'. The inode is 18582, but the r/r type prefix and the colon make it easy to copy the wrong thing. A wrong number sends icat to an unrelated inode's data blocks, giving garbled output or nothing at all.
Learn more
icat (inode cat) extracts the content of a file given its inode number, reading directly from the raw disk image. This works even for deleted files (whose directory entries have been removed but whose inode and data blocks have not yet been overwritten). It is a key tool in deleted file recovery.
The workflow of
fls(find inode) followed byicat(extract content) is the standard TSK pattern for targeted file recovery from disk images, equivalent tofindpluscaton a live filesystem but operating on the raw image. For memory-side forensics with a similar inspect-without-mounting workflow, see Volatility 3 for memory forensics.
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{f0r3ns1c4t0r_n0v1c3_...}
fls lists filesystem entries (including deleted files) by inode; icat extracts a file's content given its inode number - critical for deleted file recovery.