Timeline Forensics on Windows: Plaso, Log2Timeline and KAPE in Practice
Building super-timelines of a compromised Windows 11 test VM with KAPE for triage collection and Plaso parsing 200+ artifacts.

Three in the morning, an incident call, and all you have is a Windows 11 VDI with suspected payload execution at 22:47 the day before. No real EDR, no SIEM aggregating logs, just the live machine and forty minutes to deliver a hypothesis. That is the scenario where timeline forensics stops being an academic exercise and becomes the difference between saying the attacker used rundll32 loading a DLL from %AppData%\Roaming\winlog at 22:47:13, and shrugging. This post builds the lab that replicates exactly that pressure on an isolated Windows 11 inside VMware Workstation, and drives Plaso, log2timeline and KAPE from collection to a defensible narrative.
Why timeline forensics decides the case
A single artifact lies easily. An EVTX entry can be cleared, a timestamp can be timestomped, a log can rotate. Timeline forensics wins because it merges independent sources onto one shared timeline: filesystem metadata from the MFT, execution traces from Prefetch and Amcache, Registry persistence, EVTX events, SRUM network usage. Where three independent artifacts testify to the same moment, guesswork becomes evidence. This mindset is the defensive flip side of what we describe as proactive hunting in Hunting Living-off-the-Land Binaries on Windows with KQL and Threat Hunting with Sigma and Elastic: From Indicator to Detection Rule. The real advantage of a timeline is that it exposes causality: not just what happened, but in what order and with what spacing. If a DLL lands on disk two seconds before a process start and an outbound connection opens three seconds after, you get a narrative no single log can produce. That reconstruction of sequence is what separates a forensic statement from speculation. Timeline is not about collecting everything, it is about making time testify against the wrong hypothesis.
The stack: KAPE, Plaso, Timesketch
The stack is simple and repeatable: Eric Zimmerman's KAPE for triage collection (Targets like !SANS_Triage take under three minutes), Plaso 20240308 running inside an Ubuntu 24.04 container with 16 GB of dedicated RAM, plus Timeline Explorer for the fast view and Timesketch for collaborative navigation. KAPE collects without breaking the chain of custody because it pulls forensically clean copies with hashes. Plaso then normalizes dozens of artifact types into a single searchable super-timeline. Timeline Explorer gives you a grid, filters and color-coding; Timesketch gives you tags, stories and shared views for the team. Each tool has its place, and the combination is more powerful than any single one.
The lab setup
I build the lab on an isolated Windows 11 inside VMware Workstation, with clean snapshot, simulated post-infection snapshot and a controlled detonator, fully host-only with no internet. The default flow is snapshot, detonate sample (I use inert variants generated in the lab described at Malware Analysis in an Isolated Lab: Safe Setup with FlareVM and REMnux), collect with KAPE to a VHDX, mount read-only on the analysis host, and fire log2timeline.py against the mount point. On modest hardware, an 80 GB disk with 18 GB used produces a plaso storage of about 1.2 GB in around 22 minutes. The isolated setup is mandatory: a detonator without a network block contacts real C2 and makes you part of the problem.
Collection with KAPE: Targets and Modules
People new to KAPE find the Targets and Modules model strange, but it is what makes collection defensible in a legal context. Targets copy raw artifacts, Modules parse them with external tools. I keep a custom .tkape that adds PowerShell\Operational, WMI-Activity and TaskScheduler on top of the standard triage targets, plus a module that runs RECmd with Zimmerman's batch files to extract UserAssist, ShellBags, TypedPaths and the RunMRU set. That gives me a Triage\ directory ready for Plaso and a Modules\ directory with already-parsed CSVs. For an incident on an endpoint segmented behind a pivoting network (a scenario I cover in Pivoting with Chisel and Ligolo-ng: Segmented Networks in a Pentest Lab), KAPE runs locally and exports to an authenticated share, avoiding heavy traffic.
Building the super-timeline with log2timeline
Against the read-only mount I fire log2timeline.py --storage-file case.plaso /mnt/evidence. Plaso auto-detects artifacts, but in triage I deliberately enable the winreg, prefetch, mft, usnjrnl, winevtx, srum, amcache, shimcache and bam parsers instead of running everything, which multiplies runtime. For VSS I add --vss-stores all to lift deleted persistence out of shadow copies. The storage grows fast: a raw super-timeline easily returns eight million events. That is not a bug, it is raw material. Value only appears in the next step, filtering. The key is to generate the storage once cleanly and then only slice from it with psort.py rather than running log2timeline multiple times.
Filtering and slicing with psort
The gold is not in running the tool, it is in knowing how to filter. I always start by slicing a plus/minus thirty minute window around the known indicator with psort.py -o l2tcsv --slice '2026-01-14T22:47:13' --slice_size 30 case.plaso. That cut reduces from eight million to about fourteen thousand lines. Then I filter by MFT, EVTX and Registry sources and load Timeline Explorer with colorization by type. You can narrow further with a psort filter file that only admits relevant artifact sources and a time range. The reflex to read the whole super-timeline is the most common beginner mistake; the craft is anchoring on a temporal IOC and radiating out from there.
Crossing artifacts: Prefetch, Amcache, MFT, UsnJrnl, EVTX
A concrete example from the last lab: the detonator was an LNK pointing to powershell.exe -enc, a pattern similar to the one studied in Simulated Initial Access: Macros, LNK and ISO in an Isolated Windows 11 Lab. The first lead did not come from EVTX, it came from Prefetch (POWERSHELL.EXE-7644F8E2.pf created at 22:47:09, four seconds before the execution logged in Security 4688), and from Amcache.hve showing the SHA1 hash of the satellite DLL that came in via BITS. UsnJrnl confirmed file creation at C:\Users\elias\AppData\Roaming\winlog\runner.dll at 22:46:58, with the MFT $SI timestamp matching $FN, meaning no timestomping in this case. That cross of three independent artifacts is what validates the hypothesis; a single one lies easily.
Three traps that cost hours
First: timezone. Plaso normalizes to UTC by default, but EVTX stores in UTC and some Registry artifacts store local time disguised as UTC. I always run with --timezone UTC and document the machine offset explicitly in the report. Second: VSS. Volume Shadow Copies hide previous versions of NTUSER.DAT and can reveal persistence that was wiped; KAPE collects with --vss and Plaso processes with --vss-stores all. Third: noisy EVTX parsers (Microsoft-Windows-Kernel-General generates millions of lines) must be pruned or you waste analysis time. Related defensive techniques live in Windows Persistence: 10 Documented Techniques and Their Countermeasures.
Timesketch and the handoff
To deliver the finding, I export the relevant slice to Timesketch (docker compose up, ingest the plaso storage directly), create a sketch with tags like execution, persistence, c2_beacon, and generate a report with the stories feature. That becomes direct input for Sigma rules feeding future detection, closing the loop described in Purple Team in Practice: Building a Red vs Blue Feedback Loop. Every tagged event becomes a traceable statement, every story a thesis with evidence. That way a night triage produces not just a report but a detection artifact that surfaces the next incident earlier.
Practical checklist
First: snapshot before detonation, everything host-only. Second: KAPE triage with an extended .tkape (PowerShell, WMI, TaskScheduler). Third: read-only mount of the evidence on the analysis host. Fourth: log2timeline with only the relevant parsers plus --vss-stores all. Fifth: slice a thirty-minute window around the IOC with psort --slice. Sixth: filter by MFT, EVTX, Registry, Prefetch and Amcache and color-code in Timeline Explorer. Seventh: cross at least three independent artifacts before making a statement. Eighth: document the timezone, include VSS, prune noisy parsers. Ninth: slice to Timesketch, tag, write a story, derive a Sigma rule. Walk these nine steps with discipline and you deliver a defensible hypothesis in forty minutes.
FAQ
Why not just take the EDR alert? Because in a real incident there is often no EDR running, the alert has gaps, or the attacker cleared logs. Timeline forensics reconstructs the sequence from filesystem and Registry artifacts that are harder to erase completely, and crosses them so that a single manipulation stands out.
Is KAPE alone enough or do I need Plaso? KAPE collects and parses selectively, but the temporal correlation across dozens of artifact types is what Plaso delivers with the super-timeline. In practice you use both: KAPE for the fast, clean collection, Plaso for the unified timeline, Timesketch for handoff and detection.
Conclusion
Timeline forensics is not hoarding, it is discipline: anchor on a temporal IOC, slice a narrow window, cross at least three independent artifacts, and only then write the narrative. The KAPE, Plaso and Timesketch stack makes that reproducible and legally defensible. Practical takeaway: do not try to read eight million events. Anchor on the IOC, slice thirty minutes, cross Prefetch, Amcache, MFT and EVTX, and make time testify against the wrong hypothesis. That is exactly what separates a defensible narrative from a shrug at three in the morning.


