Chaque enregistrement MFT stocke quatre horodatages dans deux attributs distincts. Cela fait huit nombres par enregistrement. Ils ne sont pas toujours synchrones. La relation entre eux, et là où elle se brise, est le fondement de l'analyse temporelle NTFS. Si vous n'apprenez qu'un seul détail de la forensique MFT, apprenez celui-là.
Les quatre moments que NTFS enregistre
$STANDARD_INFORMATION (SI, type d'attribut 0x10) et $FILE_NAME (FN, type d'attribut 0x30) portent tous deux des horodatages pour les quatre mêmes événements :
- Créé : quand le fichier a été écrit pour la première fois sur le volume.
- Modifié : quand le contenu du fichier a changé pour la dernière fois.
- Accédé : quand le fichier a été lu pour la dernière fois.
- MFT-modifié : quand l'enregistrement lui-même a été mis à jour pour la dernière fois (n'importe quel changement d'attribut, pas seulement de données).
Les horodatages sont stockés en valeurs 64 bits au format Windows FILETIME (ticks de 100 nanosecondes depuis 1601-01-01 UTC). Granularité de 100 nanosecondes. Assez de bits pour que les événements naturels laissent du bruit dans les chiffres du bas.
Pourquoi deux jeux existent
$STANDARD_INFORMATION est le jeu d'horodatages que voit l'userland. L'API Win32 SetFileTime écrit ici. Chaque opération de routine sur un fichier qui touche un horodatage met à jour SI : écriture, lecture (selon le paramètre de temps d'accès), renommage, changement d'attribut.
$FILE_NAME a été ajouté pour la compatibilité avec le sous-système POSIX dans les premiers NT et persiste pour des raisons historiques. Il n'est mis à jour que quand le nom change : création (quand le nom est posé pour la première fois), renommage (quand le nom change) ou déplacement entre répertoires (qui renomme au sens NTFS). Après cela, FN reste inchangé tant que le fichier garde ce nom.
En pratique cela signifie que les horodatages SI tic-taquent constamment tandis que les horodatages FN restent stables. L'asymétrie est ce qui rend le timestomping détectable.
Ce que fait le timestomping
Les outils qui modifient les horodatages appellent généralement SetFileTime. Cela écrit dans SI. Cela ne touche pas FN. Après le timestomping :
- SI montre ce que l'attaquant a choisi. Souvent antidaté de plusieurs années (pour faire ressembler un outil récemment déposé à un fichier système) ou poussé en avant (pour brouiller l'heure réelle d'activité).
- FN reflète toujours l'heure réelle de création, possiblement avec une grande marge.
C'est ce qui produit la signature canonique du timestomping : un fichier avec SI créé en 2018 et FN créé il y a six minutes.
Deux motifs à surveiller pendant le triage :
- SI créé plus ancien que FN créé. C'est naturellement impossible. Les fichiers ne peuvent pas exister avant d'être nommés. Tout enregistrement où SI created précède FN created a été touché.
- SI modifié loin de FN modifié sur un fichier qui clairement n'a pas été renommé. FN modifié ne bouge que lors des renommages ; si SI dit 2017 et FN dit hier sans renommage entre, quelque chose ne va pas.
Le truc du double renommage
Les opérateurs qui savent que la divergence SI/FN est détectable utilisent un contournement : renommer le fichier (ce qui force NTFS à mettre à jour FN), puis appeler SetFileTime sur SI et FN, puis renommer en sens inverse. Maintenant les deux attributs montrent les valeurs antidatées.
Cela vainc la comparaison SI/FN. Cela ne vainc pas :
- Le journal USN. Chaque renommage écrit une paire
RENAME_OLD_NAME/RENAME_NEW_NAME. Les deux renommages nécessaires pour le truc sont visibles dans le journal. Leurs horodatages dans le journal sont les vraies heures, pas les valeurs FN truquées. $LogFile. Les enregistrements de transaction autour du renommage restent dans le log.- Snapshots VSS. Les snapshots plus anciens ont les valeurs FN antérieures au stomp. Diffez la MFT actuelle contre la MFT du snapshot pour le même enregistrement.
Le double renommage est plus dur à faire en silence. Il est toujours courant dans les kits red team matures.
Granularité sous-seconde, l'indice de l'outil paresseux
NTFS stocke les horodatages en ticks de 100 nanosecondes. Les opérations natives Windows laissent du bruit dans les chiffres du bas. L'OS n'efface pas le composant sous-seconde quand il écrit un horodatage ; ce que l'horloge du kernel a renvoyé est enregistré.
La plupart des outils de timestomping arrondissent à la seconde la plus proche avant d'écrire. Le résultat est un horodatage finissant par .0000000 UTC. Un tel horodatage est anodin (des événements naturels occasionnels arrondissent). Une colonne de suffixes .0000000 alignés à travers de nombreux fichiers est une empreinte.
C'est facile à vérifier. Prenez les colonnes created, modified, accessed et MFT-modified de votre parse MFT. Filtrez sur tout enregistrement où les quatre horodatages SI finissent par .0000000. Comparez avec une baseline d'activité Windows naturelle. Le contraste est immédiat.
Ce que Windows lui-même fait aux horodatages
Pour utiliser la comparaison SI/FN, vous devez savoir ce que Windows fait aux quatre champs par lui-même. L'aide-mémoire :
- SI created : écrit à la création. Mis à jour par certains installateurs quand ils « créent » un fichier en l'extrayant.
- SI modified : écrit à chaque écriture de données. Mis à jour par
SetFileTime. Non mis à jour par des changements de seuls métadonnées. - SI accessed : par défaut désactivé sous Windows 7+ (positionnez
fsutil behavior set disablelastaccess 0pour activer). Si désactivé, ce champ est encore mis à jour occasionnellement par certaines opérations (logiciels de sauvegarde, scans EDR), mais il est peu fiable comme signal de « dernière lecture » dans les deux sens. - SI MFT-modified : écrit à chaque changement d'attribut, y compris renommages, changements d'ACL, création d'ADS et écritures de données.
- FN created : écrit quand le nom est posé pour la première fois (création, création de hard link, renommage).
- FN modified, FN accessed, FN MFT-modified : écrits quand le nom est posé, puis largement stables.
Sur une installation propre, les quatre horodatages de FN sont typiquement égaux entre eux (ils ont tous été positionnés au même instant quand le nom a été assigné). Quand vous voyez FN avec ses quatre horodatages identiques et les quatre SI divergents, c'est normal.
Windows Update et binaires patchés
Windows Update touche les horodatages SI des binaires patchés. Après une mise à jour cumulative, la moitié de \Windows\System32\ a un SI modifié à quelques minutes près d'eux, et un FN qui est stable depuis le dernier service pack. C'est normal. Traitez ça comme un motif de baseline, pas comme une activité anormale.
Recoupez avec CBS.log et setupapi.dev.log pour la fenêtre de patch. Si SI dit que svchost.exe a été modifié à 03:14 et que le log CBS montre une installation de composant à 03:14, c'est Windows Update, pas un attaquant.
Comment je crible le timestomping
Le criblage que je lance sur un extrait MFT frais :
- Tirez chaque enregistrement où SI created < FN created. Examinez chacun manuellement.
- Tirez chaque enregistrement où SI modified est à plus de 30 jours avant FN modified et où le fichier est dans un répertoire inscriptible par l'utilisateur. Examen manuel.
- Tirez chaque enregistrement où les quatre horodatages SI finissent par
.0000000et où le fichier n'est pas un binaire système Windows. Examen manuel. - Diffez la MFT actuelle contre le snapshot VSS le plus récent. Mettez en évidence les enregistrements dont les horodatages SI ont reculé. Examen manuel.
Cette séquence attrape la majorité du timestomping dans la nature. Les opérateurs sophistiqués utilisant le truc du double renommage ou la suppression VSS nécessitent les couches journal et journal d'événements pour être détectés, mais les quatre vérifications ci-dessus les feront remonter de toute façon via d'autres artefacts (le renommage dans le journal USN, la suppression VSS dans le journal d'événements).
Lectures complémentaires
- David Cowen, couverture Forensic Lunch sur le timestomping. Des années d'études de cas de praticiens.
- SANS, aide-mémoire des règles de temps Windows. Référence rapide pour ce que chaque opération Windows fait à chaque horodatage.
- Les notes
$STANDARD_INFORMATIONet$FILE_NAMEdu projet linux-ntfs. Référence de disposition au niveau champ.