$MFT è l'indice che NTFS usa per tenere traccia di ogni file e directory su un volume. È anche il singolo artefatto più informativo che puoi estrarre da una macchina Windows. Ogni altro file del volume, compresa la tabella stessa, ha almeno un record al suo interno. Gli strumenti forensi rispondono a domande difficili su file di cui Windows non ammette più l'esistenza, perché i record sopravvivono alla cancellazione. I threat hunter inseguono la persistenza attraverso di essa perché gli attaccanti non possono muovere file su NTFS senza scrivere su di essa. Se devi imparare un solo artefatto Windows a livello di byte, sia questo.
Questo è il riferimento che avrei voluto avere quando ho iniziato. Copre cos'è la tabella, com'è fatto un record, quali attributi un record può contenere, cosa significano i file di sistema riservati all'inizio, cosa significa veramente il temuto errore "Windows non può ripristinare la master file table", e come leggere la tabella tu stesso.
Cos'è la Master File Table
$MFT è un file. Un singolo file. Si trova a un offset noto vicino all'inizio di ogni volume NTFS. Il settore di boot all'offset 0 della partizione (i 512 byte del BIOS Parameter Block) contiene un campo chiamato MftStartLcn che punta al primo cluster di $MFT. Leggi quei 1.024 byte e hai il record 0, l'autodescrizione della tabella.
Ogni riga della tabella è esattamente di 1.024 byte e descrive un file o una directory. Ogni record contiene il nome, i timestamp, i flag stile DOS, il riferimento al descrittore di sicurezza, e o i dati stessi (file piccoli) o una lista di cluster del disco dove risiedono i dati (file grandi), tutto codificato come sequenza di attributi tipizzati.
NTFS è stato introdotto con Windows NT 3.1 nel 1993 ed è il filesystem Windows di default su ogni disco fisso da Windows XP. Ha sostituito FAT, che mantiene una piccola tabella di allocazione e memorizza i nomi dei file all'interno delle voci di directory. NTFS mette quasi ogni metadato di ogni file in una singola tabella strutturata, $MFT. Quel progetto ha due conseguenze che vale la pena memorizzare:
- Tutti i metadati sono in un solo posto. Un singolo seek su
$MFTenumera ogni file del volume. Per questo gli strumenti forensi, gli antivirus, i servizi di indicizzazione e i software di backup la leggono tutti. Per questo una$MFTcorrotta è un problema molto più grande di una FAT corrotta. - I file eliminati lasciano i loro metadati. Quando NTFS elimina un file, azzera un bit nell'header del record e marca i cluster del file come liberi in
$Bitmap. Il resto del record (nome, timestamp, spesso i dati) resta al suo posto finché quello slot di record non viene riutilizzato. Vedi cosa sopravvive a una cancellazione.
L'acronimo MFT sta per Master File Table. Scritto $MFT sul disco perché, in NTFS, il segno dollaro precede i nomi dei file di metadati.
Come $MFT è disposta sul disco
Quando NTFS formatta un volume, riserva una regione chiamata zona MFT vicino all'inizio della partizione. I primi 16 record della tabella sono riservati ai file di metadati di NTFS (descritti sotto); il record 0 è la voce della tabella stessa, che punta ai suoi stessi cluster.
$MFT cresce estendendosi nella sua zona riservata ogni volta che ha bisogno di più record. Se il volume si riempie prima che la zona sia esaurita, Windows riduce la zona per fare spazio ai dati utente, motivo per cui una $MFT molto frammentata è comune su filesystem invecchiati. La tabella non si riduce mai. Una volta creato uno slot, resta in $MFT; la cancellazione azzera solo il flag in-use. Per questo vecchi record cancellati ben al di sopra dell'attuale high-water mark possono sopravvivere per anni su un volume poco usato.
Un backup dei primi record vive in $MFTMirr, posto a metà del volume. Se $MFT stessa non è leggibile, NTFS usa $MFTMirr per avviare il recupero. Vedi $MFTMirr e quando NTFS lo usa.
Anatomia di un record FILE
Ogni record MFT inizia con la firma ASCII di quattro byte FILE (46 49 4C 45). I record corrotti riportano BAAD al suo posto, una lapide scritta da chkdsk quando non è riuscito a riparare il record. Dopo la firma viene un header di 56 byte, poi l'array di fixup, poi un flusso di attributi tipizzati terminato da 0xFFFFFFFF.
L'header contiene i campi a cui ti riferisci più spesso:
- Firma.
FILEper un record valido,BAADper non riparabile. - Update sequence array (fixup). Il trucco per rilevare le scritture lacerate. Gli ultimi due byte di ogni blocco da 512 byte del record vengono sostituiti con una USN; gli originali sono salvati in questo array. Alla lettura, NTFS verifica la USN e ripristina i byte originali.
- Numero di sequenza di
$LogFile. Un puntatore a$LogFileper il recupero dopo crash. - Numero di sequenza. Viene incrementato ogni volta che lo slot del record viene riutilizzato. Combinato con il numero del record, forma il riferimento file a 64 bit che identifica univocamente una particolare incarnazione di un file.
- Conteggio degli hard link. Numero di attributi
$FILE_NAMEche puntano al record. - Flag. Il bit 0 è
IN_USE(azzerato significa eliminato). Il bit 1 èDIRECTORY. - Riferimento al record file base. Diverso da zero sui record di estensione che appartengono a un record base altrove nella tabella.
- Dimensione usata e allocata. Usata è quanto dello slot da 1.024 byte questo record consuma effettivamente; allocata è la dimensione dello slot (sempre 1.024 sui volumi standard).
Per una visita byte per byte dell'header e del flusso di attributi, vedi dentro un record MFT.
Dopo l'header vengono gli attributi. Ognuno ha il suo piccolo header (tipo, lunghezza, flag residente/non residente, nome opzionale) seguito dai dati. Non c'è un ordine fisso, ma in pratica $STANDARD_INFORMATION viene per primo e $DATA per ultimo. Un record a cui finisce lo spazio (troppi frammenti, troppi ADS, un nome insolitamente lungo) acquisisce un attributo $ATTRIBUTE_LIST che punta a uno o più record di estensione altrove nella tabella. I parser devono seguire la catena per ricostruire il file.
Attributi di file memorizzati in $MFT
Questo è l'elenco canonico dei tipi di attributo NTFS, con codici esadecimali:
| Tipo | Hex | Scopo |
|------|-----|---------|
| $STANDARD_INFORMATION | 0x10 | Quattro timestamp (creato, modificato, acceduto, MFT-modificato), flag DOS, ID proprietario, ID di sicurezza, puntatore USN. |
| $ATTRIBUTE_LIST | 0x20 | Puntatori ai record di estensione quando gli attributi di un file traboccano da un record. |
| $FILE_NAME | 0x30 | Un nome file, riferimento alla directory padre, dimensione allocata e reale, e un secondo set di quattro timestamp. Un file può averne diversi (uno per hard link, più il nome breve 8.3 sui volumi che lo hanno abilitato). |
| $OBJECT_ID | 0x40 | Identificatore di oggetto a 128 bit usato dal servizio Distributed Link Tracking. |
| $SECURITY_DESCRIPTOR | 0x50 | ACL per file (legacy). NTFS moderno memorizza le ACL centralmente in $Secure e le referenzia per ID da $STANDARD_INFORMATION. |
| $VOLUME_NAME | 0x60 | Solo sul record 3 ($Volume). Contiene l'etichetta del volume. |
| $VOLUME_INFORMATION | 0x70 | Versione NTFS, flag dirty. |
| $DATA | 0x80 | Il contenuto del file. Residente per file molto piccoli; non residente (una runlist di cluster) altrimenti. Un file può portare più attributi $DATA; quello senza nome è lo stream primario, quelli nominati sono alternate data stream. |
| $INDEX_ROOT | 0x90 | Radice di un B+ tree. Usato dalle directory ($I30), dagli indici di reparse point e da altre strutture indicizzate. |
| $INDEX_ALLOCATION | 0xA0 | Continuazione non residente di un grande indice. |
| $BITMAP | 0xB0 | Bitmap di allocazione per $MFT stessa o per grandi directory. |
| $REPARSE_POINT | 0xC0 | Symlink, junction, mount point, placeholder OneDrive, stub di dedup. |
| $EA_INFORMATION / $EA | 0xD0 / 0xE0 | Attributi estesi dell'era OS/2. Rari su Windows moderno. WSL1 li usava per i metadati POSIX, l'unico contesto degno di nota. |
| $LOGGED_UTILITY_STREAM | 0x100 | Metadati di cifratura EFS ($EFS), dati di transazione TxF. |
Un record contiene sempre almeno $STANDARD_INFORMATION, un $FILE_NAME e un $DATA. Tutto il resto è opzionale e guidato dalle funzionalità.
Residente vs non residente
La maggior parte degli attributi $DATA su un volume reale sono non residenti: l'header dell'attributo contiene una lista compatta di cluster run (un LCN iniziale più una lunghezza, ripetuti), e i byte del file vivono altrove sul disco. L'header dell'attributo è piccolo.
Se il file è abbastanza piccolo (tipicamente sotto i ~700 byte una volta considerati gli altri attributi), NTFS memorizza i byte inline dentro il record. Questi sono dati residenti, ed è uno degli artefatti più utili in ambito forense: il contenuto di un piccolo file di testo eliminato settimane fa può ancora trovarsi, byte per byte, dentro un record $MFT non allocato. Vedi dati residenti per la soglia di dimensione e cosa cercare.
File di metadati NTFS nei primi sedici record
I primi 16 record di $MFT sono riservati alla contabilità interna di NTFS. Iniziano con $ per non scontrarsi con i nomi di file utente. Quelli da conoscere:
| Rec # | File | Cos'è |
|-------|------|------------|
| 0 | $MFT | La tabella stessa. La sua runlist $DATA punta ai suoi stessi cluster. |
| 1 | $MFTMirr | Backup parziale dei primi record di $MFT. |
| 2 | $LogFile | Log delle transazioni usato per annullare o rifare operazioni incomplete dopo un crash. |
| 3 | $Volume | Etichetta del volume e flag dirty. |
| 4 | $AttrDef | Schema dei tipi di attributo validi. |
| 5 | . | La directory radice. |
| 6 | $Bitmap | Un bit per cluster del volume; traccia l'allocazione. |
| 7 | $Boot | Copia del settore di boot. |
| 8 | $BadClus | File sparse i cui run puntano a ogni cluster che il filesystem ha marcato come difettoso. |
| 9 | $Secure | Archivio centrale dei descrittori di sicurezza. |
| 10 | $UpCase | Tabella di mappatura maiuscole Unicode usata per il confronto di nomi case-insensitive. |
| 11 | $Extend | Directory contenente i file di sistema più recenti: $ObjId, $Quota, $Reparse, $UsnJrnl, $RmMetadata. |
Il change journal $UsnJrnl (sotto $Extend) è particolarmente utile in ambito forense; registra ogni cambiamento di metadati sul volume e completa $MFT per la ricostruzione della timeline. Vedi abbinare journal e tabella dei file.
Quando $MFT va male
L'errore "Windows non può ripristinare la master file table. CHKDSK abortito" appare quando chkdsk non riesce a leggere $MFT e non riesce nemmeno a ricorrere a $MFTMirr. A quel punto NTFS ha già provato e fallito la propria autoriparazione integrata. Le cause radice che ho visto, ordinate per frequenza reale:
- Supporto fisico in avaria. Settori difettosi nella zona MFT restituiscono spazzatura alla lettura. I dati SMART di solito lo confermano. Crea l'immagine del disco con
ddrescue, non condd, e lavora sull'immagine. - Interruzione improvvisa di corrente durante un'operazione metadati-intensiva. Il log delle transazioni normalmente le annulla, ma un
$LogFilecorrotto vanifica il rollback. - Corruzione a livello di driver o filtro. Stack di cifratura disco che si comportano male, minifilter di filesystem, o driver di storage bacati possono scrivere record incoerenti. Comune su host con più agenti di sicurezza che combattono tra loro.
- Sovrascritture malevole. Wiper e una manciata di famiglie di ransomware (in particolare Petya e la prima ondata di NotPetya) scarabocchiano deliberatamente su
$MFTper rendere il volume non montabile. Vedi pattern del ransomware in MFT.
La risposta forensicamente corretta:
- Smetti immediatamente di scrivere sul volume. Ogni ulteriore scrittura riduce la possibilità di recupero.
- Crea l'immagine del disco con FTK Imager,
ddoddrescueverso una destinazione sicura. Verifica l'hash. - Lavora sull'immagine, non sull'originale. Prova
testdisk,R-Studioo un parse manuale che trovi i recordFILEtramite scansione di firma direttamente sul volume. Anche se il puntatore on-disk a$MFTè perduto, i record stessi sono di solito ancora riconoscibili. - Se l'obiettivo è rimettere online il volume invece di recuperare dati, solo allora esegui
chkdsk /fsull'immagine.
chkdsk /b su un volume scrivibile può cancellare i marcatori di bad cluster, ma può anche scartare record che non riesce a comprendere. Eseguilo sull'originale solo dopo aver un'immagine e aver deciso che la disponibilità supera la fedeltà forense.
Come leggere $MFT
Hai tre opzioni realistiche:
- MFTECmd (Eric Zimmerman). Una CLI Windows che produce CSV nel layout bodyfile-friendly che la maggior parte degli strumenti di timeline si aspetta. Lo standard de facto per gli incident responder.
omerbenamram/mft. Una crate Rust e una CLI (mft_dump). Il parser che questo sito usa, utile quando vuoi scriptare l'analisi o incorporarla in una pipeline più grande.- Il parser nel browser di questo sito. Trascina
$MFTsulla home page ed esegue lo stesso parser Rust, compilato in WebAssembly, interamente nel tuo browser. Nulla viene caricato.
Per un confronto con pro e contro concreti, vedi strumenti di parsing MFT. Per workflow pratici su una $MFT parsata, vedi costruire una timeline, file eliminati e estrarre $MFT.
Domande frequenti
Cosa significa MFT?
MFT sta per Master File Table. Scritto $MFT sul disco perché, in NTFS, il segno dollaro precede i nomi dei file di metadati.
A cosa serve la master file table?
È l'indice che NTFS usa per trovare ogni file e directory su un volume. Ogni voce memorizza il nome del file, i timestamp, le informazioni di sicurezza, gli attributi e la posizione dei suoi dati sul disco.
Quali attributi di file sono memorizzati nella master file table?
Come minimo ogni record contiene $STANDARD_INFORMATION (timestamp, flag DOS), $FILE_NAME (nome e un secondo set di timestamp) e $DATA (contenuto del file o un puntatore ad esso). I record possono anche contenere $ATTRIBUTE_LIST, $OBJECT_ID, $SECURITY_DESCRIPTOR, $INDEX_ROOT, $INDEX_ALLOCATION, $BITMAP, $REPARSE_POINT, $EA e $LOGGED_UTILITY_STREAM a seconda del file. Il riferimento completo è nella tabella degli attributi sopra.
Quanto è grande la master file table?
Ogni record è di 1.024 byte. La tabella riserva di default circa il 12,5% del volume (la zona MFT) ma consuma solo lo spazio di cui ha effettivamente bisogno. Un volume con un milione di file ha una $MFT di circa 1 GB.
$MFT è la stessa cosa di $MFTMirr?
No. $MFTMirr è un backup parziale dei primi record di $MFT, posto altrove sul disco così NTFS può avviare il recupero se l'header della tabella principale è corrotto.
Come riparo una master file table corrotta?
Crea prima l'immagine del disco. Poi esegui chkdsk /f contro l'immagine (veloce, può scartare record), oppure usa uno strumento di recupero capace di scansionare firme FILE e riassemblare la tabella da cluster grezzi (lento, conserva più prove). Non eseguire mai chkdsk contro il volume originale prima di crearne l'immagine.
Posso leggere $MFT su Linux o macOS?
Sì. $MFT è solo un file. Qualsiasi parser che accetti un dump grezzo di $MFT funziona su qualunque OS: omerbenamram/mft, analyzeMFT, lo strumento browser di questo sito. Serve Windows solo per estrarre il file da un volume montato in vivo.
Letture aggiuntive
- Microsoft, Master File Table. Il riferimento ufficiale, conciso.
- Brian Carrier, File System Forensic Analysis. Ancora il miglior libro singolo sul layout e il recupero di NTFS.
- La documentazione NTFS del progetto linux-ntfs. Offset dei campi per ogni attributo, ottenuti col reverse engineering a fatica.