← Voltar ao blog

Entendendo o journal USN do NTFS ($UsnJrnl:$J)

Introdução prática ao journal Update Sequence Number do NTFS — o que é, como é estruturado em disco e por que é tão valioso na forense de Windows.

3 min de leitura

O journal Update Sequence Number do NTFS — comumente chamado de USN Journal ou simplesmente $UsnJrnl:$J — é um dos artefatos mais subestimados da forense de Windows. Toda vez que o NTFS cria, apaga, renomeia, trunca ou toca um arquivo em um volume, ele acrescenta um registro a esse log. Os registros são minúsculos (algumas dezenas de bytes cada) e o journal é gerenciado como um buffer circular de tamanho fixo — uma máquina ativa preserva tipicamente os últimos milhões de operações de arquivo.

Onde o journal vive

O journal não é um arquivo comum. É um fluxo de dados alternativo chamado $J, anexado ao arquivo \$Extend\$UsnJrnl na raiz do volume. A partir de uma imagem forense você normalmente o extrai com uma ferramenta que entende streams de metadados NTFS (FTK Imager, X-Ways, icat do The Sleuth Kit, ...). O blob $J resultante é o que ferramentas como o parser WebAssembly deste site ou usnrs consomem.

Estrutura de um registro (USN_RECORD_V2)

Cada registro é uma struct USN_RECORD_V2:

CampoBytesSignificado
RecordLength4Tamanho total do registro, incluindo nome
Major / Minor version2 + 2Atualmente 2.0
FileReferenceNumber8Entrada MFT + sequência do arquivo
ParentFileReferenceNumber8Entrada MFT + sequência do diretório pai
USN8Posição do registro dentro do journal
Timestamp8FILETIME do Windows (ticks de 100 ns desde 1601-01-01)
Reason4Bitmask descrevendo o que mudou (FileCreate, Close, ...)
SourceInfo4Pistas (ex. DATA_MANAGEMENT para mudanças dirigidas pelo SO)
SecurityId4Índice em $Secure:$SII
FileAttributes4Atributos NTFS padrão
FilenameLength / Offset2 + 2Posição do nome UTF-16 no registro
FilenamenUTF-16 LE, sem terminador nulo

O campo "reason" é o mais informativo: é uma bitmask, e o ciclo de vida típico de um único arquivo produz uma sequência como FileCreate | DataExtendDataExtend | CloseBasicInfoChange | CloseFileDelete | Close. Reconstruir essa sequência é como você consegue, a posteriori, contar o que realmente aconteceu com o arquivo.

Por que importa em DFIR

Duas razões:

  1. Sobrevive ao apagamento. Mesmo depois que um arquivo some do sistema de arquivos (e da lixeira), seu histórico de operações permanece no journal até que o buffer circular o sobrescreva.
  2. É barato de consultar. Um $J de 100 MB tipicamente guarda milhões de registros cobrindo dias a semanas de atividade, e cada registro é autodescritivo.

Quando você correlaciona o journal contra o $MFT, pode resolver caminhos completos para quase todos os registros — o $MFT fornece a cadeia parental via o atributo $FILE_NAME de cada entrada. É exatamente o que a opção «arraste seu $MFT» deste site faz por você.

O que vem a seguir

Se você nunca olhou um journal, o jeito mais fácil de ter uma noção é pegar um de uma máquina de teste e arrastá-lo para a caixa no topo desta página. Os próximos artigos da série vão escavar nos flags de razão, nos trade-offs do journal carving e em como o journal se posiciona ao lado dos demais artefatos de timeline do Windows ($LogFile, Prefetch, ShimCache).