← Torna al blog

Cosa sopravvive davvero quando un file viene eliminato su NTFS

· 7 min di lettura

La singola frase più utile che posso offrire a un nuovo esaminatore su NTFS: l'eliminazione non è cancellazione. È un cambio di flag e un aggiornamento dell'indice. Il record MFT del file resta al suo posto. I cluster di dati vengono marcati liberi in $Bitmap. Nulla viene sovrascritto finché qualcos'altro non chiede quello spazio.

La gente lo sa in astratto. L'errore che continuo a vederli commettere è supporre che la finestra di sopravvivenza sia generosa su ogni macchina. Non lo è. Su un file server affollato lo slot viene riusato in pochi minuti. Su una workstation che nessuno usa nel weekend, il record eliminato può restare un mese. Devi sapere che tipo di host stai guardando prima di impegnarti su una storia riguardo a se qualcosa è ancora recuperabile.

Cosa contiene ancora il record

Un record MFT eliminato è strutturalmente identico a uno vivo. Il bit IN_USE (bit 0 nel campo flag all'offset 0x16) è azzerato. Tutto il resto, a meno che il record sia stato rivendicato, è ciò che NTFS ha scritto per ultimo:

  • $STANDARD_INFORMATION (tipo di attributo 0x10): tutti e quattro i timestamp di SI, i flag DOS, il riferimento al descrittore di sicurezza, l'ID proprietario, il puntatore USN. I timestamp sopravvivono intatti all'eliminazione. Nota che il SI che vedi è com'era il file al momento dell'eliminazione, non quando è stato creato originariamente (Windows aggiorna SI di continuo mentre il file è vivo).
  • $FILE_NAME (0x30): uno per hard link, più il nome corto 8.3 sui volumi con disable8dot3 disattivato. Il riferimento alla directory padre è il numero di record MFT della directory in cui viveva il file. Quel riferimento tiene anche se la directory stessa è stata eliminata dopo, motivo per cui fls e MFTECmd ricostruiscono i percorsi nelle gerarchie di directory eliminate.
  • $DATA (0x80): per i file residenti (sotto i ~700 byte di dati), i byte stessi siedono inline nel record. Per i file non residenti, la runlist punta ai cluster che erano il file. Quei cluster non sono più marcati come allocati, ma non sono stati azzerati.
  • $ATTRIBUTE_LIST (0x20) quando presente, con riferimenti a eventuali record di estensione che il file usava. Quei record di estensione sono anch'essi eliminati ma, finché non vengono recuperati, sono ancora parsabili.

Il numero di sequenza è ciò che rende difendibile l'analisi dei file eliminati. Ogni record porta un numero di sequenza a 16 bit che si incrementa ogni volta che lo slot viene riusato. Una voce del journal USN o un riferimento $LogFile che punta al record 12345 sequenza 3 continua a puntare alla sequenza 3 anche dopo che lo slot è ora sequenza 4. Quella discrepanza è ciò che ti dice che lo slot è stato riusato da allora.

Quando lo slot scompare davvero

Due eventi pongono fine alla recuperabilità in modo indipendente:

Lo slot del record MFT viene riusato. NTFS non ha una strategia di allocazione fissa qui. In pratica, quando un nuovo file ha bisogno di un record, il driver guarda $MFT:$BITMAP per il record libero con numero più basso e lo usa. I record eliminati vengono recuperati grossomodo in ordine. Su un volume molto usato quell'ordine si muove veloce. La MFT stessa solo cresce; non si riduce mai, quindi vecchi record eliminati ben sopra l'attuale high-water mark possono sopravvivere per anni.

I cluster di dati vengono sovrascritti. Indipendentemente dal record. I cluster sono stati marcati liberi in $Bitmap, quindi qualsiasi allocatore può rivendicarli. Su un file appena eliminato, entrambi gli eventi devono accadere prima che il recupero diventi senza speranza. Ho visto record sopravvivere mentre i cluster erano persi da tempo (recuperi solo i metadati e i dati residenti) e l'inverso (il record viene riusato ma i cluster contengono ancora i byte originali e possono essere ricavati per carving).

Non c'è un timer netto per nessuno dei due. "Quanto durano i file eliminati su NTFS" ha la stessa risposta onesta di "quanto dura un posto libero al bar": finché qualcuno lo prende.

Cosa aggiungono i journal

La MFT ti mostra il presente. Il journal USN ti mostra il verbo. Un record USN FILE_DELETE nomina il file, la directory padre e il timestamp dell'eliminazione. Anche se lo slot MFT è stato riusato da allora, la voce USN conserva ancora il vecchio nome e la coppia record/sequenza originale. Accoppia i due e ottieni qualcosa come:

2026-04-12T13:08:11Z USN FILE_DELETE | CLOSE  rec=44231 seq=7 path=\Users\bob\Documents\secrets.zip
2026-04-12T13:08:11Z MFT rec=44231 IN_USE=0 seq=7 (ancora leggibile, eliminato)
2026-04-12T13:08:11Z MFT FN parent=12, name=secrets.zip

Questa è una risposta ricostruibile a "com'era questo file al momento dell'eliminazione" anche se il file è altrimenti sparito. $LogFile aggiunge dettaglio a livello transazionale nei secondi attorno: l'eliminazione è incorniciata da una coppia DeleteAttribute e DeallocateFileRecordSegment, e di solito puoi identificare le operazioni circostanti.

Se VSS era attivo ed esiste uno snapshot precedente all'eliminazione, il $MFT dello snapshot mostra ancora IN_USE=1 per lo stesso record/sequenza, e i cluster di dati sono stati preservati dal copy-on-write. Vedi Volume Shadow Copy e $MFT per i dettagli di estrazione.

I casi che la gente sbaglia

Strumenti di cancellazione sicura. SDelete nella modalità di default sovrascrive i cluster di dati ma non tocca il record MFT. Ottieni un record eliminato con $FILE_NAME completo, $STANDARD_INFORMATION completo e $DATA che punta a cluster azzerati. Il nome e i timestamp sopravvivono assolutamente. Questo confonde gli utenti che si aspettavano che SDelete fosse più completo di quanto è.

Eliminazione tramite hard link. Rimuovere un hard link non elimina il file; l'attributo $FILE_NAME per quel link viene rimosso e il conteggio degli hardlink cala. Il file stesso viene eliminato solo quando l'ultimo link è rimosso. Se vedi un record MFT eliminato con hardlink_count a zero e nessun $FILE_NAME rimanente, il file è stato eliminato per davvero. Se vedi un record con un conteggio hardlink non zero e un $FILE_NAME mancante, l'eliminazione era parziale.

File rinominati prima dell'eliminazione. Alcuni dropper rinominano il loro file di staging in un nome innocuo immediatamente prima di eliminarlo, sperando che il $FILE_NAME superstite suoni innocente. Il journal USN conserva la coppia RENAME_OLD_NAME e RENAME_NEW_NAME, così puoi recuperare il nome originale da lì. La MFT da sola mostra solo il nome finale.

Il cestino non è un'eliminazione. I file mandati al cestino vengono rinominati e spostati in \$Recycle.Bin\<SID>\. Il record MFT resta IN_USE=1 e il file è intatto sotto un nome $R<ID>. Il record compagno $I<ID> registra il percorso originale. Svuotare il cestino elimina poi normalmente.

Strumenti che leggono bene i record eliminati

Per il triage uso uno di:

  • MFTECmd con --de 1 (drop entries) o semplicemente output non filtrato filtrato a valle. Marca i dati residenti e ti dà il numero di sequenza.
  • omerbenamram/mft_dump con -o json. Numero di sequenza, flag residente, elenco completo degli attributi. Buono per essere pipato in uno script che tira fuori record dove IN_USE=0 e seq corrisponde a un riferimento USN.
  • fls -m -r del Sleuth Kit per un bodyfile che include voci eliminate. Vecchio stile, funziona ancora. icat -r recupera i dati di file non residenti i cui cluster sono intatti.
  • analyzeMFT se vuoi specificamente un'opzione pure-Python e non ti importa la velocità.

Il parser nel browser di questo sito filtra a IN_USE=0 con un clic e mostra i dati residenti inline. Se il volume era importante, il file era piccolo e lo slot non è stato riusato, hai spesso i byte davanti a te nella tabella.

Cosa ancora non puoi rispondere dalla sola MFT

La MFT ti dice che un record esiste ed è stato eliminato. Non ti dice chi l'ha eliminato. Per quello vuoi Security 4663 (object access) se le SACL erano configurate, o Sysmon Event ID 23 (FileDelete) che registra l'utente e il processo. Sulla maggior parte degli host nessuno dei due è abilitato. In quel caso ricadi su prove corroboranti: un hit di Prefetch per uno strumento di eliminazione, una voce di Amcache per un binario sconosciuto in esecuzione al momento giusto, voci di Recent File Cache della stessa finestra.

La MFT è il pavimento. Costruisci il resto della storia sopra.

Letture aggiuntive

  • Brian Carrier, File System Forensic Analysis. I capitoli sulla semantica di eliminazione di NTFS restano definitivi.
  • Documentazione di fls del Sleuth Kit per l'output bodyfile canonico che include voci eliminate.
  • Microsoft, Master File Table. Il riferimento a livello MS su cosa NTFS garantisce e non garantisce.

Risorse esterne