All blog posts

Hunting APTs with Windows Prefetch: A Practical, Analyst-First Guide

For incident responders, SOC analysts, and threat hunters • Windows 10/11 & Windows Server • Splunk & Elastic queries included

It’s 02:07, the SOC is quiet, and your only clue is a whisper of activity on a finance workstation. There’s no EDR hit, no helpful command line. What is there is older, simpler, and surprisingly stubborn to erase: Windows Prefetch.

Built for performance, Prefetch captures what executables touch on launch and when they were last seen. For responders, that’s a durable pivot: a way to reconstruct operator sessions, find staging directories, and scope a campaign—especially when logs are thin or tampered with.

This post is a hands-on guide to Prefetch for Windows 10/11 and Windows Server, with concrete hunts, detections, and workflows you can use today.


Prefetch 101: What It Is (and Isn’t)

Purpose. Prefetch speeds application launches by recording the files an executable typically loads. Windows then “prefetches” those reads next time.

Where it lives.

C:\Windows\Prefetch\

What the files look like.

<EXECUTABLE_NAME>-<PATH_HASH>.pf

That hash disambiguates same-named binaries launched from different paths (e.g., a legit rundll32.exe in System32 versus a planted copy in C:\ProgramData\).

Why responders care. Each .pf file often contains:

  • Executable name and (resolvable) image path
  • Multiple last-run timestamps (typically up to eight) and a run count
  • File metrics: DLLs and support files touched during start-up—frequently including scripts and staging folders
  • Volume info to help locate where things lived

Important caveats.

  • Prefetch is usually enabled on Windows 10/11 clients. On Windows Server, behavior varies by version, image, and policy—some environments reduce or disable it.
  • Executions directly from network paths (and some removable media cases) typically do not generate Prefetch.
  • It won’t give you command lines; pair with Amcache, Event Logs, EDR, and MFT/USN for full context.

Narrative: A Midnight Walkthrough

Picture a finance laptop, HOST-FIN-01. At 02:05, a .pf file updates for RUNDLL32.EXE. Minutes later, three new runs of POWERSHELL.EXE. At 02:20, 7Z.EXE shows up for the first time on that host, touching a sensitive share. At 02:28, RCLONE.EXE appears with a configuration file in %TEMP%.

Even if you missed the command lines or the operator cleared a few Windows logs, Prefetch sketches the sequence: loader → script runner → archiver → exfil tool. With just that, you can set priorities—quarantine, scope other machines, and search for those same binaries or staging paths elsewhere in the estate.

Collection & Parsing (Triage to Enterprise)

Triage (single system).

  1. Copy C:\Windows\Prefetch\*.pf read-only (live response or from VSS).
  2. Parse locally for quick wins; export to CSV/JSON for correlation.

At scale. Collect via your IR agent or KAPE; parse with a DFIR tool and forward to Splunk/Elastic. Normalize fields like: hostname, pf_name, image_name, image_path, run_count, last_run_1..8, first_seen, last_run, file_metrics, volume.

Parser example.

PECmd.exe -d C:\Windows\Prefetch --csv C:\IR\out\ --json C:\IR\out\
    

Pro tip: Don’t “browse” the Prefetch directory on a live system with tools that might write; copy out first.

Analyst Playbooks That Catch Real Operator Tradecraft

1) LOLBin Abuse (blend-in tactics)

APT operators love native tools—rundll32.exe, regsvr32.exe, mshta.exe, powershell.exe, wmic.exe, certutil.exe, bitsadmin.exe, schtasks.exe, cscript.exe/wscript.exe, forfiles.exe.

Prefetch tells you: whether those binaries ran, if they ran from non-system paths, and which files/scripts they touched on launch.

2) Lateral Movement Footprints

When PsExec is used, you’ll often find PSEXESVC.EXE-*.pf on the remote target—a high-confidence lateral indicator. Correlate with service installs, admin share access, and Amcache/MFT.

3) Staging, Compression, and Exfil

Archive tools (7z.exe, rar.exe, tar.exe) and movers (rclone.exe, curl.exe, bitsadmin.exe) pop in Prefetch. If they’re new to the host and appear late in the intrusion, investigate.

4) Masquerading & Renames

Renamed binaries (svchosts.exe, chrome_update.exe) still load tell-tale DLLs/configs. Prefetch run bursts (multiple last runs within minutes) reveal hands-on-keyboard windows.

Splunk & Elastic: Detections You Can Deploy

Data assumptions: your Prefetch parser populated fields like hostname, image_name, image_path, run_count, last_run, last_run_1..8, first_seen, file_metrics.

Splunk – LOLBins from non-system paths

index=prefetch sourcetype=prefetch
| search image_name IN ("RUNDLL32.EXE","REGSVR32.EXE","MSHTA.EXE","POWERSHELL.EXE","WMIC.EXE","CERTUTIL.EXE","BITSADMIN.EXE","SCHTASKS.EXE","CSCRIPT.EXE","WSCRIPT.EXE","FORFILES.EXE")
| where NOT like(image_path, "C:\\Windows\\%")
| stats dc(hostname) as hosts_seen values(hostname) as hosts values(image_path) as paths count by image_name
| sort - hosts_seen, count

Splunk – New archive/exfil tools (7 days)

index=prefetch sourcetype=prefetch image_name IN ("7Z.EXE","RAR.EXE","TAR.EXE","RCLONE.EXE","CURL.EXE")
| eval first_seen=_time if(isnull(first_seen),_time,relative_time(strptime(first_seen,"%Y-%m-%d %H:%M:%S"), "@d"))
| where _time>=relative_time(now(), "-7d@d")
| stats min(first_seen) as first_seen values(image_path) as paths by hostname, image_name
| convert ctime(first_seen)

Splunk – PsExec remote execution marker

index=prefetch sourcetype=prefetch image_name="PSEXESVC.EXE"
| timechart span=1h count by hostname

Elastic (KQL) – LOLBins from non-system paths

index : prefetch AND
image_name.keyword : ("RUNDLL32.EXE","REGSVR32.EXE","MSHTA.EXE","POWERSHELL.EXE","WMIC.EXE","CERTUTIL.EXE","BITSADMIN.EXE","SCHTASKS.EXE","CSCRIPT.EXE","WSCRIPT.EXE","FORFILES.EXE") AND
NOT image_path.keyword : "C:\\Windows\\*"

Elastic (ES|QL) – New archive/exfil tools (7 days)

FROM prefetch
| WHERE image_name IN ("7Z.EXE","RAR.EXE","TAR.EXE","RCLONE.EXE","CURL.EXE")
  AND @timestamp >= NOW() - INTERVAL 7 DAYS
| STATS first(min(first_seen)) BY hostname, image_name

Dashboard ideas: New executables by host (14d), LOLBin last-run timeline, Rare Prefetch by host count, Archive/exfil tools heatmap.

Windows Server Nuances

  • Policy variance: many Server images tweak SysMain/Prefetch; some disable application prefetching. Document expectations per tier.
  • Role-driven baselines: servers launch fewer interactive apps—outliers pop (e.g., 7Z.EXE on a DC).
  • RDP & services: bursts across several .pf files often mark admin sessions or deployments.

Red Flags & Tamper Signals

  • Sudden drop in Prefetch volume on a chatty workstation → check if SysMain/Prefetch got disabled.
  • Missing Prefetch for known executions → network path execution or cleanup: pivot to MFT/USN, Amcache, Services & Task Scheduler logs.
  • Mass deletion of .pf files → look for filesystem journal evidence; correlate with registry/policy changes.

From Artifact to Action: An End-to-End Flow

  1. Collect & Parse Prefetch on endpoints (KAPE + PECmd).
  2. Ingest structured records into Splunk/Elastic.
  3. Detect LOLBins from non-system paths, PsExec markers, new archive/exfil tools, and after-hours run bursts.
  4. Scope for the same .pf names and staging folders in file_metrics.
  5. Correlate with Amcache, MFT/USN, Event Logs (logons/services), and EDR.
  6. Brief & Contain with a coherent, time-ordered sequence.

Conclusion

Prefetch isn’t glamorous, but it’s relentlessly useful. It turns “something ran” into when, how often, and what it touched—clues that APT operators struggle to erase at scale. If you make Prefetch a first-class signal—collected, parsed, and hunted alongside Amcache, MFT/USN, and your EDR—you’ll surface earlier stages of intrusion chains and tell crisper, faster stories when it counts.

More blog posts