Retour à tous les articles

Prefetch est l'un de ces artefacts que l'on qualifie si souvent de « preuve d'exécution » que l'on oublie de se demander ce qu'il prouve réellement. Il prouve que Windows a démarré un processus exécutant un binaire portant un nom et un hash de chemin donnés. C'est suffisant pour clore beaucoup d'affaires. Ce n'est pas suffisant pour les clore toutes, et l'écart est précisément l'endroit où j'ai vu des analystes faire des affirmations qu'ils ne pouvaient pas défendre.

Ce billet est la version de « que nous dit Prefetch » que j'écrirais à l'attention de quelqu'un qui s'apprête à entrer dans une enquête contestée.

Ce qu'est Prefetch, en termes simples

Windows observe les dix premières secondes de chaque processus nouvellement démarré. Il enregistre les fichiers touchés par le processus, les DLL chargées, et comment les pages mémoire sont remontées en cas de défaut. Cette trace est compressée et stockée dans un fichier .pf dans C:\Windows\Prefetch\. La prochaine fois que le même exécutable démarre, Windows lit le .pf pour précharger les pages dont il s'attend à avoir besoin, d'où le nom.

C'est l'objectif opérationnel. La valeur forensique est incidente : parce que Windows doit savoir quoi précharger, il doit se souvenir que l'exécutable a tourné. Prefetch tient donc un enregistrement par binaire des huit dernières exécutions, du nombre total d'exécutions, du chemin résolu du binaire, et d'une liste de fichiers chargés.

Le format du nom est <EXECNAME>-<HASH>.pf, où le hash est calculé à partir du chemin complet (et sur Win10+, parfois d'autres éléments de contexte) afin que le même binaire lancé depuis deux emplacements différents reçoive deux fichiers .pf distincts. Cela compte : un attaquant qui copie psexec.exe dans C:\Users\victim\AppData\Local\Temp\ produit une entrée Prefetch différente d'une psexec.exe légitime dans C:\Program Files\. Vous les distinguez du premier coup d'œil.

Ce qu'il prouve réellement

Un fichier .pf prouve qu'un exécutable au nom embarqué a été démarré, c'est-à-dire qu'un processus a été créé et a tourné assez longtemps pour être observé par le service Prefetch. C'est une affirmation forte. Plus forte que Shimcache, plus forte qu'AmCache, et plus forte que le journal USN seul.

Ce qu'il ne prouve pas :

  • Il ne prouve pas que le fichier au chemin actuellement sur le disque soit le fichier qui a tourné. Prefetch enregistre le chemin de l'exécutable, pas son hash. Si evil.exe a été supprimé puis qu'un evil.exe bénin a été déposé à sa place, le .pf référence « l'exécutable à ce chemin » — qui est désormais un fichier différent.
  • Il ne prouve pas qu'un humain l'a lancé. Windows démarre des processus pour toutes sortes de raisons automatisées. Un .pf pour cmd.exe veut dire que cmd a démarré ; pas qu'un utilisateur ait tapé quoi que ce soit dedans.
  • Il ne prouve pas ce que le binaire a fait une fois lancé. Vous obtenez la liste de chargement, pas la ligne de commande. Pour les arguments, il faut Sysmon EID 1 ou Security 4688.
  • Il ne prouve pas l'exécution dans un contexte utilisateur particulier. Prefetch est par machine. La question du « qui » exige un autre artefact.

Si vous ne retenez qu'une chose : Prefetch est une preuve d'exécution au niveau du binaire, pas au niveau utilisateur, commande ou comportement.

Les particularités Win10/11 qui piègent

Pendant des années, la règle était « Windows garde les huit dernières exécutions ». Sur Win10 1709+, c'est devenu un maximum de huit, mais souvent moins, Windows ayant commencé à expirer les anciennes entrées agressivement durant les fenêtres de maintenance. Si vous lisez un .pf et n'y trouvez que trois horodatages d'exécution, n'en concluez pas que le binaire n'a tourné que trois fois. Il a tourné au moins trois fois.

Sur Win11 22H2 et ultérieur, Prefetch est partiellement désactivé par l'OS sur les SSD sous certaines conditions. Microsoft appelle ça une optimisation. Forensiquement, c'est un trou. Sur des hôtes Win11 sur SSD, j'ai vu la couverture Prefetch tomber à environ 60 % des exécutions. Vérifiez toujours HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\PrefetchParameters\EnablePrefetcher et EnableSuperfetch sur l'hôte avant de supposer que Prefetch est complet. La valeur par défaut 3 veut dire que les deux sont actifs ; 0 veut dire désactivé.

Les serveurs sont pires. Prefetch est désactivé par défaut sur Windows Server. Beaucoup de parcs ont une GPO qui l'active, beaucoup non. Si vous faites du DFIR sur un serveur et qu'il n'y a pas de répertoire Prefetch ou qu'il est vide, c'est peut-être simplement le défaut, pas un sabotage adverse.

Le format MAM (Prefetch compressé sur Win10+) est incompatible avec les anciens parsers offline. PECmd d'Eric Zimmerman le gère correctement ; beaucoup d'anciens parsers Python non, et produisent silencieusement des résultats erronés. J'ai vu des rapports basés sur la sortie de prefetchparser.py depuis un hôte Win10 qui étaient structurellement faux parce que le parser sautait silencieusement les fichiers compressés MAM.

Lire les horodatages sans se faire piéger

Chaque .pf porte jusqu'à huit horodatages d'exécution et un horodatage « last run ». Le format est FILETIME (intervalles de 100 nanosecondes depuis 1601 UTC), et les heures correspondent au moment où Windows a commencé à surveiller le processus, pas au moment où le binaire était sur disque. Cette distinction compte dans un cas précis.

Last run moins Created (du .pf lui-même, depuis NTFS) donne en gros la durée de vie de l'entrée. Si Last run est récent mais le .pf a été créé il y a deux ans, le binaire tourne sur cet hôte depuis deux ans. Ça suffit à exclure l'hypothèse « première apparition de cet outil chez nous ». Couplez avec la MFT pour les dates propres du binaire.

Là où je vois les analystes se brûler : comparer le « Last run » d'un .pf à un « Process create » 4688 ailleurs sur l'hôte et les traiter comme la même heure. Elles sont proches mais pas identiques, et l'écart varie selon les builds et la charge CPU. Quelques secondes, c'est normal. Une minute d'écart, vous regardez la même exécution. Une heure, vous regardez deux exécutions différentes.

La liste de chargement de fichiers, et à quoi elle sert

Au-delà du compteur d'exécution, chaque .pf porte une liste des fichiers que l'exécutable a ouverts dans ses dix premières secondes. Jusqu'à ~1000 entrées sur un binaire normal, toutes stockées comme chemins résolus par Windows à l'époque. C'est la partie que la plupart des gens survolent.

La liste de chargement est l'endroit où je regarde quand il faut répondre à « qu'a touché ce processus ». Trois motifs que je traque régulièrement :

  • Indices de détournement de l'ordre de recherche DLL. Un binaire de confiance chargeant une DLL depuis \AppData\Local\Temp\ au lieu de \System32\ apparaît comme un chemin dans la liste. Triez par préfixe de chemin.
  • Fichiers de configuration de malware. Beaucoup de malware de commodité charge sa configuration depuis un nom fixe à côté du binaire. \AppData\Roaming\<outil>\config.bin et chemins similaires sont des indices criants.
  • Ouvertures de documents. Si winword.exe a \Users\bob\Documents\offer-letter.docx dans sa liste et que vous enquêtez sur une revendication de phishing, c'est une corroboration que le document a été ouvert sur cet hôte. Couplez avec les fichiers LNK et les jump lists pour le contexte utilisateur.

La liste de chargement n'inclut pas les fichiers écrits, seulement lus (au sens large où Windows trace les défauts de page dessus). Pour les écritures, il faut Sysmon EID 11.

Anti-forensique et ce qui tient

Les attaquants peuvent supprimer et suppriment effectivement des .pf. Trois choses à savoir :

  1. Supprimer le .pf n'efface pas la trace de la MFT. Une suppression Prefetch laisse un enregistrement USN FileDelete | Close et une entrée MFT qui persiste jusqu'à réutilisation. Si le répertoire paraît suspectement vide, parsez le journal USN.
  2. Désactiver Prefetcher en pleine enquête est facile et détectable. Un changement de valeur de registre dans PrefetchParameters met à jour le LastWrite de la hive SYSTEM. Comparez avec des snapshots VSC.
  3. Les .pf des binaires apportés par l'attaquant sont souvent oubliés. C'est le cadeau qui n'arrête pas de donner. Les attaquants nettoient les emplacements évidents — le binaire lui-même, le répertoire de staging — et oublient Prefetch. J'ai clos des dossiers où la seule preuve survivante d'une mimikatz renommée était le MIMI-xxxxxx.pf jamais nettoyé.

Un workflow que j'applique vraiment

Ordre des opérations sur un hôte où Prefetch importe :

  1. Acquérir l'ensemble du répertoire C:\Windows\Prefetch\. Préservez les horodatages système de fichiers ; ne copiez pas avec quelque chose qui les réinitialise.
  2. Lister par Created NTFS décroissant. Tout ce qui a été créé dans la fenêtre suspecte va dans la liste courte.
  3. Parser vers un tableau plat : nom de fichier, nom d'exécutable, chemin, compteur d'exécutions, 8 dernières exécutions.
  4. Trier par compteur croissant. Les binaires à exécution unique avec chemins en zone utilisateur sont intéressants. Les binaires à nombreuses exécutions sous \System32\ sont normaux.
  5. Pour chaque ligne intéressante, sortir la liste de chargement et chercher les motifs ci-dessus.
  6. Corroborer avec Sysmon / Security EVTX en croisant le chemin d'exécutable et les heures d'exécution. C'est là que l'affirmation Prefetch devient défendable.

L'étape 4 est celle que je coache le plus aux analystes. À contre-courant, les .pf à exécution unique sont en général les plus intéressants dans une intrusion. Les .pf à nombreuses exécutions sont en général du bruit de fond, sauf s'ils vivent dans des endroits suspects.

Où Prefetch s'inscrit dans le tableau d'artefacts

C'est un outil parmi plusieurs, et les affirmations les plus solides le combinent avec d'autres. Prefetch pose un nom dans la liste. AmCache pose un hash à côté. Shimcache dit que Windows a regardé le fichier à un moment donné. La MFT situe le fichier dans le temps et l'espace. Le journal USN raconte ce qui lui est arrivé. Sysmon et Security disent qui, quand et avec quels arguments.

Traitez Prefetch comme le pivot pour « le binaire a tourné », et vous l'utiliserez correctement. Traitez-le comme la réponse à « que s'est-il passé sur cet hôte », et vous aurez tort.

Lire les .pf dans le navigateur

Le parser de ce site décode le Prefetch compressé MAM de Win10/11 ainsi que l'ancien format SCCA, dans votre navigateur, sans upload. Déposez un .pf (ou tout le répertoire) et vous obtenez le nom de l'exécutable, le compteur d'exécutions, les huit heures d'exécution et la liste de chargement dans un tableau triable. Utile quand le contenu Prefetch de l'hôte est suffisamment sensible pour que vous préfériez ne pas le confier à un service tiers.

Pour aller plus loin

Si le service Prefetch était désactivé, rien de ce qui précède ne vous sauvera. Vérifiez d'abord.