# A timeline row's MACB flags (bodyfile convention): M = Modified # content changed A = Accessed # read (often disabled on modern Win) C = Changed # MFT record / metadata changed ($SI) B = Born # created # NTFS keeps TWO timestamp sets per file: # $STANDARD_INFORMATION ($SI) — shown in Explorer, USER-writable # $FILE_NAME ($FN) — set by kernel, NOT trivially settable
# Timestomping edits $SI but usually leaves $FN intact. # Red flags: - $SI < $FN # file "created" before its FN entry - $SI sub-second == 0 # zeroed nanoseconds = tool artifact - $SI far from $UsnJrnl / $LogFile activity for that record # MFTECmd surfaces both sets side by side: MFTECmd.exe -f "C:\$MFT" --csv . --csvf mft.csv # then compare SI* vs FN* columns in Timeline Explorer
# 1) Build a bodyfile from a disk image (all files, incl. deleted) fls -r -m C: -o 2048 disk.dd > body.txt # -o = partition start sector # or point at a single filesystem/partition image with no -o # 2) Turn the bodyfile into a sorted CSV timeline mactime -b body.txt -d > timeline.csv # -d = comma-delimited mactime -b body.txt -d 2026-09-01..2026-09-30 > sept.csv # Recover deleted entries / inode content while you are here fls -rd disk.dd # list deleted files icat disk.dd <inode> > out # dump file content by inode
# Parse EVERYTHING (FS + registry + evtx + browser + prefetch...) log2timeline.py --storage-file out.plaso disk.dd # scope parsers to go faster: log2timeline.py --parsers "winevtx,winreg,prefetch" \ --storage-file out.plaso disk.dd # Inspect what was collected pinfo.py out.plaso # Emit a CSV timeline (l2tcsv is the classic wide format) psort.py -o l2tcsv -w timeline.csv out.plaso
# Date-slice (huge speed + noise win) psort.py -o l2tcsv -w day.csv out.plaso \ "date > '2026-09-28 00:00:00' AND date < '2026-09-30 00:00:00'" # Focus around a pivot event (+/- N minutes) psort.py --slice "2026-09-29 14:03:00" --slice-size 15 \ -o l2tcsv -w window.csv out.plaso # Or push straight into Timesketch for interactive review psort.py -o timesketch out.plaso
# $MFT → CSV, open in Timeline Explorer (TLE) and sort by date MFTECmd.exe -f "C:\$MFT" --csv . # $MFT → bodyfile (feed into mactime for a TSK-style timeline) MFTECmd.exe -f "C:\$MFT" --body . --bdl C: # Registry / evtx / prefetch → CSV, all TLE-loadable RECmd.exe --bn BatchExamples\Kroll.guid -d C:\ --csv . EvtxECmd.exe -d C:\Windows\System32\winevt\Logs --csv .
# KAPE: triage-collect then run EZ Tools modules automatically kape.exe --tsource C: --target !SANS_Triage --tdest out \ --mdest mout --module !EZParser # forensic-timeliner (2025): merge EZTools + Chainsaw + # Hayabusa CSV output into ONE mini super-timeline forensic-timeliner.exe --source mout --out combined.csv # Chainsaw also builds execution timelines from Shimcache/SRUM chainsaw analyse shimcache --mft $MFT --output shim_tl.csv
| Step | Why / how |
|---|---|
| anchor first | Find one known event (a download, a login, the flag file's ctime) → slice ±15 min around it, don't read the whole timeline |
| reduce noise | Date-slice at psort/mactime; drop $SI-Access rows; exclude Windows-update churn |
| correlate sources | A super-timeline interleaves FS + evtx + registry + browser — the story is where they line up on the same second |
| watch timezones | Plaso is UTC by default (-z to set); evtx local vs UTC mismatches fake "impossible" ordering |
| trust $FN over $SI | When times disagree, $FN and $UsnJrnl are the harder-to-forge ground truth |
log2timeline.py --storage-file out.plaso img then date-slice
② Just NTFS? → fls -r -m C: img > body; mactime -b body -d
③ Windows triage? → KAPE !EZParser → Timeline Explorer
④ Timestomp? → compare $SI vs $FN in MFTECmd output
⑤ Anchor on one known event, slice ±15 min, then widen