Horodatages Amcache expliqués : KeyLastWriteTimestamp vs LinkDate vs les autres
Amcache expose plusieurs horodatages différents, et les confondre est l'erreur la plus courante des nouveaux analystes Amcache. Datez un constat de travers et la timeline entière s'effondre. Cette page est la référence complète : chaque horodatage exposé par Amcache, ce qu'il représente réellement, et lequel vous devriez utiliser comme pivot pour chaque question donnée.
Pour le contexte Amcache plus large, voir la référence complète Amcache ; pour la structure de registre environnante, voir Structure du registre Amcache.
Les horodatages d'un coup d'œil#
| Horodatage | Source | Représente |
|---|---|---|
KeyLastWriteTimestamp |
Métadonnée de clé du registre | Quand l'appraiser a écrit cette entrée pour la dernière fois. Ce qui ressemble le plus à « quand Amcache a enregistré ceci ». |
LinkDate |
PE IMAGE_FILE_HEADER.TimeDateStamp |
Quand le binaire a été compilé / lié. Contrôlable par l'attaquant. |
InstallDate |
Valeur InventoryApplication |
Quand l'application a été installée. |
MsiInstallDate |
Valeur InventoryApplicationFile |
Quand le MSI parent a été installé (le cas échéant). |
LastModified |
Valeur de ruche (dépend du schéma) | Un marqueur de dernière modification, présent dans certaines versions de schéma. |
LastWriteTimestamp (legacy Programs) |
Métadonnée de clé du registre | Même idée que KeyLastWriteTimestamp, mais pour le schéma legacy Root\Programs. |
La règle unique la plus importante :
KeyLastWriteTimestampest le pivot « quand cela a-t-il été vu sur cet hôte ». Tout le reste est une question différente.
KeyLastWriteTimestamp#
C'est le last-write au niveau du registre de la clé contenant l'entrée. C'est une métadonnée de la ruche du registre elle-même — Windows la met à jour chaque fois que le contenu de la clé change.
Pour Root\InventoryApplicationFile\<entry>, le
KeyLastWriteTimestamp est mis à jour à chaque fois que l'appraiser
écrit ou met à jour cette entrée. En pratique, cela signifie :
- La première fois que l'appraiser inventorie un fichier, la clé
est créée et son
KeyLastWriteTimestampest l'heure de l'inventaire. - Si les métadonnées du fichier changent entre inventaires (taille, hash, version), la clé est réécrite et l'horodatage avance.
- Si rien ne change entre inventaires, l'horodatage reste en place — même si l'appraiser a repassé et a confirmé que le fichier est toujours présent.
Ce dernier point importe : KeyLastWriteTimestamp n'est pas « la
dernière fois que l'appraiser a vu ce fichier ». C'est « la dernière
fois que l'appraiser a écrit à propos de ce fichier ». Pour un
fichier stable et inchangé, l'horodatage peut avoir des semaines ou
des mois, même si le fichier a été présent pendant toute cette durée.
À quoi sert KeyLastWriteTimestamp#
- Approximations de first-seen. Pour un binaire que l'attaquant
a déposé à neuf sur un hôte propre,
KeyLastWriteTimestampest l'heure du passage de l'appraiser après le dépôt. Sous réserve que :- l'appraiser ne s'exécute pas instantanément — il peut y avoir jusqu'à ~24 h de délai sur les postes de travail, plus sur les serveurs,
- le binaire doit encore être présent au moment de l'appraiser (les binaires transitoires supprimés avant le passage suivant peuvent n'apparaître jamais),
- la résolution de l'horodatage est celle que l'appraiser écrit — typiquement à la seconde près.
- Jointures sur fenêtre temporelle. Une fois que vous avez une
entrée suspecte, prenez son
KeyLastWriteTimestamp± votre fenêtre choisie (une heure est un défaut courant) et joignez tous les autres CSVs (Prefetch, Sysmon, Security 4688) sur cette fenêtre. Vous obtenez l'histoire complète de ce qui s'est passé autour de l'événement d'inventaire. - Détection de remplacement de binaire. Si deux lignes
InventoryApplicationFilepartagent le mêmeFullPathmais ont des valeursHashdifférentes et des valeursKeyLastWriteTimestampdifférentes, le binaire à ce chemin a changé entre ces deux moments. Triez par horodatage pour voir la séquence.
À quoi KeyLastWriteTimestamp ne sert pas#
- « Quand ce binaire a-t-il existé pour la première fois sur disque ? »
— c'est une question de système de fichiers
(
$STANDARD_INFORMATION.CreationTimedans la MFT).KeyLastWriteTimestampest au mieux une borne supérieure : le fichier existait sur disque au plus tard à l'horodatage, mais probablement avant. - « Quand ce binaire s'est-il exécuté ? » — Amcache enregistre la présence, pas l'exécution. Utilisez Prefetch.
- Précision sous la seconde. Ne tirez pas de conclusions à partir de quelques centaines de millisecondes.
LinkDate#
Le TimeDateStamp de l'en-tête PE — la valeur que le linker a
estampée dans l'IMAGE_FILE_HEADER du binaire au moment de la
compilation/édition de liens. Chaque PE en a un.
À quoi sert LinkDate#
- Regrouper les binaires par campagne de build. Si vous triez
tous les PE non associés sur un hôte par
LinkDate, vous voyez fréquemment des clusters serrés : 3 à 10 binaires tous estampés dans le même jour ou la même heure. C'est souvent un seul attaquant compilant sa boîte à outils complète en une session. - Repérer des builds suspicieusement vieux ou neufs. Un pilote compilé en 2014 qui apparaît pour la première fois dans votre Amcache aujourd'hui est un drapeau pour BYOVD. Un binaire compilé dans le futur est un drapeau pour des manipulations de décalage d'horloge ou un outillage bâclé.
- Confirmer qu'un build appartient à la campagne attendue. « Nos builds d'outil interne ont toujours un linkdate lundi à 03:00 UTC ; celui-ci est mardi à 14:00 — à enquêter. »
À quoi LinkDate ne sert pas#
- « Quand ce binaire est-il apparu sur cet hôte ? » Contrôlable
par l'attaquant. Un attaquant peut définir n'importe quel
TimeDateStampqu'il veut au moment du link, et il est parfois défini à0délibérément (pour des builds reproductibles) ou à une date dans le passé (pour faire paraître le binaire ancien/établi). Faire confiance àLinkDatecomme pivot de présence d'hôte produit des conclusions fausses. - Identité cryptographique.
LinkDateseul n'est pas unique ; de nombreux binaires partagent le même horodatage de link.
InstallDate (sur InventoryApplication)#
Quand l'application a été installée, au format FILETIME du registre. Utile pour :
- Recroiser avec
KeyLastWriteTimestampsur les enregistrements de fichier. Si leKeyLastWriteTimestampd'un fichier est significativement plus ancien que l'InstallDatede son application parente, quelque chose est inhabituel — le fichier semble avoir été sur disque avant l'existence de l'application selon Windows. - Détecter les installs silencieux. Les applications installées
sans interaction utilisateur laissent parfois
InstallDateprès du 1601-01-01 (l'époque FILETIME) ou à des dates irréalistes dans le futur. Les deux sont des drapeaux.
MsiInstallDate (sur InventoryApplicationFile)#
La date d'installation du MSI parent pour les fichiers issus d'un
installateur MSI. Même format FILETIME que InstallDate. Utile pour
distinguer les fichiers arrivés via un install MSI propre des
fichiers arrivés via copie / dépôt.
LastModified (quand présent)#
Certaines versions de schéma Amcache exposent une valeur
LastModified par fichier. Toutes les ruches ne l'ont pas. Quand
présente, traitez-la comme l'heure de dernière modification système
de fichiers telle que l'appraiser l'a vue à l'inventaire — pas
comme faisant autorité. Le $STANDARD_INFORMATION de la MFT est la
source faisant autorité.
LastWriteTimestamp sur le legacy Programs#
Le schéma legacy Root\Programs expose un LastWriteTimestamp par
entrée qui est conceptuellement identique à KeyLastWriteTimestamp
dans le schéma moderne. Les mêmes réserves s'appliquent.
Le pivot standard borné dans le temps#
Le pattern d'enquête sur lequel la plupart des analystes se standardisent :
- Identifiez une ligne suspecte dans
*_UnassociatedFileEntries.csv(typiquement via « PE non signé dans un chemin inscriptible par l'utilisateur »). - Prenez son
KeyLastWriteTimestamp. - Définissez une fenêtre d'une heure centrée sur cet horodatage.
- Tirez de cette fenêtre :
- Toutes les autres lignes Amcache (cross-clé — pilotes, périphériques, raccourcis).
- Toutes les entrées Prefetch (exécution définitive).
- Tous les événements Security 4688 de création de processus.
- Tous les événements Sysmon
1(process create),7(image load) et11(file create). - Toutes les créations système de fichiers depuis la MFT et le journal USN.
- La timeline résultante est le tableau complet de ce qui s'est passé autour de cet événement d'inventaire.
C'est la jointure canonique « que faisait l'attaquant dans cette
minute ? », et KeyLastWriteTimestamp est l'ancre qui la rend
possible.
Un exemple travaillé#
Vous voyez deux lignes Amcache pour le même chemin :
FullPath: C:\Users\bob\AppData\Local\Temp\notepad.exe
Row A: KeyLastWriteTimestamp = 2026-03-12 14:23:11 UTC
Hash = aaaaaaaa...
LinkDate = 2018-04-03 09:00:00 UTC
Publisher = ""
Row B: KeyLastWriteTimestamp = 2026-04-19 02:14:55 UTC
Hash = bbbbbbbb...
LinkDate = 2018-04-03 09:00:00 UTC
Publisher = ""
En les lisant :
LinkDateest identique. C'est leTimeDateStampdans l'en-tête PE — l'attaquant a réutilisé la même identité de build, ou a utilisé un template qui linkstamp chaque build de la même manière. Pas une preuve du moment du build.Hashdiffère. Un contenu de fichier différent était au chemin aux deux momentsKeyLastWriteTimestamp.KeyLastWriteTimestampdiffère. Amcache a vu le chemin deux fois, à ~5 semaines d'intervalle, avec un contenu différent à chaque fois.
Conclusion : un binaire à ce chemin a été remplacé entre le 12 mars et le 19 avril. Pivotez sur l'horodatage du 19 avril ± 1 h pour l'événement de dépôt du nouveau binaire ; pivotez sur le 12 mars ± 1 h pour le dépôt original. Deux événements d'intrusion ; un chemin ; une entrée Amcache pour trouver les deux.
Voir aussi#
- Référence complète Amcache — la vue d'ensemble haut niveau.
- Structure du registre Amcache — où se trouve chaque horodatage dans la ruche.
- FileId Amcache expliqué — le pivot par hash de contenu qui s'associe aux horodatages.
- ProgramId Amcache expliqué — le pivot par identité applicative.
- Les colonnes de sortie d'AmcacheParser expliquées — chaque champ CSV, en contexte.
Pour explorer les horodatages sur votre propre ruche sans rien installer, déposez un fichier sur la page d'accueil de l'analyseur — il analyse entièrement dans votre navigateur.
Articles liés
- Volatility et Amcache : extraire la ruche depuis des images mémoire
Un guide pratique pour récupérer Amcache depuis une image mémoire Windows en utilisant Volatility — quand la récupération côté mémoire est la seule option, quels plugins utiliser, et comment passer le relais à AmcacheParser.
- Plugin amcache de RegRipper : ce qu'il fait et quand l'utiliser
Un guide pratique sur le plugin amcache de RegRipper — ce qu'il analyse, comment sa sortie texte diffère du CSV d'AmcacheParser, et quand l'utiliser à la place (ou en complément) de l'outil Zimmerman.
- Les colonnes de sortie d'AmcacheParser expliquées : chaque champ CSV décodé
Référence champ par champ pour la sortie CSV d'AmcacheParser — FileId, PathHash, ProgramId, LinkDate, BinFileVersion, IsPeFile et toutes les autres colonnes, avec les pivots qui comptent en DFIR.
- Guide de téléchargement d'AmcacheParser : sources officielles, miroirs et vérification
Tous les moyens de télécharger AmcacheParser d'Eric Zimmerman — Get-ZimmermanTools, téléchargement direct, KAPE, Velociraptor — avec vérification par somme de contrôle et schémas d'installation en environnement isolé.