Time Capsule
Time Capsule
Platform: tamuctf | Category: Forensics | Type: Challenge | Difficulty: Medium | OS: Linux | Author: XESXOR | Date: 2026-03-22 | Status: Solved Techniques: ascii_decoding, filesystem_forensics, inode_metadata_extraction, timestamp_analysis
Summary
Task: ext4 disk image with 17 image files, flag hidden somewhere. Solution: timestamps encode ASCII via minutes×60+seconds formula, reading files in order spells the flag.
Time Capsule — TAMUctf 2026
Description
My friend Bob found an old drive of his with a bunch of images from his childhood dated back to 2007. You could almost call it a time capsule of sorts. To motivate people to go through the images, he has hidden a flag somewhere. Do you think you could try to find it for me?
Given: time-capsule.tar.gz containing time-capsule.img — a 50MB ext4 filesystem image with 17 image files (memory_1.jpg through memory_17.jpg/png/webp/avif) in /home/bob/nostalgia/.
Goal: Find the hidden flag within the disk image.
Analysis
Initial Reconnaissance
Extracted the tar.gz and identified the file as a Linux ext4 filesystem:
bash read-only • copy allowedtar -xzf time-capsule.tar.gz file time-capsule.img # time-capsule.img: Linux rev 1.0 ext4 filesystem data
Filesystem Analysis with Sleuth Kit
Used fls to recursively list all files:
bash read-only • copy allowedfls -r time-capsule.img
Found 17 image files in /home/bob/nostalgia/ and 3 deleted/orphan inodes (33, 34, 35) — but these had 0 size with no recoverable data.
Dead Ends Explored
- String search — No "gigem" string found anywhere in raw disk image (even searched base64-encoded variants)
- EXIF/metadata — No flag hidden in image metadata
- PNG analysis — No appended data after IEND chunks
- Slack space — No data in slack or unallocated space
- Deleted files — Orphan inodes were empty
- Steganography — No hidden data in pixel values
Key Insight — Timestamps Encode the Flag
The challenge title "Time Capsule" and the specific mention of "2007" were hints pointing at timestamps.
Using istat to examine inode metadata revealed that all files had modification timestamps set to 2007-01-01 10:MM:SS — but with different minute:second values:
bash read-only • copy allowedistat time-capsule.img 17 # memory_1.jpg # Modify: 2007-01-01 10:01:43
The pattern: minutes × 60 + seconds = ASCII character code
Solution
Extract timestamps from each file's inode and decode:
python read-only • copy allowed#!/usr/bin/env python3 import subprocess import re # File inodes in order (memory_1 through memory_17) files = [ (17, "memory_1.jpg"), (18, "memory_2.jpg"), (19, "memory_3.jpg"), (20, "memory_4.jpg"), (21, "memory_5.jpg"), (22, "memory_6.jpg"), (23, "memory_7.jpg"), (24, "memory_8.jpg"), (25, "memory_9.jpg"), (26, "memory_10.jpg"), (27, "memory_11.jpg"), (28, "memory_12.jpg"), (29, "memory_13.jpg"), (30, "memory_14.png"), (31, "memory_15.webp"), (32, "memory_16.avif"), (16, "memory_17.jpg"), ] flag = "" for inode, name in files: result = subprocess.run( ["istat", "time-capsule.img", str(inode)], capture_output=True, text=True ) # Extract modification time (format: 2007-01-01 10:MM:SS) match = re.search(r"Modify:\s+\d{4}-\d{2}-\d{2}\s+10:(\d{2}):(\d{2})", result.stdout) if match: minutes, seconds = int(match.group(1)), int(match.group(2)) ascii_val = minutes * 60 + seconds char = chr(ascii_val) flag += char print(f"{name}: 10:{minutes:02d}:{seconds:02d} → {minutes}×60+{seconds} = {ascii_val} → '{char}'") print(f"\nFlag: {flag}")
Decoding Table
| File | Timestamp | Calculation | ASCII | Char |
|---|---|---|---|---|
| memory_1 | 10:01:43 | 1×60+43 | 103 | g |
| memory_2 | 10:01:45 | 1×60+45 | 105 | i |
| memory_3 | 10:01:43 | 1×60+43 | 103 | g |
| memory_4 | 10:01:41 | 1×60+41 | 101 | e |
| memory_5 | 10:01:49 | 1×60+49 | 109 | m |
| memory_6 | 10:02:03 | 2×60+3 | 123 | { |
| memory_7 | 10:01:38 | 1×60+38 | 98 | b |
| memory_8 | 10:02:01 | 2×60+1 | 121 | y |
| memory_9 | 10:01:43 | 1×60+43 | 103 | g |
| memory_10 | 10:00:48 | 0×60+48 | 48 | 0 |
| memory_11 | 10:01:50 | 1×60+50 | 110 | n |
| memory_12 | 10:00:51 | 0×60+51 | 51 | 3 |
| memory_13 | 10:01:35 | 1×60+35 | 95 | _ |
| memory_14 | 10:00:51 | 0×60+51 | 51 | 3 |
| memory_15 | 10:01:54 | 1×60+54 | 114 | r |
| memory_16 | 10:00:52 | 0×60+52 | 52 | 4 |
| memory_17 | 10:02:05 | 2×60+5 | 125 | } |
| |