$LogFile : retrouver les traces de fichiers supprimés
Ce que garde le $LogFile NTFS après une suppression : nom, dossier, entrée MFT, dates, tailles, runs, parfois le contenu. Où le trouver, ce qu'il ne prouve pas.
TL;DR. Dans le $LogFile, une suppression se traduit typiquement par un DeleteIndexEntry* (nom retiré du dossier parent) suivi d'un DeallocateFileRecordSegment (enregistrement FILE libéré). Ces enregistrements — plus la création du fichier si elle figure encore dans le journal — donnent le nom, le dossier parent, l'entrée MFT et le numéro de séquence, les dates $FILE_NAME, les tailles, souvent les dernières valeurs $STANDARD_INFORMATION, parfois des runs de données et, pour les tout petits fichiers, le contenu. Le journal ne donne pas l'heure de suppression : au mieux « à la dernière date connue ou après ». Les fichiers envoyés à la Corbeille sont des renommages, pas des suppressions.
Les fichiers éphémères sont les favoris de l'attaquant : télécharger, décompresser, exécuter, supprimer. Le temps que vous imagiez le disque, l'enregistrement FILE a été réutilisé, le slack $I30 a été écrasé et le journal USN indique FILE_DELETE avec un nom et rien d'autre. Le $LogFile peut encore contenir la structure du fichier telle que NTFS l'a vue en dernier — pour les dernières minutes ou heures.
Ce qu'une suppression écrit dans le journal
| Étape | Opération | Contenu des octets |
|---|---|---|
| Nom retiré du dossier | DeleteIndexEntryRoot ou DeleteIndexEntryAllocation | L'entrée d'index retirée : référence du fichier (entrée + séquence) et un $FILE_NAME embarqué avec référence du parent, nom, quatre dates, tailles allouée et réelle, drapeaux |
| Enregistrement FILE libéré | DeallocateFileRecordSegment | Entrée cible ; le côté undo permet à NTFS de restaurer l'enregistrement |
| Bit du bitmap MFT effacé | ClearBitsInNonresidentBitMap | Quelle entrée MFT est devenue libre |
| Clusters libérés | ClearBitsInNonresidentBitMap sur $Bitmap | Quels clusters sont devenus libres (fichiers non résidents) |
Savoir si c'est le redo ou l'undo qui contient l'entrée d'index retirée fait partie des détails que les parseurs traitent différemment ; le parseur dans le navigateur essaie les deux. Les opérations elles-mêmes sont décrites dans Les opérations redo/undo expliquées.
Ce que l'on peut reconstruire
Nom et emplacement. Depuis l'entrée d'index, même si la création est sortie du journal. Le parent est une référence MFT ; résolvez-la avec le $MFT du même volume, sinon vous verrez [MFT #n] pour les dossiers inconnus.
Identité. L'entrée MFT et son numéro de séquence. Quand une entrée est réutilisée, NTFS incrémente son numéro de séquence (comme le note le readme de LogFileParser à propos de son historique de noms) : l'entrée + la séquence distinguent le fichier supprimé de celui qui occupe l'entrée aujourd'hui.
Dates. Les dates $FILE_NAME de l'entrée d'index et, si le journal contient encore des enregistrements antérieurs pour l'entrée, les dernières valeurs $STANDARD_INFORMATION. Aucune n'est l'heure de suppression.
Tailles. Taille allouée et taille réelle du $FILE_NAME de l'entrée d'index. Avec prudence : les tailles $FILE_NAME des entrées de répertoire ne sont pas toujours tenues à jour.
Runs de données. Si la création du fichier (InitializeFileRecordSegment, CreateAttribute) et les UpdateMappingPairs ultérieurs sont encore dans le journal, ses runs de clusters peuvent être reconstruits. LogFileParser l'implémente et documente la récupération de fichiers supprimés fragmentés dont l'enregistrement FILE avait été écrasé, à condition que les clusters eux-mêmes n'aient pas été réutilisés.
Contenu (petits fichiers uniquement). Un fichier assez petit pour être résident stocke son contenu dans l'enregistrement FILE. Si l'image de l'enregistrement ou le CreateAttribute de son $DATA survit dans le journal, le contenu aussi. C'est opportuniste : l'auteur de LogFileParser note que, sur les Windows récents, les modifications ultérieures de données résidentes ne journalisent en général que le fait qu'un changement a eu lieu, pas les nouveaux octets.
L'heure de suppression : ce qu'on peut dire et ce qu'on ne peut pas dire
Les enregistrements n'ont pas d'horloge. Pour une suppression, la meilleure borne tirée du seul journal est « à la date la plus récente connue pour ce fichier ou après » — en général sa dernière valeur $SI de modification/changement. Le parseur dans le navigateur étiquette ces événements « dernière date connue — supprimé à cette heure ou après ».
Pour une heure réelle, corrélez :
- l'enregistrement
FILE_DELETEdu journal USN pour la même référence de fichier (parseur de journal USN) ; - un événement voisin du journal qui, lui, porte une heure (ordre par LSN) ;
- les événements Sécurité ou Sysmon sur l'activité des processus autour (parseur EVTX).
Corbeille : un déplacement, pas une suppression
Supprimer depuis l'Explorateur sans Maj déplace le fichier dans $Recycle.Bin\<SID>\ sous un nom $R… et crée un fichier $I… correspondant avec le chemin d'origine et l'heure de suppression. Dans le $LogFile, cela apparaît comme un renommage/déplacement vers $Recycle.Bin plus la création du fichier $I, pas comme une libération. La libération n'arrive qu'au vidage de la Corbeille. Le fichier $I est petit et résident, son contenu peut donc aussi apparaître dans le journal ; analysez-le correctement avec le parseur de Corbeille.
Exemple commenté (exemple synthétique)
Dans l'exemple du parseur (synthétique, poste fictif FIN-WKS-07) :
| LSN | Événement | Détail |
|---|---|---|
| 117494 | Création | \Users\svc_backup\Desktop\creds.txt, création $FN 10:38:10.5119430 |
| 117577 | Données résidentes écrites | Premiers octets du fichier (une fausse note d'identifiants marquée SYNTHETIC) |
| 117610 | Modification de $SI | Modification / changement / accès → 10:38:27.7024018 |
| 117804 | Suppression | Même entrée ; heure « dernière date connue — supprimé à cette heure ou après » 10:38:27.7024018 |
Entre la création et la suppression, le journal montre aussi un .lnk créé dans Recent — une piste pour le parseur LNK. Dans un vrai dossier, vous chercheriez ensuite l'enregistrement USN FILE_DELETE pour dater la suppression, et le contenu dans toute autre copie (sauvegardes, synchronisation cloud, mémoire : parseur RAM).
Le même exemple montre aussi une suppression anodine : \Windows\Temp\~DF3A1B7C2E.TMP, créé et supprimé en moins d'une minute. Les fichiers temporaires tournent en permanence ; le signalement de suppression aide au tri, ce n'est pas un constat.
Là où ça casse
- La rétention. Une suppression d'hier sur un volume système a presque certainement disparu. Voir jusqu'où remonte le $LogFile.
- Le regroupement. Une suppression dont la création est hors du journal porte moins d'informations ; un parseur qui regroupe par proximité (comme le fait actuellement le parseur dans le navigateur) peut y rattacher à tort des enregistrements voisins. Vérifiez les enregistrements bruts.
- Les entrées réutilisées. Résoudre les chemins avec un
$MFTpris plus tard peut donner le nom du nouvel occupant d'une entrée ou d'un parent. Comparez les numéros de séquence ; le parseur dans le navigateur ne les vérifie pas encore lors de la résolution via le$MFT. - La validation. Le parseur dans le navigateur n'est validé que sur des journaux synthétiques ; confirmez les suppressions importantes avec LogFileParser ou NTFS Log Tracker (comparatif).
Questions fréquentes
Le $LogFile peut-il montrer des fichiers supprimés ?
Oui, si la suppression est assez récente pour figurer encore dans le journal circulaire. Le retrait de l'entrée d'index et la libération de l'enregistrement FILE portent le nom du fichier, son dossier parent, son entrée MFT et son numéro de séquence, ses dates $FILE_NAME et ses tailles.
Peut-on récupérer le contenu d'un fichier supprimé depuis le $LogFile ?
Rarement, et seulement pour de petits fichiers résidents dont le contenu apparaît dans une image d'enregistrement FILE ou une création d'attribut encore présente dans le journal. Pour les fichiers plus gros, le journal peut contenir des runs de données pointant vers des clusters, utiles au carving si ces clusters n'ont pas été réutilisés.