La référence forensique définitive d'Amcache.hve : chaque clé, chaque valeur, chaque horodatage

Amcache.hve est la source d'artefacts d'exécution la plus riche sur un hôte Windows moderne. C'est aussi l'une des plus mal comprises. Cet article est la référence que j'aurais aimé avoir lorsque j'ai commencé à extraire des ruches de machines compromises : chaque sous-clé, chaque valeur, chaque horodatage, à quoi ressemblait le schéma dans chaque version de Windows et — tout aussi important — les affirmations sur Amcache qui ne sont pas réellement vraies.

Si vous cherchez de la documentation sur l'outil plutôt que sur l'artefact lui-même, voir le Guide complet d'AmcacheParser et la référence des colonnes de sortie.


1. Ce qu'est réellement Amcache.hve#

Amcache.hve est une ruche du registre écrite par le sous-système Application Compatibility / Program Compatibility Assistant de Windows. Ce n'est pas un artefact de sécurité par conception. Microsoft l'utilise pour alimenter la télémétrie de compatibilité du Customer Experience Improvement Program et du Compatibility Appraiser, qui décident tous deux quels logiciels installés risquent de casser lors d'une mise à niveau.

S'il importe au DFIR, c'est par effet de bord de cette finalité : pour évaluer si un programme peut être mis à niveau sans risque, Windows doit énumérer les programmes, pilotes, périphériques et fichiers de la machine. Cette énumération est déversée — avec empreintes, chemins, éditeurs, tailles et horodatages — dans Amcache.hve.

Chemin#

C:\Windows\AppCompat\Programs\Amcache.hve

Une paire de journaux de transaction .LOG1 / .LOG2 se trouve à côté. Les deux journaux doivent être rejoués dans la ruche avant l'analyse si celle-ci n'a pas été démontée proprement. La plupart des outils modernes (AmcacheParser, l'analyseur en navigateur, RegRipper) le font pour vous, mais ne supprimez jamais les fichiers .LOG avant le triage — ils peuvent contenir les écritures qui détiennent vos preuves.

Qui l'écrit#

  • compatTelRunner.exe — piloté par la tâche planifiée \Microsoft\Windows\Application Experience\Microsoft Compatibility Appraiser.
  • Également touché par aeinv.dll (Application Experience Inventory) et la pile CompatTelemetry plus large.

Par défaut, l'appraiser s'exécute quotidiennement et à l'ouverture de session, mais la cadence varie selon la version de Windows et les stratégies de groupe. Ne supposez pas que les données Amcache sont en temps réel. Un binaire exécuté cinq minutes avant un arrêt peut ne pas apparaître du tout ; un autre exécuté une heure avant peut apparaître avec un KeyLastWriteTimestamp reflétant l'exécution de l'appraiser, pas l'exécution du binaire.

Acquisition#

La ruche est maintenue ouverte par l'OS pendant l'exécution. Pour en récupérer une copie à chaud, vous avez besoin d'un accès NTFS brut :

  • KAPE avec la cible Amcache
  • Velociraptor Windows.Registry.Amcache
  • FTK Imager → File System → C:\Windows\AppCompat\Programs
  • RawCopy64.exe / CopyRawFiles.ps1
  • Depuis une image E01/AFF4/VHDX, lisez simplement le fichier normalement

Un instantané de copie de cliché (vssadmin list shadows) vous donne souvent une ruche antérieure contenant des preuves que la ruche actuelle a déjà éliminées.


2. Évolution du schéma : de Windows 7 à Windows 11#

Le schéma d'Amcache a profondément changé. Si vous abordez une enquête en vous attendant à trouver des clés Windows 10 1607 sur une ruche Windows 7, vous penserez que l'artefact est vide. Il ne l'est pas — il a juste une autre tête.

Version de Windows Amcache présent ? Schéma dominant
Windows 7 RTM / SP1 (pré-KB2952664) Non (utilise RecentFileCache.bcf) n/a
Windows 7 SP1 + KB2952664 (2015) Oui Root\File\{VolumeGUID}\{FileRef} + Root\Programs
Windows 8 / 8.1 Oui Root\File + Root\Programs
Windows 10 1507 – 1511 Oui Root\File + Root\Programs (transitoire)
Windows 10 1607 (Anniversary Update) Oui Root\InventoryApplicationFile et la famille Inventory* plus large introduite
Windows 10 1703 – 1809 Oui Schéma Inventory stable ; ajouts mineurs de champs
Windows 10 1903 – 22H2 Oui Schéma Inventory, LongPathHash, champs pilote supplémentaires
Windows 11 21H2 / 22H2 / 23H2 / 24H2 Oui Schéma Inventory, enregistrements de périphériques étendus, détail PnP enrichi

Le saut de 1607 est le plus important. Les ruches antérieures à 1607 ont une poignée de clés contenant peut-être une douzaine de valeurs chacune. Les ruches postérieures à 1607 ont une dizaine de conteneurs Inventory* de premier niveau, chacun avec des données imbriquées riches.

Schéma historique (Win7 → Win10 1511)#

Root\
  File\
    {Volume GUID, e.g. "{abcd1234-...}"}\
      {NTFS File Reference, e.g. "0000abcd00000001"}\
        ... values ...
  Programs\
    {ProgramId}\
      ... values ...
  Orphan\
  Generic\

Les valeurs intéressantes sous chaque sous-clé File\{Vol}\{FileRef} étaient numérotées (0, 1, 2, ... 101, ...). La correspondance est bien documentée dans les travaux originaux de Willi Ballenthin de 2013/2015 et reproduite dans le blog Mandiant. Points saillants :

Valeur Signification
0 Nom du produit
1 Nom de la société
2 PE FileVersion
3 Code de langue (LCID)
5 BinaryFileVersion
6 BinaryProductVersion
c FileDescription
f PE LinkDate (FILETIME)
11 Dernière modification (FILETIME)
12 Création (FILETIME)
15 Chemin complet
17 Dernière modification (créneau FILETIME alternatif)
100 ProgramId
101 FileId (SHA-1 avec préfixe 0000)

Schéma moderne (Win10 1607+)#

Root\
  InventoryApplication\
    {ProgramId}\          ← enregistrement de programme installé
  InventoryApplicationFile\
    {Name|FileId}\        ← enregistrement par fichier
  InventoryApplicationShortcut\
  InventoryApplicationFramework\
  InventoryApplicationDriver\
  InventoryDeviceContainer\
  InventoryDevicePnp\
  InventoryDeviceInterface\
  InventoryDriverBinary\
  InventoryDriverPackage\
  InventoryMiscellaneousUUPInfo\
  Programs\               ← historique, souvent encore présent
  File\                   ← historique, souvent vide sur les OS modernes
  Orphan\
  Generic\

Chaque sous-clé moderne porte des valeurs nommées (et non numériques), ce qui les rend beaucoup plus faciles à lire. Le reste de cet article est la référence champ par champ de ces valeurs modernes.


3. Root\InventoryApplicationFile — la cheville ouvrière#

Une sous-clé par fichier inventorié par Windows. C'est là que les binaires d'attaquant, les DLL chargées en side-loading et les outils ad-hoc tendent à apparaître.

Valeur Type Signification Note forensique
Name string Nom du fichier par ex. mimikatz.exe
LowerCaseLongPath string Chemin complet (en minuscules) Le pivot le plus utile à lui seul.
LongPathHash string Empreinte utilisée en interne par Windows pour la déduplication des chemins Utile pour joindre des enregistrements à travers les redémarrages.
FileId string "0000" + SHA-1(31 premiers MiB) Retirez le préfixe 0000 pour les recherches VT / TI.
Publisher string CN X.509 ou ressource PE company Vide = non signé.
Version string PE FileVersion
BinFileVersion string PE VS_FIXEDFILEINFO.dwFileVersion
BinProductVersion string PE VS_FIXEDFILEINFO.dwProductVersion
ProductName string Ressource PE ProductName
ProductVersion string Ressource PE ProductVersion
LinkDate string ou FILETIME PE TimeDateStamp Contrôlé par l'attaquant. À utiliser pour regrouper, pas pour dater.
BinaryType string pe32, pe64, pe32_arm64, pe32_managed, ... À filtrer sur PE natif en threat hunting.
Size dword/qword Taille du fichier en octets
Language dword LCID de la ressource PE
IsPeFile dword (0/1) Est-ce un PE ? Presque toujours 1 ici.
IsOsComponent dword (0/1) Binaire livré avec Windows Filtrer à 0 pour réduire le bruit.
ProgramId string Empreinte d'identité à 44 caractères de l'application parente Vide/zéro = fichier « non associé ».
Usn qword Numéro de séquence USN journal au moment de l'inventaire
AppxPackageFullName string Nom complet de package UWP Renseigné pour les applications du Store.
AppxPackageRelativeId string Identifiant relatif au package UWP

Deux formats de FileId#

Deux formats coexistent en pratique :

  • 0000 + 40 caractères hex — SHA-1 des 31 premiers MiB du fichier. C'est le format dominant à partir de Windows 8.
  • 0001 + 32 caractères hex — MD5 ; rare et essentiellement historique.

Lors d'un pivot vers les flux de threat intelligence, vérifiez toujours le préfixe et retirez-le. Soumettre le FileId brut à VirusTotal renverra zéro résultat et fera perdre un temps de triage significatif.

« Non associé » vs « associé »#

Un fichier avec un ProgramId non vide qui pointe vers une sous-clé InventoryApplication existante est « associé » — Windows l'a relié à un produit installé. Un fichier avec un ProgramId vide ou nul est « non associé » et n'a pu être rattaché à aucune application enregistrée.

L'outillage d'attaquant est presque toujours non associé. Filtrer InventoryApplicationFile sur les entrées non associées ayant un LowerCaseLongPath sous \Users\, \AppData\, \ProgramData\, \Temp\ ou \PerfLogs\ est le filtre de triage le moins coûteux et le plus productif sur une affaire typique de malware grand public.


4. Root\InventoryApplication — enregistrements de programmes installés#

Une sous-clé par application enregistrée (installations MSI, entrées Ajouter/Supprimer des programmes, applications du Store, etc.).

Valeur Signification
Name Nom d'affichage
Version Version de l'application
Publisher Chaîne de l'éditeur
RootDirPath Répertoire d'installation
Source MSI, AddRemoveProgram, WindowsUpdate, ...
InstallDate Date d'installation (chaîne ou FILETIME)
Type Application, OptionalFeature, ...
Language LCID
MsiPackageCode GUID de package MSI
MsiProductCode GUID de produit MSI
RegistryKeyPath Clé de désinstallation (SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\...)
UninstallString Ligne de commande pour désinstaller
OSVersionAtInstallTime Version de Windows lors de l'installation
InstallDateArpLastModified Date de dernière modification dans Ajouter/Supprimer
PackageFullName Nom complet UWP (le cas échéant)

InstallDateArpLastModified est sous-utilisé. Si l'InstallDate d'une ligne et sa valeur ARP-last-modified divergent de plusieurs mois, vous regardez peut-être un binaire remplacé (pensez au DLL side-loading via un installateur légitime laissé en place par l'IT).


5. Root\InventoryDriverBinary — artefacts en mode noyau#

La meilleure source unique pour les chasses BYOVD (bring-your-own-vulnerable-driver).

Valeur Signification
DriverName Nom du fichier pilote
DriverInBox Vrai si livré avec Windows
DriverIsKernelMode Vrai pour les pilotes ring-0
DriverSigned Indicateur de signature déclaré (à ne pas croire aveuglément — vérifiez le certificat séparément)
DriverType Drapeaux de bits : legacy / PnP / service / système de fichiers / ...
DriverVersion Chaîne de version du pilote
DriverCompany Chaîne société
Product Nom du produit
ProductVersion Version du produit
WdfVersion Version du Windows Driver Framework, le cas échéant
Service Nom du service sous-jacent
Inf Nom de fichier .inf
DriverPackageStrongName Nom fort (strong name)
DriverTimeStamp Date de link PE du pilote
ImageSize Taille de l'image en octets
Hash SHA-1 du pilote

Pour le BYOVD : triez par DriverTimeStamp ascendant, filtrez DriverSigned à vrai, puis examinez le KeyLastWriteTimestamp de chaque enregistrement. Les pilotes anciens, signés et récemment inventoriés constituent le jeu à fort signal. Recoupez avec loldrivers.io pour les noms et empreintes connus comme abusés.


6. Root\InventoryDeviceContainer et Root\InventoryDevicePnp#

InventoryDeviceContainer est la liste de périphériques côté utilisateur : « Brother HL-L2350DW », « Logitech BRIO », « Samsung Galaxy S22 ». Une sous-clé par périphérique logique. Valeurs notables : Categories, DiscoveryMethod, FriendlyName, Manufacturer, ModelName, ModelNumber, IsConnected, IsPaired, Icon.

InventoryDevicePnp est l'énumération technique : une sous-clé par interface de périphérique, avec BusReportedDescription, DeviceClass, DeviceId, InstanceId, Manufacturer, Service, DriverName.

Joignez les deux sur InstanceId pour obtenir à la fois le nom commercial et les identifiants matériels PnP. C'est souvent la réponse la moins coûteuse à « est-ce que le périphérique X a déjà été branché sur cet hôte ? » sans avoir à patauger dans les logs Setup.


7. Root\InventoryApplicationShortcut et autres clés mineures#

  • InventoryApplicationShortcut — une sous-clé par .lnk connu de Windows. Porte ShortcutPath, TargetPath, et le ProgramId parent. Utile pour « qu'est-ce qui était épinglé à la barre des tâches le $DATE ».
  • InventoryApplicationFramework — enregistrements de frameworks .NET / runtime.
  • InventoryApplicationDriver — pont entre une application installée et le pilote qu'elle a livré.
  • InventoryDriverPackage — enregistrements de packages au niveau INF.
  • InventoryMiscellaneousUUPInfo — informations de staging Unified Update Platform ; rarement pertinent.

8. Les horodatages : la partie que tout le monde se trompe#

Amcache expose au moins cinq sortes distinctes de « quand », et elles signifient des choses différentes. Les mal interpréter est l'erreur la plus fréquente dans les conclusions Amcache.

Horodatage Source Ce qu'il dit réellement
KeyLastWriteTimestamp Dernière écriture registre de la sous-clé Ce qui se rapproche le plus de « quand Amcache a observé cela ». C'est votre pivot de référence.
LinkDate Header PE TimeDateStamp Quand le compilateur/linker a tamponné le binaire. Contrôlé par l'attaquant, fréquemment falsifié.
InstallDate (InventoryApplication) Ce que l'installateur a écrit Best-effort ; reflète le comportement de l'installateur, pas nécessairement la vérité de terrain.
InstallDateArpLastModified Dernière modification de la clé Ajouter/Supprimer Utile pour détecter le remplacement d'une application existante.
DriverTimeStamp Date de link PE d'un pilote Mêmes réserves que LinkDate.

Le piège de KeyLastWriteTimestamp#

KeyLastWriteTimestamp est la dernière fois où la clé de registre a été écrite, donc la dernière fois où l'appraiser a touché l'enregistrement. Si Windows a réévalué le fichier mardi dernier suite à un changement de métadonnées, l'horodatage dira mardi — pas la date à laquelle le fichier a été observé pour la première fois.

Cela signifie :

  • Vous ne pouvez pas supposer que KeyLastWriteTimestamp est « première observation ».
  • Vous pouvez supposer qu'il est « dernier passage de l'appraiser ».
  • Pour « première observation », corrélez avec les copies de cliché de ruches Amcache antérieures, ou avec l'entrée du USN journal référencée par Usn.

Le mythe « Amcache = exécution »#

Vous lirez dans bien des vieux articles de blog qu'« Amcache prouve l'exécution ». Cette affirmation n'est pas tenable. Les travaux de Maxim Suhanov (2018, « Windows ShellBag and Amcache forensics: just stop relying on single-source signals ») ont démontré que le Compatibility Appraiser inventorie des fichiers qui n'ont pas été exécutés — par exemple des exécutables présents dans des répertoires scannés par l'appraiser.

Ce qu'Amcache prouve de manière fiable :

  • Le fichier existait sur le système au moment de l'inventaire.
  • Son empreinte, son chemin, son éditeur et ses métadonnées PE à cet instant.

Ce qu'Amcache ne prouve pas à lui seul :

  • Que le fichier a été exécuté.
  • Quand le fichier a été déposé sur le disque pour la première fois.
  • Que l'utilisateur (et non le système) en est responsable.

Pour la preuve d'exécution, corroborez avec Prefetch, Sysmon EventID 1, Security 4688, ShimCache, BAM/DAM, UserAssist ou SRUM. Amcache est un fantastique artefact de triage et un artefact d'appui solide, mais c'est un faible témoin d'exécution à source unique.


9. ProgramId et FileId : comment fonctionnent les identifiants#

ProgramId (44 caractères)#

Une empreinte dérivée du nom, de la version, de l'éditeur et de la langue de l'application. L'algorithme exact n'a pas été formellement documenté par Microsoft, mais les conséquences pratiques sont :

  • Le même produit installé sur deux machines aura (généralement) le même ProgramId.
  • Une mise à jour de version mineure le changera (généralement).
  • Ce n'est pas une empreinte de contenu — deux binaires différents d'un même produit partagent un ProgramId.

Utilisez ProgramId pour pivoter, jamais pour identifier un fichier.

FileId (44 caractères avec préfixe 0000)#

Celui-ci est une empreinte de contenu :

FileId = "0000" + SHA1(31 premiers MiB du contenu du fichier)

Pour les fichiers de moins de 31 MiB, FileId[4:] est un SHA-1 complet du fichier et correspondra au SHA-1 reporté par n'importe quel autre outil. Pour les fichiers de plus de 31 MiB, FileId[4:] est un SHA-1 des 31 premiers MiB uniquement — il ne correspondra pas à un SHA-1 fichier complet.

Cela compte : un installateur packé de 200 Mo aura un FileId qui ne correspondra pas à son SHA-1 fichier complet, et une recherche VT clé sur l'empreinte complète peut manquer tandis qu'une recherche clé sur la valeur Amcache pourra toucher (et inversement). Dans le doute, cherchez les deux.


10. Anti-forensique et altération#

Amcache peut être altéré. La ruche réside sur disque et peut être modifiée hors ligne. Schémas connus :

  • Suppression sélective de clés par un acteur de niveau SYSTEM entre deux exécutions de l'appraiser.
  • Écritures de type Set-ItemProperty pour planter des valeurs LinkDate ou Publisher trompeuses pour un binaire que l'attaquant veut faire passer pour bénin.
  • Remplacement de ruche par une ruche récoltée sur une machine saine.
  • Désactivation de la tâche planifiée de l'appraiser (visible dans l'historique du Planificateur de tâches et les logs Microsoft-Windows-Application-Experience).

Corroborations défensives :

  • Les fichiers .LOG1 / .LOG2 contiennent souvent l'état pré-altération.
  • Les Volume Shadow Copies de Amcache.hve des jours précédents vous donnent un avant/après.
  • Le USN journal enregistre les écritures sur le fichier de ruche lui-même.
  • Le log d'événements Microsoft-Windows-Application-Experience/Program-Telemetry enregistre les exécutions de l'appraiser.

Si une ruche paraît trop propre — entrées InventoryApplicationFile clairsemées, aucune ligne non associée, couverture éditeur parfaite — soyez méfiant. Un poste Windows normal accumule des milliers d'enregistrements de fichiers au cours de sa vie.


11. Corroboration inter-artefacts#

Amcache est à son meilleur lorsqu'on le joint à ses voisins. Les jointures qui paient le plus souvent :

Question Recouper Amcache avec
Ce binaire a-t-il réellement été exécuté ? Fichiers Prefetch .pf, Sysmon 1, BAM/DAM, ShimCache, UserAssist
Quand a-t-il été déposé sur le disque ? Horodatages $MFT $STANDARD_INFORMATION et $FILE_NAME, USN journal
D'où vient-il ? InstallSource dans Programs, ADS Zone.Identifier, historique de navigation, logs de passerelle e-mail
A-t-il appelé sa base ? Logs DNS, Sysmon 3, logs pare-feu
Quel utilisateur l'a exécuté ? Security 4688, BAM/DAM (par SID), UserAssist (par NTUSER)
État antérieur de cette ruche ? Shadow Copies, sauvegardes antérieures, collectes KAPE Triage

Un constat sourcé sur Amcache plus Prefetch plus un Security 4688 est reportable. Un constat sourcé sur Amcache seul est une piste.


12. Outils qui lisent Amcache#

Aucun outil unique n'est le meilleur dans toutes les situations. Une équipe DFIR qui tourne en garde plusieurs sous la main.

Outil Points forts Quand l'utiliser
AmcacheParser (Eric Zimmerman) Canonique, éprouvé, intégré à KAPE, sortie CSV Traitement en masse, pipelines KAPE, sortie présentable en justice
RegRipper (plugin amcache.pl) Rapports textuels, excellent pour les timelines narratives Quand vous voulez un résumé lisible par un humain
Cet analyseur dans le navigateur Aucune installation, s'exécute entièrement côté client via WebAssembly, aucun upload Triage rapide, démonstrations en formation, portables tiers sur lesquels vous ne pouvez pas installer de logiciel
Velociraptor Windows.Registry.Amcache Collecte et analyse à l'échelle de la flotte Sweep type EDR sur des centaines d'hôtes
Magnet AXIOM / EnCase GUI + gestion d'affaire intégrée Équipes équipées d'outils commerciaux
Python python-registry / Rust nt-hive Accès programmatique Pipelines sur mesure, recherche

Si vous voulez éviter toute installation, déposez une ruche sur la page d'accueil et vous verrez chaque clé et valeur en quelques secondes. Rien ne quitte le navigateur.


13. Pour aller plus loin (les sources qui font réellement avancer le domaine)#

L'essentiel de ce qui est « connu » sur Amcache vient d'un petit nombre de chercheurs. Si vous n'avez le temps que pour quatre lectures, lisez celles-ci :

  • Willi Ballenthin (Mandiant) — la cartographie originale des champs Amcache pour le schéma historique. Reste la référence canonique pour les ruches antérieures à 1607.
  • Andrea Fortuna — plusieurs articles parcourant le schéma Inventory* tel qu'il a évolué sous Windows 10.
  • Maxim Suhanov — travaux d'internals registre, et le traitement le plus rigoureux de ce qu'Amcache prouve et ne prouve pas. Son travail est ce qui a tué le mythe « Amcache = exécution ».
  • Notes d'outil d'Eric Zimmerman — lisez les notes de version d'AmcacheParser ; c'est par là que les nouveaux champs de schéma sont publiquement documentés en premier.

Ensuite, lisez vos propres ruches. Le schéma que l'on rencontre en production contient des champs qu'aucun article de blog ne couvre, et la seule façon fiable de savoir ce que votre build de Windows enregistre est de regarder.


Voir aussi#

Vous avez une ruche que vous voulez examiner sur-le-champ ? Déposez-la sur la page d'accueil de l'analyseur — elle est analysée dans votre navigateur, localement, en quelques secondes.

Articles liés

Retour à tous les articles