Description
Can you find the flag in this disk image? Wrap what you find in the picoCTF flag format.
Download and decompress the disk image.
Mount or analyze the image to explore the filesystem and its metadata.
gunzip partition4.img.gzsudo mount -o loop partition4.img /mnt/diskSolution
Want to try it yourself first?
The guided walkthrough reveals hints one step at a time.
Step 1Decompress the image
ObservationThe raw partition image is inside a gzip container, and no filesystem tool can read it until that comes off.Extract the raw partition image from the gzip archive.bashgunzip partition4.img.gzWhat didn't work first
Tried: Mounting the .gz file directly with sudo mount -o loop partition4.img.gz /mnt/disk before decompressing.
mount reads a gzip header where it expects a filesystem signature and rejects the file. The partition image is inside the archive; extract it first.
Tried: Using tar -xzf partition4.img.gz instead of gunzip to decompress.
tar wants a tar archive and says so when it does not find one. This is a single file compressed with gzip and no tar container, so gunzip is the tool.
Learn more
Raw disk partition images are forensically complete snapshots of a storage partition. Unlike filesystem-level copies (like
cp -r), they capture every bit on the partition: live files, deleted files, slack space (unused space within file clusters), unallocated space (sectors not belonging to any file), filesystem journal entries, and all metadata structures. This completeness is essential for forensic analysis where evidence may exist in unexpected locations.Timeline-1 is the second part of the timeline challenge series and uses a different disk image than Timeline-0 (note the different URL hash). While both challenges use the same methodology (fls + mactime), the specific filesystem content differs, meaning the flag is in a different location or encoded differently. Treating each disk image as an independent investigation is the correct approach.
Step 2Build a filesystem timeline
ObservationThis follows directly from Timeline-0 with another disk image, so run the same fls and mactime workflow and get a timestamp-sorted timeline before looking for anything.fls -mproduces a body file with MAC timestamps for every inode TSK can read.mactime -b body.txt -dsorts that into a comma-delimited (-d= delimited / CSV-style) timeline you can grep.bashfls -m '/' -r partition4.img > body.txtbashmactime -b body.txt -d > timeline.csvExpected output
573417h13r_7h4n_7h3_1457_58527bb222
What didn't work first
Tried: Running fls without the -m flag to list files, then grepping for 'picoCTF' in the output to find the flag directly.
Without that flag, fls prints filenames and no timestamps, and no filename here holds the flag; it is encoded in file content. The body file format is what mactime parses and sorts, and that sorting is what reveals the anomaly.
Tried: Skipping mactime and grepping the body.txt output directly for suspicious filenames.
The body file is pipe-delimited with raw epoch timestamps and unreadable without conversion. And the suspicious file has an unremarkable name that blends right in: the anomaly only appears once mactime collapses its four identical timestamps into one row.
Learn more
Why
flsautodetects the filesystem. TSK probes the image's superblock / boot sector signatures: ext4's magic number0xEF53at offset 0x438, NTFS'sNTFSsignature at offset 3 of the boot sector, FAT's OEM identifier and BPB layout, HFS+'sH+at offset 1024, APFS's container superblock magic. If a known signature matches, fls picks the right parser and you don't pass-fmanually. (When in doubt:fsstat partition4.imgprints the detected type explicitly.)Allocated vs deallocated inodes. On ext4/NTFS, file metadata (timestamps, permissions, size, block pointers) lives in inode/MFT entries, separate from the directory entries that map names to inodes. When a file is deleted, the directory entry is often cleared first (or marked unused), and the inode is marked deallocated - but the metadata bytes are not zeroed.
fls -rwalks both allocated and deallocated inode entries, so deleted-file metadata persists in the timeline even if the data blocks have been reused. This is the entire reason filesystem timelines work for forensics.What
-dactually does.mactime -demits comma-delimited output (CSV-style) instead of the default human-readable columnar format. CSV is what you want for grep, awk, and spreadsheet imports. There's also-y(ISO 8601 dates) and-z UTC(force timezone), which keep results deterministic across machines.On a real system disk the CSV can run into millions of rows. For this challenge the key next move is not grepping for picoCTF (the flag does not appear in the timeline output as a filename or path), but filtering for entries where all four MACB timestamp types fire together - that pattern reveals timestomping. See the Volatility 3 guide for the in-memory equivalent of this workflow.
Step 3Spot the timestomped file
ObservationThe hint says the flag is in file content rather than a filename, so the planted file is camouflaged by timestomping. Grep the timeline for rows where all four timestamps fire at once.Filter the timeline for entries where all four MACB timestamp slots fire at exactly the same instant - that pattern (macb appearing as a single combined event on one row) betrays deliberate timestamp manipulation. Among the results,.ash_history(the ash/Alpine shell history file) stands out: reading it via icat with its inode number reveals the only recorded command waspower off, which is the anti-forensic action the hints reference. Next, look for other files with timestamps clustered near that same moment; /etc/chat appears there and is a second red flag because it is not a standard Linux config file.bashgrep 'macb' timeline.csv | tail -n 30What didn't work first
Tried: Grepping the timeline for 'picoCTF' to find the flag directly without filtering for macb entries.
No filename or path in the timeline contains the flag; it is base64 inside a file's content. Grepping the timeline for the prefix returns nothing, which reads as the whole approach being wrong. Filtering on the four-timestamp rows is the pivot that names the inode to open.
Tried: Filtering for 'macb' in the timeline but focusing only on .ash_history and treating its 'power off' content as the flag.
The shell history shows the anti-forensic move, powering off to hide evidence, and holds no flag: its content is that one command. The flag is in a separate timestomped entry further down the timeline.
Learn more
What timestomping looks like in the output. The mactime CSV has a column for which timestamp type fired:
m(modified),a(accessed),c(changed / inode-changed),b(born / created). When an attacker uses a tool liketouch -tordebugfsto set all four timestamps to the same value, mactime collapses them into a single row flaggedmacb. Legitimate files almost never have all four timestamps identical to the nanosecond on a live system, so this pattern is a reliable indicator of tampering.In this image, /etc/chat (inode 32716) shows the
macbpattern. The name/etc/chatis not a standard Linux system file, which is a second red flag: a planted file hiding in a directory that looks like a normal config location.Step 4Extract the file content with icat and base64-decode
ObservationThat filter turns up /etc/chat, a non-standard file whose four timestamps are identical. Read its data blocks with icat and decode the base64.icat reads the data blocks pointed to by an inode and writes them to stdout, bypassing the directory layer entirely. First use icat with the .ash_history inode to confirm the only recorded command ispower off- the deliberate anti-forensic action. Then extract /etc/chat (inode 32716), which holds a base64-encoded string; pipe through base64 -d to recover the flag inner content, then wrap it as instructed.bashicat partition4.img <ash_history_inode>bashicat partition4.img 32716bashicat partition4.img 32716 | base64 -dWhat didn't work first
Tried: Mounting the image and using cat /mnt/disk/etc/chat instead of icat to read the file content.
Mounting works for allocated files, but a timestomped file may have inconsistent directory entry state, and a path gives you no control over which inode you actually read. If the file were deleted, which is common in these scenarios, a mount finds nothing. icat reads blocks by inode straight from the image, whatever the directory layer says.
Tried: Piping the icat output through base64 -e (encode) instead of base64 -d (decode).
The file already holds base64. Encoding it again adds a second layer that decodes back to the first, not to the flag. Decode instead.
Learn more
Why icat instead of cat. Once you have the inode number from the timeline,
icatis the correct tool: it bypasses the directory layer and reads the raw data blocks associated with that inode directly from the partition image.catwould require the file to be accessible via a mounted path, which may not work cleanly for timestomped or partially deleted entries.The raw output of
icat partition4.img 32716is a base64-encoded string (NTczNDE3aDEzcl83aDRuXzdoM18xNDU3XzU4NTI3YmIyMjIK). Piping that throughbase64 -dyields the flag inner content:573417h13r_7h4n_7h3_1457_58527bb222. Wrap that inpicoCTF{}as the challenge instructs to get the complete flag.
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{573417h13r_7h4n_7h3_1457_...}
The flag is hidden in the content of /etc/chat (inode 32716), a timestomped file detectable by its identical MACB timestamps. Extract with icat and base64-decode to get the inner value.