← Voltar ao blog

Provar que um ficheiro existiu quando já não está no disco

· 7 min de leitura

Os engagements forenses giram muitas vezes em torno de uma única pergunta: este ficheiro alguma vez esteve neste computador? Não "está lá agora" (isso é o dir). A pergunta mais difícil: conseguimos mostrar que esteve lá ontem, na semana passada, no ano passado? Para volumes NTFS, a resposta é geralmente sim, e o $MFT é a fonte única mais forte. Frequentemente o conteúdo do ficheiro também volta.

Esta é a visão prática do que se pode provar só com os metadados do MFT, que corroboração os journals acrescentam, e os casos em que as afirmações confiantes desmoronam na revisão.

O que sobrevive a uma eliminação

Quando um ficheiro é eliminado em NTFS, o bit IN_USE no cabeçalho do registo é limpo e a entrada de índice no directório-pai é removida. O próprio registo fica, contendo:

  • $FILE_NAME com o nome do ficheiro original e a referência ao registo MFT do directório-pai.
  • Oito carimbos temporais (quatro em $STANDARD_INFORMATION, quatro em $FILE_NAME) congelados no momento da eliminação.
  • Tamanhos lógico e físico dos dados do ficheiro.
  • Para ficheiros pequenos (~700 bytes ou menos de $DATA), o conteúdo inteiro do ficheiro guardado inline no registo. Veja resident data.
  • Para ficheiros maiores, a runlist dos clusters que continham os dados. Esses clusters podem ou não ainda conter os bytes originais.
  • O número de sequência do registo, que prova que está a olhar para o ficheiro que viveu nesse slot naquela altura (não para um inquilino posterior).

Um registo MFT eliminado com $FILE_NAME = secret-plan.docx, referência ao pai resolvendo em \Users\bob\Documents, e SI created 2024-11-03T14:02:11Z demonstra que um ficheiro com esse nome existiu nesse directório nesse dia. O registo é a evidência, e a evidência está assinada pelo próprio NTFS, no sentido em que o driver do sistema de ficheiros a escreveu.

O que torna a evidência defensável

Três propriedades fazem com que os registos MFT se aguentem numa revisão em que alguém está a tentar partir o seu caso:

  1. O NTFS escreve-os ele próprio, não o utilizador. Os registos não são editáveis por utilizador através das APIs normais do Windows. Um arguido não pode alegar de forma credível que um único registo foi plantado a menos que alegue que todo o $MFT foi forjado, o que é uma fasquia alta com os cruzamentos de journal abaixo.
  2. Oito carimbos temporais cruzam-se. A manipulação geralmente nota-se. SI mudado mas FN inalterado é a assinatura de timestomping clássica; veja os quatro carimbos temporais do MFT. SI created a anteceder FN created é impossível naturalmente.
  3. $UsnJrnl e $LogFile corroboram. Se o $MFT diz que o ficheiro foi criado no tempo T, o USN journal deve registar FILE_CREATE no mesmo tempo. Desacordos são em si evidência (de forja ou de erro de parser; nos dois casos vale a pena perseguir).
  4. Snapshots VSS são independentes. Um snapshot anterior à eliminação contém uma cópia do MFT onde o ficheiro era IN_USE=1. O snapshot foi escrito pelo VSS num tempo conhecido. Duas testemunhas independentes ($MFT vivo + $MFT do snapshot) a mostrar o mesmo ficheiro é muito mais forte do que qualquer uma sozinha. Veja Volume Shadow Copy e $MFT.

Vale a pena demorar nesse quarto ponto. Em casos sérios procuro sempre snapshots VSS. Convertem uma única observação numa série de observações, cada uma num ponto diferente no tempo, e são escritos por um caminho de código inteiramente diferente do MFT vivo. Difícil forjar os dois consistentemente.

O que não se pode provar só com o $MFT

O MFT prova que o ficheiro existiu num directório específico num tempo específico, com o tamanho e os carimbos temporais específicos no registo. Não prova:

  • Quem o criou ou acedeu. Para isso são necessários logs de eventos de Security (4663 com SACLs, Sysmon Event ID 11/15, ou 4688 criação de processo com linha de comandos se o ficheiro foi nomeado numa linha de comandos).
  • Que programa o produziu. Prefetch, Amcache e Shimcache ajudam aqui. O Sysmon Event ID 1 é o padrão de ouro se estava activado.
  • O que continha o ficheiro, para ficheiros grandes, a menos que recupere os clusters de dados. Ficheiros residentes dão-lhe os bytes; ficheiros não residentes requerem que a runlist de clusters ainda aponte para espaço não alocado e não sobrescrito.
  • Se um utilizador realmente o abriu. Jump lists, ficheiros LNK, e RecentFileCache são mais úteis aqui.
  • Se foi visto por alguém além do utilizador dono do directório. Isso precisa de logs de auditoria de ACL.

Uma resposta completa geralmente funde o MFT com os artefactos circundantes. O MFT é a pedra angular porque sem ele as outras peças não têm onde se ancorar. Um hit de Prefetch para secret-tool.exe é interessante; o mesmo hit emparelhado com um registo MFT a mostrar que secret-tool.exe foi largado em \Temp\ no mesmo minuto por um processo cujo Sysmon Event ID 1 está na timeline é conclusivo.

Um fluxo de trabalho que se aguenta na revisão

  1. Adquira $MFT, $UsnJrnl:$J, $LogFile, todos os snapshots VSS. Faça hash a tudo (SHA-256). Documente o tempo de aquisição.
  2. Analise o MFT. Encontre o registo para o ficheiro em questão, vivo ou eliminado. Puxe o número de sequência, a referência ao pai, todos os oito carimbos temporais, o $DATA residente se houver, e a runlist de clusters caso contrário.
  3. Resolva a referência ao pai seguindo o registo MFT do pai. Repita até chegar ao registo 5 (a raiz). A cadeia resultante é o caminho do directório. Cruze-a contra qualquer caminho que tenha de logs ou relatos de testemunhas.
  4. Cruze com o USN journal. Para o mesmo par registo/sequência, liste todas as entradas USN. FILE_CREATE dá-lhe a criação original; FILE_DELETE dá-lhe a eliminação. Os motivos pelo meio são a história do ficheiro.
  5. Compare com os MFTs dos snapshots VSS. A cópia de cada snapshot do mesmo registo dá-lhe um checkpoint. Se três snapshots mostram o registo IN_USE=1 com carimbos temporais consistentes e o MFT vivo mostra IN_USE=0, tem quatro testemunhas independentes a concordar sobre a existência do ficheiro e uma testemunha sobre a eliminação.
  6. Documente as impossibilidades que excluiu. Divergência SI/FN verificada. Números de sequência consistentes. Carimbos temporais dos snapshots coerentes. A narrativa da defesa tem de explicar todas estas para minar a sua conclusão.

A última etapa é o que separa uma descoberta de um argumento. Listar o que verificou e o que excluiu torna a cadeia de raciocínio visível.

Casos extremos que mordem

Hard links. Um ficheiro com múltiplos hard links vive por múltiplos atributos $FILE_NAME. Eliminar um link apenas remove esse nome; o ficheiro permanece. Confirme que a eliminação que está a seguir corresponde de facto ao desaparecimento do ficheiro, não apenas à remoção de um único nome.

Ficheiro renomeado antes da eliminação. Alguns droppers renomeiam o ficheiro de staging para um nome inócuo imediatamente antes da eliminação, na esperança de que o $FILE_NAME sobrevivente seja lido como inocente. O USN journal preserva o par RENAME_OLD_NAME / RENAME_NEW_NAME. Puxe-o.

Slot de registo reutilizado. O slot de um ficheiro eliminado foi reivindicado por um novo ficheiro. O registo MFT actual é o novo ficheiro na sequência N; o journal referencia o ficheiro antigo na sequência N-1. Use o número de sequência para desambiguar. Referências que apontam para uma sequência diferente da actual estão a apontar para um inquilino anterior.

O ficheiro nunca existiu e alguém está a mentir. Menos comum, mas vale a pena saber. Forja pura de metadados é difícil de fazer consistentemente entre MFT, USN, e VSS, mas um operador determinado com acesso de admin tem ferramentas. Procure inconsistências entre artefactos que deveriam concordar.

Leituras adicionais

Recursos externos