← Retour au blog

Repérer le timestomping et l'anti-forensique dans le journal USN

Les attaquants qui modifient les horodatages MFT ne peuvent pas se cacher du change journal. Comment les divergences $STANDARD_INFORMATION vs $FILE_NAME et les BasicInfoChange inattendus exposent l'activité anti-forensique.

6 min de lecture

Les opérateurs sophistiqués ne suppriment pas seulement les preuves — ils essaient de camoufler ce qu'ils laissent. La technique la plus fréquente est le timestomping : éditer les horodatages NTFS d'un fichier pour qu'il paraisse innocent (ou hors fenêtre d'investigation). Ça marchait. Avec le journal USN activé, il laisse des signaux clairs.

Cet article décrit ce que le timestomping fait au disque, comment le journal l'expose, et quels autres gestes anti-forensiques on peut attraper avec le même artefact.

Rappel rapide sur les horodatages NTFS

Chaque entrée MFT porte des horodatages dans deux attributs :

  • $STANDARD_INFORMATION (SI) : les horodatages que les outils en espace utilisateur et la plupart des API peuvent modifier. C'est ce que dir, l'Explorateur et Get-ChildItem affichent. Format documenté dans la référence NTFS de Microsoft.
  • $FILE_NAME (FN) : les horodatages que NTFS positionne en interne sur chaque attribut $FILE_NAME. Il y en a typiquement un par nom (un fichier peut avoir plusieurs noms s'il est en hard link). Ils sont beaucoup plus durs à modifier — ça demande un accès noyau ou des outils spécialisés.

Les outils de timestomping (SetMACE, le timestomp.exe du module anti-forensique historique de Metasploit, plusieurs implants custom) ciblent généralement les horodatages SI. Certains ciblent désormais aussi FN. Dans les deux cas, ils touchent au MFT — et cette touche allume le journal.

Ce que le journal enregistre pour une édition d'horodatage

Quand des horodatages SI sont écrits, NTFS émet un enregistrement BasicInfoChange | Close. Cet enregistrement est le smoking gun, parce que :

  • Un « touch » légitime produit un BasicInfoChange | Close avec un DataExtend ou DataOverwrite issu de l'écriture qui a déclenché la mise à jour des horodatages.
  • Un timestomp produit un BasicInfoChange | Close nu, sans écriture précédente sur la même FileReferenceNumber.

Quand vous voyez BasicInfoChange | Close sans DataOverwrite, DataExtend ou FileCreate dans la même session de handle, vous regardez une manipulation de métadonnées — presque toujours du timestomping ou un changement d'attribut (read-only/hidden).

La comparaison classique : SI vs FN

La détection de timestomping la plus solide compare, pour chaque fichier, les horodatages $STANDARD_INFORMATION aux horodatages $FILE_NAME. Les investigateurs Mandiant écrivent là-dessus depuis des années ; le white paper historique Mandiant sur le timestomping est la référence, et Brian Carrier en parle dans File System Forensic Analysis.

Le journal complète plutôt qu'il ne remplace la comparaison :

  • La comparaison MFT vous dit qu'un timestomping a eu lieu à un moment. Elle ne peut pas dire quand.
  • Les BasicInfoChange | Close du journal vous disent exactement quand l'écriture SI s'est produite, et quel contexte process l'entourait (à coupler avec Security.evtx 4663).

Un fichier timestompé ressemble donc à ceci dans vos données :

  1. La comparaison MFT signale SI < FN (ou SI dans le futur de FN, etc.).
  2. Le journal a un BasicInfoChange | Close à, disons, 2026-04-12 03:08:14 sans écritures autour.
  3. Cet horodatage est celui que vous mettez dans votre rapport.

$LogFile et le journal en désaccord sur les écritures MFT

Le journal enregistre les écritures au niveau du fichier ; $LogFile enregistre les transactions MFT sous-jacentes. Un timestomp produit :

  • Une transaction d'écriture MFT dans $LogFile (modifiant $STANDARD_INFORMATION de l'entrée cible).
  • Un BasicInfoChange | Close dans le journal.

Si vous trouvez une transaction de mise à jour MFT dans $LogFile sans BasicInfoChange | Close correspondant dans le journal, l'opérateur a peut-être supprimé l'enregistrement journal — possible via fsutil usn deletejournal suivi de createjournal, ce qui laisse ses propres traces.

Autres gestes anti-forensiques attrapés par le journal

Désactivation du journal

fsutil usn deletejournal /D /N C: supprime le journal. Après l'appel :

  • Le fichier journal est reconstruit vide. Les enregistrements antérieurs sont perdus.
  • L'entrée MFT de $UsnJrnl est nouvellement écrite — $LogFile enregistre la transaction.
  • Security.evtx, si des SACL étaient en place, enregistre un Sensitive Privilege Use pour SeRestorePrivilege ou SeManageVolumePrivilege.

Le journal ne peut pas vous dire ce qu'il contenait, mais l'acte même de désactivation est un signal fort d'anti-forensique. Voir la référence fsutil usn de Microsoft pour les commandes de gestion et leurs prérequis de privilège.

Flux de données alternatifs

Le masquage par ADS est plus vieux que moi, et le journal l'enregistre proprement : un bit de raison StreamChange se déclenche quand un flux alternatif est ajouté ou retiré. Filtrez StreamChange et vous ferez ressortir chaque création/modification d'ADS sur le volume. Les faux positifs incluent les flux Zone.Identifier légitimes des téléchargements de navigateur — ils produisent aussi des StreamChange, couplés au FileCreate du fichier original.

Astuces de hard link

HardLinkChange se déclenche quand des hard links sont ajoutés ou retirés. Les opérateurs utilisent parfois les hard links pour rendre un fichier accessible via deux parents — utile pour contourner des contrôles basés sur le chemin. Tracer les HardLinkChange et pivoter sur FileReferenceNumber pour voir tous les parents.

Abus de reparse points

Les reparse points (junctions, liens symboliques, points de montage) peuvent rediriger un chemin ailleurs. ReparsePointChange s'allume quand un est ajouté ou modifié. Cherchez les reparse points dans $Recycle.Bin, \Users\Default ou d'autres emplacements « ne-devrait-pas-être-touché ».

Ce qu'on ne peut pas attraper ainsi

Une liste courte de gestes anti-forensiques qui contournent entièrement le journal :

  • Démarrer depuis un media externe et réécrire le disque — n'a jamais touché l'OS en vie.
  • Réécritures en espace utilisateur préservant la même taille de contenu (overwrite au même offset, pas de mise à jour SI). Elles produisent des DataOverwrite mais perdent le contenu original. Le journal voit l'écriture, pas ce qu'il y avait avant.
  • Désactivation du journal avant que l'opérateur ne fasse quoi que ce soit d'autre. Le journal ne peut enregistrer que ce qui s'est passé pendant qu'il était actif.

Pour ces cas, il faut soit $LogFile, soit les shadow copies, soit de la télémétrie hors-hôte. Le journal est un témoin fort, pas le seul.

Un scan pratique

Le filtre le plus rapide pour le timestomping sur un journal parsé :

  1. Filtrer les enregistrements de raison exactement BasicInfoChange | Close.
  2. Pour chacun, regarder les 5 minutes précédentes d'enregistrements sur le même FileReferenceNumber. S'il n'y a pas de DataOverwrite, DataExtend, FileCreate ou rename, signaler.
  3. Pour les entrées signalées, calculer le delta SI-vs-FN dans le MFT. Trier par plus grand delta.

Le haut de la liste, c'est en général votre timestomping. Les entrées restantes sont des opérations comme l'Explorateur basculant « Caché » ou des scripts qui touchent aux attributs — dépendant du contexte, mais rarement intéressantes pour une investigation typique.