Détecter le timestomping avec le $LogFile NTFS
Comment le $LogFile trahit le timestomping : valeurs $SI avant et après, contrôle $SI/$FN, quatre indices concrets, faux positifs et méthode pour confirmer.
TL;DR. Les outils de timestomping réécrivent le plus souvent $STANDARD_INFORMATION ($SI) via SetFileTime ou NtSetInformationFile. Le contrôle classique — création $SI antérieure à la création $FILE_NAME ($FN) — ne montre qu'un écart. Le $LogFile montre la réécriture : un UpdateResidentValue sur $SI avec les anciennes dates dans les octets undo et les nouvelles dans les octets redo. Quatre indices méritent un signalement : date de création réécrite, valeur qui recule, valeurs à la seconde pile, création $SI antérieure à la création $FN. Tous les quatre ont des explications innocentes ; confirmez avec le journal USN, les artefacts d'exécution et les enregistrements voisins.
Le timestomping (MITRE ATT&CK T1070.006) coûte peu à l'attaquant et cher à l'analyste : un binaire antidaté sort de tous les filtres « fichiers créés pendant l'incident ». Le $LogFile est l'un des rares artefacts qui enregistrent le changement en tant que changement.
Comment les horodatages sont réécrits
NTFS conserve deux jeux de quatre horodatages par fichier (création, modification, modification de l'entrée MFT, accès) :
| Attribut | Qui le met à jour | Modifiable facilement en mode utilisateur ? |
|---|---|---|
$STANDARD_INFORMATION | La plupart des opérations sur fichier ; les applications via SetFileTime | Oui, avec un droit d'écriture sur le fichier |
$FILE_NAME | Le système de fichiers, surtout à la création, au renommage et au déplacement | Pas directement |
La plupart des outils ne touchent que $SI. Certains vont plus loin et manipulent $FN indirectement, par exemple en fixant $SI puis en déplaçant le fichier pour que NTFS recopie les valeurs dans le nouveau $FN ; Palmbach et Breitinger analysent sept outils tiers et une approche PowerShell dans Artifacts for Detecting Timestamp Manipulation in NTFS on Windows and Their Reliability (DFRWS EU 2020).
Les horodatages sont des valeurs FILETIME : des intervalles de 100 nanosecondes depuis le 1er janvier 1601 UTC. C'est cette précision qui fait ressortir les valeurs à la seconde pile.
Pourquoi le $MFT seul ne suffit pas
Le $MFT montre l'état courant. On en tire la comparaison $SI/$FN et les contrôles de sous-secondes, rien de plus. Vous n'apprenez pas :
- quelle était la valeur avant ;
- si elle a changé une fois ou plusieurs ;
- si
$FNa aussi été manipulé (auquel cas les deux jeux concordent et le contrôle classique passe).
L'article de Cho en 2013 (Computers & Security 34) bâtit une méthode de détection précisément là-dessus : des valeurs de dates passées récupérées dans le $LogFile, combinées aux motifs attendus des opérations courantes sur fichier.
À quoi ressemble la réécriture dans le journal
Un appel SetFileTime sur un fichier existant produit typiquement un enregistrement UpdateResidentValue dont la cible est l'attribut $SI de l'enregistrement FILE du fichier :
| Champ | Valeur |
|---|---|
| Redo / undo | UpdateResidentValue / UpdateResidentValue |
| Attribut cible | $MFT:$DATA (l'enregistrement FILE) |
| Offset d'enregistrement | Offset de $SI dans l'enregistrement FILE (0x38 quand c'est le premier attribut d'un enregistrement NTFS 3.1) |
| Offset d'attribut | Offset du premier octet modifié dans $SI |
| Octets redo | Nouvelles valeurs d'horodatage |
| Octets undo | Valeurs d'horodatage précédentes |
L'offset d'attribut compte. Les mises à jour peuvent être partielles — dfir.ru note qu'une mise à jour de $SI peut commencer à l'horodatage M (How the $LogFile works?) — donc un parseur doit replacer les octets dans les bonnes cases. L'activité normale (écrire dans un fichier) produit aussi ces enregistrements : nouvelles valeurs de modification / changement / accès, création inchangée. Tout l'enjeu est de les distinguer des réécritures.
Quatre indices, et leurs autres causes
Le parseur de $LogFile dans le navigateur signale une modification de $SI comme timestomping possible dès qu'au moins un de ces indices est présent, et indique lesquels :
| Indice | Pourquoi il compte | Causes innocentes |
|---|---|---|
| Date de création réécrite | Une écriture normale ne change pas la date de création | Outils de copie/restauration qui préservent les dates, installeurs, clients de synchronisation |
| Une valeur recule | L'activité normale fait avancer les dates | Extraction d'archive appliquant les dates stockées, restauration de sauvegarde, correction d'horloge |
Valeur à la seconde pile (.0000000) | NTFS stocke 100 ns ; les outils de type SetFileTime et les scripts passent souvent des secondes entières | Le champ date/heure DOS du ZIP a une résolution de deux secondes, donc les fichiers extraits peuvent porter des heures rondes ; fichiers issus de FAT |
Création $SI antérieure à la création $FN | $FN est fixé par le système de fichiers à la création | Fichier copié ou extrait avec dates préservées |
Autre source innocente de dates de création anciennes : le tunnelling du système de fichiers. Quand un fichier est supprimé ou renommé et qu'un fichier de même nom est créé dans le même dossier peu après (15 secondes par défaut), Windows attribue au nouveau fichier la date de création de l'ancien. Les éditeurs qui enregistrent en écrivant un fichier temporaire puis en le renommant le déclenchent en permanence.
Une combinaison en dit plus qu'un indice isolé. Un fichier dans un dossier modifiable par l'utilisateur dont la date de création saute d'aujourd'hui à une date ronde des années plus tôt, sans extraction d'archive autour, mérite l'attention. Mille fichiers dont la date de modification recule, créés dans la même seconde qu'un fichier Prefetch de 7z.exe, relèvent probablement d'une extraction.
Exemple commenté (exemple synthétique)
Le journal d'exemple du parseur (synthétique, poste fictif FIN-WKS-07) contient cette séquence pour l'entrée MFT 322 :
- Création de
\Users\svc_backup\Downloads\tools\m64.exe— création$FN2026-09-14 10:06:52.3551871. - Renommage / déplacement vers
\ProgramData\Intel\m64.exe— modification$FN10:09:40.5560318. - Modification de
$SI— avant : création 10:06:52.3551871, modification MFT 10:09:40.5560318 ; après : les quatre dates à 2019-03-19 07:14:22.0000000.
Les quatre indices se déclenchent : création réécrite, valeurs qui reculent, secondes pile, création $SI (2019) antérieure à la création $FN (2026). Notez ce que fait le parseur de l'heure de l'événement : comme les nouvelles valeurs ont reculé, il ne s'en sert pas comme heure du changement. L'événement emprunte l'heure de son voisin (le déplacement de 10:09:40) et il est marqué ≈. L'heure réelle de la réécriture viendrait de l'enregistrement BASIC_INFO_CHANGE du journal USN.
Le même motif dans le seul $MFT montrerait $SI = 2019 et $FN = 2026 : assez pour soupçonner, pas assez pour montrer la valeur d'origine ni l'ordre des événements (déplacé d'abord, antidaté ensuite).
Confirmer un constat
- Trouvez l'enregistrement brut. Ouvrez les enregistrements de l'événement, vérifiez qu'il s'agit d'un
UpdateResidentValuesur le$SIde la bonne entrée, et lisez vous-même les octets undo et redo. - Consultez le journal USN. Un enregistrement
BASIC_INFO_CHANGEpour la même référence de fichier date le changement (parseur de journal USN). - Cherchez l'outil. Le Prefetch (parseur Prefetch), l'Amcache (parseur Amcache), les journaux PowerShell et Sysmon (parseur EVTX) peuvent montrer l'exécution d'un utilitaire de timestomping ou d'un script capable d'appeler
SetFileTime. - Regardez les voisins. Une réécriture isolée sur un exécutable dans
ProgramDatan'a rien à voir avec une série de réécritures pendant une extraction. - Recoupez avec un second parseur si le constat va dans un rapport : le parseur dans le navigateur n'est validé à ce jour que sur des journaux synthétiques. Le comparatif des parseurs de $LogFile liste les alternatives ; NTFS Log Tracker intègre ses propres motifs de manipulation de dates.
Limites
- La rétention. Si la réécriture date de plusieurs heures sur un volume système chargé, l'enregistrement a probablement disparu (jusqu'où remonte le $LogFile).
- Le contexte manquant. Si la création du fichier est sortie du journal, les valeurs « avant » ne viennent que des octets undo, qui peuvent ne couvrir qu'une partie de
$SI. - La manipulation de
$FN. Quand l'attaquant a aussi déplacé le fichier pour propager les dates dans$FN, l'indice$SI/$FNdisparaît ; la réécriture et les enregistrements de renommage restent la preuve. - Des heuristiques, pas des verdicts. Chaque indice ci-dessus a des causes légitimes. Rapportez l'observation (ancienne valeur, nouvelle valeur, LSN des enregistrements) et les recoupements, pas le signalement.
Questions fréquentes
Pourquoi le $LogFile est-il utile pour détecter le timestomping ?
Parce que le changement lui-même est journalisé. Un UpdateResidentValue sur $STANDARD_INFORMATION porte les nouveaux horodatages dans ses octets redo et les précédents dans ses octets undo : on voit la valeur avant et après la réécriture au lieu de la déduire d'un écart.
Une création $SI antérieure à la création $FN prouve-t-elle un timestomping ?
Non. C'est un indice fort, mais les copies, extractions d'archives, installeurs et restaurations de sauvegarde peuvent aussi placer les dates $STANDARD_INFORMATION dans le passé. Cherchez la réécriture dans le $LogFile, un BASIC_INFO_CHANGE correspondant dans le journal USN et la trace d'exécution d'un outil de modification de dates.
Pour aller plus loin
- D. Palmbach, F. Breitinger, Artifacts for Detecting Timestamp Manipulation in NTFS on Windows and Their Reliability, FSI: Digital Investigation, 2020.
- G.-S. Cho, A computer forensic method for detecting timestamp forgery in NTFS, Computers & Security, 2013.
- MITRE ATT&CK, Indicator Removal: Timestomp (T1070.006).