← Voltar ao blog

O que sobrevive de facto quando se elimina um ficheiro em NTFS

· 7 min de leitura

A frase mais útil que posso oferecer a um examinador novo sobre NTFS: eliminar não é apagar. É uma mudança de flag e uma actualização de índice. O registo do MFT do ficheiro fica onde está. Os clusters de dados são marcados como livres em $Bitmap. Nada é sobrescrito até que outra coisa peça aquele espaço.

As pessoas sabem isto em abstracto. O erro que continuo a ver é assumir que a janela de sobrevivência é generosa em qualquer máquina. Não é. Num file server ocupado, o slot é reutilizado em minutos. Numa estação de trabalho que ninguém usa ao fim-de-semana, o registo eliminado pode ficar um mês. Tem de saber que tipo de host está a olhar antes de se comprometer com uma história sobre se algo continua recuperável.

O que o registo ainda contém

Um registo de MFT eliminado tem uma estrutura idêntica a um vivo. O bit IN_USE (bit 0 no campo de flags, no offset 0x16) está limpo. Tudo o resto, a não ser que o registo tenha sido reivindicado, é o que o NTFS escreveu por último:

  • $STANDARD_INFORMATION (tipo de atributo 0x10): os quatro carimbos temporais no SI, as flags DOS, a referência ao descritor de segurança, o owner ID, o ponteiro USN. Os carimbos temporais sobrevivem à eliminação intactos. Note que o SI que vê é como o ficheiro ficou no momento da eliminação, não quando foi originalmente criado (o Windows actualiza o SI constantemente enquanto o ficheiro está vivo).
  • $FILE_NAME (0x30): um por hard link, mais o nome curto 8.3 em volumes com disable8dot3 desligado. A referência ao directório-pai é o número de registo MFT do directório onde o ficheiro vivia. Essa referência aguenta-se mesmo que o próprio directório tenha sido eliminado depois, que é como fls e MFTECmd reconstroem caminhos para dentro de hierarquias de directórios eliminados.
  • $DATA (0x80): para ficheiros residentes (sob ~700 bytes de dados), os bytes ficam inline no registo. Para ficheiros não residentes, a runlist aponta para os clusters que eram o ficheiro. Esses clusters já não estão marcados como alocados, mas também não foram zerados.
  • $ATTRIBUTE_LIST (0x20) quando presente, com referências a quaisquer registos de extensão que o ficheiro usava. Esses registos de extensão estão eles próprios eliminados mas, até serem reclamados, ainda são analisáveis.

O número de sequência é o que torna a análise de ficheiros eliminados defensável. Cada registo carrega um número de sequência de 16 bits que incrementa cada vez que o slot é reutilizado. Uma entrada do USN journal ou uma referência do $LogFile que aponta para o registo 12345 sequência 3 continua a apontar para a sequência 3 mesmo depois de o slot estar agora na sequência 4. Essa discrepância é o que lhe diz que o slot foi reutilizado desde então.

Quando o slot desaparece de facto

Dois eventos terminam independentemente a recuperabilidade:

O slot do registo MFT é reutilizado. O NTFS não tem uma estratégia de alocação fixa aqui. Na prática, quando um novo ficheiro precisa de um registo, o driver olha para $MFT:$BITMAP para o registo livre com número mais baixo e usa-o. Os registos eliminados são recuperados aproximadamente por ordem. Num volume muito usado, essa ordem corre depressa. O próprio MFT só cresce; nunca encolhe, por isso registos eliminados antigos bem acima da marca actual podem sobreviver durante anos.

Os clusters de dados são sobrescritos. Independente do registo. Os clusters foram marcados como livres em $Bitmap, por isso qualquer alocador pode reivindicá-los. Num ficheiro recentemente eliminado, ambos os eventos têm de ocorrer antes de a recuperação se tornar desesperada. Já vi registos a sobreviver mas os clusters há muito desaparecidos (recupera-se só os metadados e dados residentes) e o inverso (o registo é reutilizado mas os clusters ainda contêm os bytes originais e podem ser carved).

Não há um cronómetro limpo para nenhuma das duas. "Quanto tempo duram os ficheiros eliminados em NTFS" tem a mesma resposta honesta que "quanto tempo dura um lugar livre ao balcão": até alguém o ocupar.

O que os journals acrescentam

O MFT mostra-lhe o presente. O USN journal mostra-lhe o verbo. Um registo USN de FILE_DELETE nomeia o ficheiro, o directório-pai e o carimbo temporal da eliminação. Mesmo que o slot do MFT tenha sido entretanto reutilizado, a entrada USN continua a preservar o nome antigo e o par registo/sequência original. Combine os dois e obtém algo como:

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 (still readable, deleted)
2026-04-12T13:08:11Z MFT FN parent=12, name=secrets.zip

Isto é uma resposta reconstrutível à pergunta "como era este ficheiro na altura da eliminação", mesmo que o ficheiro tenha desaparecido. O $LogFile acrescenta detalhe ao nível das transacções nos segundos imediatamente adjacentes: a eliminação fica enquadrada por um par DeleteAttribute e DeallocateFileRecordSegment, e geralmente consegue identificar as operações em redor.

Se o VSS estava activo e existe um snapshot anterior à eliminação, o $MFT do snapshot ainda mostra IN_USE=1 para o mesmo registo/sequência, e os clusters de dados foram preservados por copy-on-write. Veja Volume Shadow Copy e $MFT para os detalhes da extracção.

Os casos em que as pessoas se enganam

Ferramentas de eliminação segura. O SDelete no modo por omissão sobrescreve os clusters de dados mas não faz nada ao registo MFT. Fica com um registo eliminado com $FILE_NAME completo, $STANDARD_INFORMATION completo e $DATA a apontar para clusters zerados. O nome e os carimbos temporais sobrevivem absolutamente. Isto apanha utilizadores que esperavam que o SDelete fosse mais minucioso do que é.

Eliminação de ficheiros através de hard links. Remover um hard link não elimina o ficheiro; o atributo $FILE_NAME desse link é removido e o contador de hard links desce. O ficheiro só é eliminado quando o último link é removido. Se vir um registo MFT eliminado com hardlink_count de zero e nenhum $FILE_NAME restante, o ficheiro foi verdadeiramente eliminado. Se vir um registo com contador de hard links diferente de zero e um $FILE_NAME em falta, a eliminação foi parcial.

Ficheiros renomeados antes da eliminação. Alguns droppers renomeiam o seu ficheiro de staging para um nome inócuo imediatamente antes de o eliminar, na esperança de que o $FILE_NAME sobrevivente seja lido como inocente. O USN journal preserva o par RENAME_OLD_NAME e RENAME_NEW_NAME, por isso pode recuperar de lá o nome original. O MFT, por si só, mostra apenas o nome final.

A reciclagem não é uma eliminação. Os ficheiros enviados para a reciclagem são renomeados e movidos para \$Recycle.Bin\<SID>\. O registo MFT continua IN_USE=1 e o ficheiro está intacto sob um nome $R<ID>. O registo companheiro $I<ID> regista o caminho original. Esvaziar a reciclagem elimina depois normalmente.

Ferramentas que lêem bem registos eliminados

Para triagem, recorro a uma de:

  • MFTECmd com --de 1 (drop entries) ou simplesmente saída sem filtro filtrada a jusante. Marca dados residentes e dá-lhe o número de sequência.
  • omerbenamram/mft_dump com -o json. Número de sequência, flag de residente, lista completa de atributos. Bom para enviar para um script que extraia registos onde IN_USE=0 e seq corresponda a uma referência USN.
  • fls -m -r do Sleuth Kit para um bodyfile que inclui entradas eliminadas. Old-school, continua a funcionar. O icat -r recupera os dados de ficheiros não residentes cujos clusters estão intactos.
  • analyzeMFT se especificamente quiser uma opção em Python puro e não se importar com a velocidade.

O parser de browser deste site filtra para IN_USE=0 com um clique e faz emergir os dados residentes inline. Se o volume era importante, o ficheiro era pequeno e o slot não foi reutilizado, frequentemente tem os bytes à sua frente na tabela.

O que continua a não conseguir responder só com o MFT

O MFT diz-lhe que um registo existe e foi eliminado. Não lhe diz quem o eliminou. Para isso, quer Security 4663 (acesso a objecto) se as SACLs estavam configuradas, ou o Sysmon Event ID 23 (FileDelete) que regista o utilizador e o processo. Na maioria dos hosts, nenhum dos dois está activado. Nesse caso, recorre a evidência corroborativa: um hit de Prefetch para uma ferramenta de eliminação, uma entrada Amcache de um binário pouco familiar a correr na altura certa, entradas de recent file cache da mesma janela.

O MFT é o piso. Construa o resto da história em cima.

Leituras adicionais

  • Brian Carrier, File System Forensic Analysis. Os capítulos sobre semântica de eliminação NTFS continuam a ser definitivos.
  • Documentação do fls do Sleuth Kit para a saída canónica de bodyfile que inclui entradas eliminadas.
  • Microsoft, Master File Table. A referência ao nível da MS para o que o NTFS garante e não garante.

Recursos externos