Les opérateurs qui se soucient de leur métier ne se contentent pas d'effacer les preuves. Ils camouflent ce qu'ils laissent derrière. Le mouvement le plus courant est le timestomping — réécrire les timestamps d'un fichier NTFS pour que le fichier ait l'air innocent, ou pour qu'il vieillisse hors de la fenêtre d'enquête. Ça marchait fiablement. Avec le USN journal activé, comme il l'est par défaut sur chaque hôte Windows moderne, ça laisse une signature si distinctive qu'un seul filtre et une résolution de chemin parent la feront émerger.
Ce billet passe en revue ce que le timestomping fait au disque, comment le journal l'expose et quels autres mouvements anti-forensiques tu peux attraper avec le même artefact gratuitement.
Un rappel rapide sur les timestamps NTFS
Chaque entrée MFT porte des timestamps dans deux attributs :
$STANDARD_INFORMATION(SI). Les timestamps que les outils user-space et la plupart des API lisent et écrivent.dir, Explorer,Get-ChildItem,os.stat,GetFileTime— ils retournent tous SI. Microsoft documente le layout dans la référence des NTFS file times.$FILE_NAME(FN). Les timestamps que NTFS définit en interne pour chaque attribut$FILE_NAME(un fichier peut avoir plusieurs noms s'il est hard-linké). Les valeurs FN sont beaucoup plus dures à changer — elles ne se mettent à jour que sur des opérations spécifiques et le kernel n'expose pas d'API propre pour les réécrire.
Les outils de timestomping ciblent SI par défaut. L'ancien timestomp.exe de Metasploit, SetMACE, et des dizaines d'implants custom écrits par des opérateurs avec un métier ne serait-ce que modeste réécrivent tous $STANDARD_INFORMATION via NtSetInformationFile avec une payload FileBasicInformation. Les implants modernes (la commande timestomp de Cobalt Strike parmi eux) peuvent aussi réécrire FN en manipulant la MFT directement, ce qui est plus impliqué et produit des preuves $LogFile supplémentaires.
Quoi qu'il en soit, l'acte d'écrire l'entrée MFT allume le journal.
Ce que le journal enregistre pour une édition de timestamp
Quand des timestamps SI sont écrits, NTFS émet un enregistrement BasicInfoChange | Close sur le FileReferenceNumber du fichier. Cet enregistrement est le diagnostic :
- Une touche légitime produit
BasicInfoChange | Closeavec unDataExtendouDataOverwritede l'écriture réelle qui a déclenché la mise à jour du timestamp. - Un timestomp produit un
BasicInfoChange | Closenu sans écriture précédente sur le mêmeFileReferenceNumber.
Quand tu vois BasicInfoChange | Close sans DataOverwrite, DataExtend, FileCreate ou rename dans la même session de handle, tu regardes de la manipulation de métadonnées. La grande majorité sont du timestomping ; le reste sont des basculements d'attributs (+H, +R, compression on/off) et des changements d'état EFS.
La comparaison SI vs FN
La détection de timestomping la plus faisant autorité compare les timestamps SI de chaque fichier à ses timestamps FN. Le motif remonte aux premières recherches forensiques Windows de Mandiant et est couvert dans File System Forensic Analysis de Brian Carrier. Les formes qui doivent te faire arrêter :
- SI antérieur à FN. Un fichier ne peut pas avoir été légitimement modifié avant que son nom n'existe. C'est le pistolet fumant canonique.
- SI dans le futur de FN d'une marge irréaliste. Opérateur poussant l'âge apparent vers l'avant pour ressembler à un fichier système d'une install propre.
- SI et FN ont l'air impossiblement propres — secondes rondes, valeurs M/A/C/B identiques, toutes correspondant à une date d'install Windows connue. Vaut un regard plus rapproché même quand aucune paire individuelle ne signale.
Le journal complète la comparaison plutôt que de la remplacer. La comparaison MFT te dit que quelque chose a altéré les timestamps. Le journal te dit exactement quand la réécriture SI s'est produite, ce qui est le timestamp que tu mets dans le rapport. Apparie les deux et l'affaire s'écrit toute seule :
- La comparaison MFT signale SI < FN sur
\Windows\System32\drivers\suspicious.sys. - Le journal a un
BasicInfoChange | Closesur leFileReferenceNumberdu fichier à2026-04-12 03:08:14Zsans écritures autour. - Ce timestamp est quand l'opérateur a lancé sa commande
timestomp. Corrèle avec Sysmon événement 1 et tu as le processus.
$LogFile et le journal devraient s'accorder
Le journal enregistre les écritures au niveau par-fichier. $LogFile enregistre les transactions MFT sous-jacentes au niveau écriture-de-métadonnées. Un timestomp produit :
- Une transaction d'écriture MFT dans
$LogFile, modifiant l'attribut$STANDARD_INFORMATIONde l'entrée cible. - Un
BasicInfoChange | Closedans le journal.
Si $LogFile montre une transaction de mise à jour MFT sur un fichier sans BasicInfoChange | Close correspondant dans le journal, l'opérateur a peut-être supprimé l'enregistrement du journal en effaçant $UsnJrnl et en en créant un nouveau. Cette manœuvre est possible (fsutil usn deletejournal /D /N C: suivi de fsutil usn createjournal /m ... /a ... C:), mais bruyante en soi.
Autres mouvements anti-forensiques que le journal attrape
Désactiver ou effacer le journal
fsutil usn deletejournal /D /N C: retire le journal entièrement. Après son exécution :
- Le fichier journal est reconstruit vide. Les enregistrements antérieurs à l'appel sont partis pour toujours.
- L'entrée MFT de
$UsnJrnlest fraîchement écrite, ce que$LogFileenregistre. - Le log Security enregistre un événement Sensitive Privilege Use pour
SeRestorePrivilegeouSeManageVolumePrivilege, si des SACL étaient configurées (ce qui d'habitude n'était pas le cas).
Le journal ne peut pas te dire ce qu'il contenait, mais l'acte de le désactiver est en soi un fort signal d'anti-forensique. Microsoft documente les commandes de gestion dans la référence fsutil usn.
Les opérateurs qui savent que le journal existe tendent à faire une de deux choses : l'effacer en partant (bruyant), ou éviter sélectivement de laisser des preuves dedans (plus dur, exige de rester hors du disque). Sur un hôte où le journal est suspectement vide autour d'une fenêtre d'incident connue, traite ça comme une hypothèse à tester.
Flux de données alternatifs
Cacher des choses dans des ADS est plus vieux que moi, et le journal l'enregistre proprement. Le bit Reason StreamChange se déclenche quand un flux de données alternatif est ajouté, renommé ou retiré sur un fichier. Filtre sur StreamChange et chaque événement de création/modification d'ADS sur le volume fait surface.
Faux positifs attendus : flux Zone.Identifier légitimes de téléchargements navigateur (appariés au FileCreate du fichier hôte), flux Mark-of-the-Web des clients mail, et état SmartScreen. Tout le reste produisant des enregistrements StreamChange sur des binaires système signés, sur des fichiers dans \Windows\System32\, ou sur des binaires de profil utilisateur hors du flow normal de téléchargement navigateur mérite un regard.
Astuces de hard-link
HardLinkChange se déclenche quand des hard links sont ajoutés ou retirés. Les opérateurs utilisent parfois des hard links pour rendre un binaire malicieux accessible via deux parents, ce qui peut défaire les règles AppLocker et les contrôles EDR basés sur le chemin. Pivote sur FileReferenceNumber pour voir tous les parents d'un inode donné.
Abus de reparse point
ReparsePointChange s'allume quand un reparse point — jonction, lien symbolique, point de montage — est ajouté, modifié ou retiré. Cherche des reparse points créés dans \$Recycle.Bin\, \Users\Default\, \ProgramData\ ou d'autres endroits où ils n'existeraient pas normalement. Le parser de corbeille est l'artefact complémentaire pour le côté $Recycle.Bin.
Changements de sécurité et d'Object ID
SecurityChange expose les réécritures d'ACL et de propriétaire. ObjectIdChange expose les manipulations d'Object ID plus rares. Les deux sont silencieux sur un hôte sain. Des rafales de l'un ou l'autre sur des binaires de profil utilisateur ou sur des fichiers système valent la peine d'être creusées.
Une procédure de scan pratique
Le filtrage le plus rapide pour le timestomping en utilisant un journal parsé :
- Filtre les enregistrements dont le masque Reason est exactement
BasicInfoChange | Close. La plupart des parsers par défaut font « contient le bit » ; tu veux une correspondance exacte pour ce scan. - Pour chaque candidat, regarde les cinq minutes précédentes d'enregistrements sur le même
FileReferenceNumber. S'il n'y a pas deDataOverwrite,DataExtend,FileCreateou rename, signale l'enregistrement. - Pour les enregistrements signalés, calcule le delta SI vs FN dans la MFT. Trie par delta absolu.
Le haut de la liste est ton timestomping. Les entrées signalées restantes sont d'habitude des invocations attrib +H ou attrib +R, ou des scripts qui basculent le read-only — dépendantes du contexte, rarement intéressantes pour une enquête IR typique, mais à garder dans la sortie classée pour la complétude.
Le parser sur cette page expose le filtrage par masque exact. Pour l'étape 3, il te faut une $MFT parsée ouverte à côté — la plupart des analystes utilisent MFTECmd d'Eric Zimmerman pour l'export CSV et pivotent dans un tableur.
Ce que tu ne peux pas attraper de cette façon
Une courte liste de mouvements anti-forensiques qui contournent entièrement le journal :
- Démarrer depuis un média externe et réécrire le disque. N'a jamais touché l'OS vif, n'a jamais écrit au journal.
- Réécritures de fichier en userland qui préservent la taille du contenu au même offset sans mise à jour SI. Produit des enregistrements
DataOverwritemais perd le contenu original. Le journal voit l'écriture, pas ce qui était là avant. - Désactiver le journal avant de faire quoi que ce soit d'autre. Le journal ne peut enregistrer que ce qui s'est passé pendant qu'il tournait.
Pour ceux-là, il te faut $LogFile, des Volume Shadow Copies, de la télémétrie hors-hôte, ou un dump RAM acquis assez près de l'incident pour contenir encore l'état pertinent.
Lectures complémentaires
- Microsoft Learn — File Times et la référence d'API
NtSetInformationFile. Cette dernière est la syscall que chaque outil de timestomping finit par appeler. - MFTECmd d'Eric Zimmerman — le parser offline canonique pour les timestamps SI et FN dans un CSV plat.
- Documentation libfsntfs de Joachim Metz — la référence ouverte la plus complète sur les internes de
$LogFile, qui est le second témoin quand le journal seul ne suffit pas. - Brian Carrier, File System Forensic Analysis — le chapitre sur les attributs de métadonnées NTFS reste la référence canonique sur la façon dont SI et FN se comportent sous différentes opérations.