Table de fichiers principale ($MFT)¶
Qu'est-ce que la MFT¶
NTFS représente chaque fichier et chaque répertoire par un enregistrement dans la table de fichiers principale (Master File Table). Les enregistrements contiennent des attributs tels que les noms, les références au parent, les horodatages, les tailles, les indicateurs, les identifiants de sécurité, les informations de point d'analyse (reparse) et les métadonnées des flux de données. Le contenu des petits fichiers et les flux de données alternatifs peuvent être résidents, c'est-à-dire que leurs octets sont stockés à l'intérieur même de l'enregistrement MFT.
La MFT est fondamentale car elle couvre les enregistrements alloués et supprimés de l'ensemble du volume. Elle peut montrer qu'un fichier a existé, où il était lié, s'il a été supprimé et comment ses métadonnées ont changé — même lorsque la navigation ordinaire dans les répertoires ne l'affiche plus.
Meilleure conclusion : un enregistrement de fichier NTFS comportant les métadonnées affichées existait au moment de la collecte ou a survécu dans un enregistrement non alloué. La MFT à elle seule ne prouve ni une exécution ni une intention de l'utilisateur.
Emplacement et collecte¶
$MFT est une métadonnée NTFS protégée. Collectez-la avec un outil d'acquisition forensique ou de triage capable
d'un accès NTFS brut ; une copie ordinaire en mode utilisateur ne peut normalement pas la lire. Associez-la à $J, $LogFile
et aux métadonnées du volume lorsque c'est possible.
Précautions d'analyse¶
- Un enregistrement supprimé peut être partiellement écrasé, ou son numéro d'enregistrement peut être réutilisé.
SNdistingue les générations d'un même numéro d'entrée. Faites correspondre l'entrée et la séquence.- Les horodatages de
$STANDARD_INFORMATION(0x10) et de$FILE_NAME(0x30) sont mis à jour selon des comportements différents. Aucun des deux n'est à l'abri d'une manipulation. SI<FN,uSecZerosetCopiedsont des pistes, et non des verdicts automatiques de timestomping.- Les liens physiques (hard links) produisent plusieurs attributs
$FILE_NAMEet plusieurs chemins pour un même enregistrement de fichier. - NTFS peut stocker plusieurs noms (y compris DOS 8.3), des flux de données alternatifs et des enregistrements d'extension.
- Les mises à jour de l'heure d'accès peuvent être désactivées, différées ou regroupées.
- Un chemin complet est reconstruit à partir des enregistrements parents.
[Orphaned],[Unknown]ouPathUnknownsignalent une ascendance manquante/réutilisée/endommagée — et non un nom de répertoire littéral. - Le slack d'un enregistrement FILE (ses octets au-delà de la taille utilisée) peut conserver des noms qu'il contenait auparavant : les
entrées d'index d'un petit répertoire dont l'index a été déplacé vers une allocation d'index (la plupart d'entre elles y sont
encore utilisées), un nom antérieur, ou l'occupant précédent d'un enregistrement réutilisé. Les noms récupérés
n'ont pas de
$STANDARD_INFORMATION, et l'en-tête d'entrée d'un nom peut avoir été écrasé. Lorsque la taille utilisée ou les attributs d'un enregistrement n'indiquent pas où commence son slack, rien n'en est récupéré et le champParseErrorsde sa ligne indiqueslack not readainsi que la raison.
Analyser avec Juntei¶
Usage: juntei parse-ntfs mft <INPUT> [OPTIONS]
Input:
-d, --directory <DIR> Recursively find $MFT files
-f, --file <FILE> Parse one $MFT
Filtering:
-r, --ranges <RANGES> Parse selected entry numbers (example: 0-15,30)
Output:
-o, --output <PATH> Save records
-t, --output-type <TYPE> csv, ys-ntfs-parser-csv, json, jsonl
-e, --extract-resident-streams <DIR> Extract resident $DATA streams
CSV Output:
-a, --all-times Include every $FILE_NAME time
-s, --short-names Include DOS 8.3-name rows
--cutoff <DATE> Keep recent SI-created or SI-modified records
Records:
-x, --recover-slack Recover file names from FILE record slack
Resident Data:
-i, --include-resident-data Put resident $DATA in the CSV
-E, --resident-extensions <EXT> Only these extensions (ex: ps1,bat,vbs,js)
-M, --resident-max-size <BYTES> Only data up to this size
Inspection:
-D, --dump-entry <ENTRY> Show one entry in full detail
-L, --list-directory <ENTRY|PATH> List a directory's contents
juntei parse-ntfs mft -f '$MFT' -o mft.csv
juntei parse-ntfs mft -f '$MFT' --cutoff '2026-10-20T00:00:00Z' -a -o recent.csv
juntei parse-ntfs mft -f '$MFT' -t jsonl -r 32000-32100 | jq .
juntei parse-ntfs mft -f '$MFT' -x -o mft-with-slack.csv
juntei parse-ntfs mft -f '$MFT' -i -E ps1,bat,vbs,js -o scripts.csv
juntei parse-ntfs mft -f '$MFT' -D 0x270-5
juntei parse-ntfs mft -f '$MFT' -L '\Users\alice\Downloads'
N'exécutez jamais les flux résidents extraits avec -e ; ce n'est pas sans raison que Juntei leur attribue des noms en .dontrun.
Les colonnes de données résidentes de -i contiennent les mêmes octets : traitez-les comme un contenu non fiable.
-D affiche une entrée : son en-tête, chaque attribut (avec les data runs) et les noms présents dans son slack tels que
-t json -x les écrit, puis les octets de l'enregistrement. -L liste chaque nom d'un répertoire, utilisé ou
supprimé, avec son numéro d'entrée et de séquence, son type, sa taille et son heure de modification. Un répertoire est désigné par
son entrée (30, 0x1E, 30-1) ou par son chemin (\Windows\System32, C:/Windows ; insensible à la casse).
Champs de sortie CSV¶
| Champ | Interprétation |
|---|---|
EntryNum (Entry Number) |
Numéro d'enregistrement MFT. À combiner avec SN ; les numéros d'enregistrement sont réutilisés. |
SN (Sequence Number) |
Compteur de génération utilisé par les références NTFS. Une non-correspondance peut révéler des relations obsolètes/supprimées. |
InUse |
Indicateur d'allocation au moment de la collecte. false signifie que l'enregistrement est libre/supprimé, et non que tous les octets sont intacts. |
ParentEntryNum (ParentEntryNumber), ParentSN (Parent Sequence Number) |
Référence du répertoire parent provenant de $FILE_NAME. Validez les deux parties. |
ParentPath |
Chemin parent reconstruit. Les marqueurs inconnu/orphelin révèlent une ascendance non résolue. |
File (Filename) |
Nom provenant du $FILE_NAME ou du flux de la ligne courante. Un enregistrement peut comporter plusieurs lignes. |
Ext (Extension) |
Extension extraite du nom à titre pratique ; ne constitue pas une détermination fiable du type de fichier. |
Size (File Size) |
Taille logique associée à la ligne/au flux. L'allocation éparse/compressée peut différer. |
RefCnt (Reference Count) |
Nombre de références de liens physiques NTFS ; comparez-le avec prudence au nombre de noms subsistants. |
ReparseTarget |
Cible décodée des points d'analyse pris en charge, tels que les jonctions/liens symboliques. Les chemins peuvent rediriger. |
Dir (Directory) |
L'enregistrement porte l'indicateur de répertoire. |
HasADS (Has Alternate Data Streams) |
L'enregistrement contient des flux de données alternatifs nommés. Cela ne le rend pas malveillant. |
IsADS (Is Alternate Data Stream) |
Cette ligne représente un flux de données alternatif nommé plutôt que les données sans nom du fichier. |
SI<FN (Standard Information Before File Name) |
La création SI précède une heure de création FN différente. Examinez la copie/le timestomping et les causes légitimes. |
uSecZeros (Microsecond Zeros) |
L'heure de création/modification SI tombe exactement sur une limite de milliseconde. Simple heuristique faible de timestomping. |
Copied |
L'heure de modification précède l'heure de création. Souvent cohérent avec une copie de fichier ; ne prouve pas une action de l'attaquant. |
SI-Flags (Standard Information Flags) |
Attributs/indicateurs de fichier de $STANDARD_INFORMATION. Les indicateurs caché/système peuvent être des pivots utiles. |
Type (Name Type) |
Espace de noms de $FILE_NAME (Win32, DOS, POSIX ou combiné). À utiliser pour éviter de compter deux fois les noms. |
DataModified (SI), Accessed (SI), MetadataChanged (SI), Created (SI) |
Heures SI. Champs courants des chronologies, mais les outils en mode utilisateur peuvent en modifier plusieurs. |
DataModified (FN), Accessed (FN), MetadataChanged (FN), Created (FN) |
Heures FN. Mises à jour différemment et généralement plus difficiles à modifier par les API ordinaires ; elles ne sont pas pour autant immuables. |
USN (Update Sequence Number) |
Dernier USN associé à l'attribut SI de l'enregistrement. Pivotez vers $J si cet USN subsiste. |
LogfileSN (Logfile Sequence Number) |
Numéro de séquence $LogFile NTFS provenant de l'en-tête de l'enregistrement FILE ; utile pour l'analyse des transactions de bas niveau. |
SID (Security ID) |
Index dans $Secure de NTFS ; ce n'est pas en soi un SID Windows. Joignez-le au SecurityID de parse-ntfs secure-sds pour obtenir le propriétaire et les ACL du fichier. |
ObjectID-FileDroid |
Identifiant d'objet / identifiant de suivi des liens distribués, s'il est présent ; à corréler avec les droids des LNK/Jump Lists. |
LoggedUtilStream |
Contexte décodé de $LOGGED_UTILITY_STREAM, lorsqu'il est pris en charge. Examinez les valeurs inhabituelles. |
ZoneID-Contents |
Contenu résident de Zone.Identifier, tel que ZoneId et les URL de téléchargement. Il peut être absent, supprimé ou non résident. |
SourceFile |
Le $MFT d'entrée, indispensable lorsque l'on combine des hôtes ou des volumes. |
ResidentDataBase64, ResidentDataHex, ResidentDataASCII |
Avec -i : le contenu du $DATA résident de la ligne (celui du fichier ou du flux de données alternatif), en Base64, sous forme d'octets (41-42) et sous forme de texte lorsqu'il s'agit d'ASCII imprimable. Vide lorsque les données sont non résidentes ou filtrées par -E/-M. |
ParseErrors |
Dommages ou relations non prises en charge affectant cette ligne. N'écartez jamais cette colonne lors du filtrage. |
FromSlack |
Avec -x : True pour un nom récupéré dans le slack d'un enregistrement FILE. Ses EntryNum et SN désignent le fichier vers lequel pointait le nom (vides lorsque son en-tête d'entrée a été écrasé), ses horodatages récupérés figurent dans les colonnes (FN), et InUse vaut False. |
SlackRecord, SlackOffset |
Avec -x : l'enregistrement FILE dont le slack contenait le nom, identifié par sa place dans le $MFT plutôt que par le numéro d'enregistrement écrit à l'intérieur (celui propre à un enregistrement d'extension, même si ses noms sont listés avec son enregistrement de base), et le décalage en octets du nom dans le $MFT. Les ParseErrors d'une ligne de slack sont les problèmes de cet enregistrement, comme fixup values do not match : les octets récupérés peuvent en être affectés. |
CopyOfEntryInUse |
Avec -x : un fichier utilisé porte encore ce nom dans le même répertoire (et il s'agit du même fichier, lorsque la référence a subsisté). Les noms qu'aucun fichier utilisé ne porte sont les plus intéressants : supprimés, renommés, ou occupant précédent d'un enregistrement réutilisé. |
Les colonnes d'horodatage suivent l'ordre MACB (Modified, Accessed, Changed, Birth/création) :
DataModified SI/FN, Accessed SI/FN, MetadataChanged SI/FN, puis Created SI/FN.
(SI) signifie $STANDARD_INFORMATION ; (FN) signifie $FILE_NAME. Ces noms décrivent la
source habituelle pour un enregistrement complet. Pour une ligne de nom de fichier normale sans attribut SI, le
mécanisme de repli existant place la création FN dans Created (FN) et les valeurs FN de modification/de changement d'enregistrement/d'accès
respectivement dans DataModified (SI), MetadataChanged (SI) et Accessed (SI).
Les lignes de slack récupérées placent les quatre heures dans les colonnes (FN) et laissent les colonnes SI vides.
Les valeurs de repli des lignes normales ne constituent pas une preuve SI indépendante. Utilisez les attributs JSON d'origine
et la provenance du slack pour déterminer la source de l'horodatage.
-t ys-ntfs-parser-csv (anciennement ys-mft-parser-csv, toujours accepté) utilise le schéma orienté entrées
du parseur maintenu. Ces noms de colonnes lisibles s'appliquent à la sortie -t csv par défaut,
y compris le MFT.csv d'auto-parse. Les sorties JSON/JSONL conservent chaque
attribut (y compris le $DATA résident, en hexadécimal) et FullPath ; utilisez-les lorsque le CSV
d'investigation aplati omet la structure de bas niveau. Avec -x, chaque entrée JSON comporte également
SlackFileNames.
Stratégie d'investigation¶
- Filtrez une fenêtre temporelle, mais conservez les enregistrements supprimés et les deux jeux d'horodatages.
- Recherchez les chemins complets, les doubles extensions suspectes, les ADS, les répertoires de préparation (staging) et les empreintes/noms connus.
Avec
-x, incluez les noms du slack qu'aucun fichier utilisé ne porte (CopyOfEntryInUseFalse) ; avec-i -E ps1,bat,vbs,js, lisez les petits scripts directement dans le CSV. - Pivotez sur l'entrée/la séquence et sur
USNvers le journal USN. - Comparez les références MFT des Prefetch/LNK/Jump Lists avec l'enregistrement cible.
- Corrélez la suppression avec la quarantaine Defender ou avec l'activité USN
FILE_DELETE/de renommage.