Back to all posts

Detecting Windows Prefetch tampering

Prefetch is one of the cleanest execution artifacts Windows produces, which is exactly why competent attackers go after it. The good news: attackers are sloppy about Prefetch more often than they are careful, and every common form of tampering leaves a trail somewhere else on the host. Here is what each one actually looks like when you sit down with the data.

Wholesale deletion

The crude option is del /q C:\Windows\Prefetch\*.pf or a PowerShell equivalent. It is fast, it is loud, and it works as long as nobody compares the result against a baseline.

Signal: file count well below what the OS version and uptime should produce. A Windows 11 workstation that has been online for six months sitting at twelve .pf files is not a clean install. Even a fresh Win10 image hits the low hundreds within a week.

Counter-analysis: file deletions are USN events. Pull the USN journal and grep for .pf to recover filenames and the timestamps they were removed. NTFS $LogFile (still resident, much shorter window) often holds the same evidence with attribute detail. The directory's own MFT entry retains a last-modified time that pins down when the purge ran. Pair with the Security or Sysmon EVTX around that window and you usually identify the process that did it.

Targeted deletion

The careful version: delete the single .pf belonging to the malicious binary, leave everything else alone. Much harder to spot on file count alone.

Signal: an execution you can prove from elsewhere — Security 4688, Sysmon EID 1, AmCache, Shimcache, LNK or jump list entries — with no corresponding .pf. On a host where EnablePrefetcher = 3 and the SysMain service has been running, that gap is not a coincidence.

Counter-analysis: carve unallocated space on the system volume. Xpress Huffman compressed Prefetch begins with MAM\x04 — a four-byte signature that is rare in normal data. Both bulk_extractor and a quick scalpel rule will pull deleted .pf files back out if their clusters have not been reused. Also check Volume Shadow Copies; Prefetch directories often survive in older snapshots.

Planted prefetch files

Drop a .pf from another machine onto the target. Used to fabricate an alibi, used in red-team exercises to test SOC detection, occasionally used by malware that wants to look like it has been around for a while.

Signal: the 8-character hash in the filename does not match what the Win7+ Hash Function 5 produces for the executable path embedded in the payload. Recompute and compare. A mismatch is conclusive.

Other tells: NTFS file-record timestamps that contradict the FILETIME values inside the file (a .pf cannot have run before it existed); identical execution timestamps across "different" entries, which usually means the attacker copy-pasted the same template and forgot to vary the byte ranges; volume serial numbers in the volume information section that do not match this host's volumes.

Falsified run counts and timestamps

The surgical version: edit a real .pf in place to lower the run count or rewrite the eight last-run FILETIME slots. Rare because it requires understanding the SCCA layout, but it does happen.

Signal: where SCCA checksums are present, they fail. File Last-Modified in the MFT does not line up with the most recent FILETIME inside. Run counts that drop between collections are impossible under normal Windows behavior — SysMain only increments — so a decrease means something rewrote the file.

Prefetch disabled before the attack

The cheapest anti-forensics is to never produce the artifact in the first place. Set EnablePrefetcher = 0 and EnableSuperfetch = 0, stop SysMain, and the host will not write .pf files at all. See the disabled-server post for the registry layout in detail.

Signal: HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\PrefetchParameters\EnablePrefetcher = 0 on a workstation where the default is 3, combined with an empty C:\Windows\Prefetch\. Cross-check via the registry hive parser against an older Volume Shadow Copy — if the value flipped from 3 to 0 mid-uptime, the SYSTEM hive LastWrite time tells you when, and the EVTX for that window usually tells you who.

Putting it together

The question on a contested case is rarely "did this binary run". It is "can I defend the claim that this .pf says what it says?" Treat each entry the way you would treat any other piece of evidence: corroborate it. A single Prefetch hit is a lead. A Prefetch hit that lines up with AmCache hashes, Shimcache paths, USN write events, and a Security 4688 or Sysmon 1 is testimony.

Further reading

  • Joachim Metz, libscca documentation — for the exact field layout you need to detect in-place edits.
  • Eric Zimmerman, PECmd — surfaces the SCCA fields you cross-check against the filename hash.