Reconstruir uma timeline de actividade do utilizador a partir do journal USN

A partir de três minutos de registos do $UsnJrnl, é normalmente possível reconstruir o que um utilizador estava a fazer — Office, browser, downloads, código. Como ler o journal como um log de comportamento.

Por 7 min de leitura

Muito do «o que se passava neste computador entre as 14:00 e as 16:00» pode ser respondido directamente a partir do journal USN, sem qualquer outro artefacto. Os registos não são um log de syscalls e não estão etiquetados com um utilizador, mas são algo quase tão útil: um registo de alta frequência, ao nível de cada operação, de cada ficheiro que a máquina tocou. Com conhecimento de padrões que leva alguns casos a construir, é possível recuperar comportamento à granularidade de gravar no Office, navegação no browser, recompilação de IDE, pausa para almoço.

Este artigo é o guia prático para ler o journal como uma timeline de comportamento.

Porque é que isto sequer funciona

A maioria das acções visíveis para o utilizador num desktop Windows produz uma assinatura reconhecível no filesystem. Carregar em Guardar no Word e o Word escreve um ficheiro temporário, renomeia-o atomicamente e faz BasicInfoChange | Close no resultado. Abrir um separador novo no Chrome e a cache de disco acrescenta. Correr um npm install e um milhar de ficheiros package.json nascem em segundos.

Estas assinaturas não estão documentadas em nenhuma referência da Microsoft. Aprendem-se a olhar para journals de hosts em experiências controladas e a casá-los com actividade conhecida. Em baixo está um conjunto inicial, ordenado pela frequência com que vejo cada um em casos.

O Office em contexto real

Quando um utilizador grava um ficheiro Word, Excel ou PowerPoint vê:

FileCreate | Close            ~$<filename>.docx     (ficheiro de bloqueio)
FileCreate | Close            <filename>.tmp        (temp atómico)
DataExtend | Close            <filename>.tmp        × N
RenameOldName | Close         <filename>.docx
FileDelete | Close            <filename>.docx
RenameNewName | Close         <filename>.docx       (era <filename>.tmp)
FileDelete | Close            ~$<filename>.docx
BasicInfoChange | Close       <filename>.docx

O ficheiro de bloqueio ~$ é o sinal do Office de que um documento está aberto. O seu FileCreate e o FileDelete delimitam a janela de abertura/fecho com precisão. O rename atómico de .tmp para .docx é a própria gravação. O BasicInfoChange no fim é o ficheiro novo a ver o seu mtime carimbado ao fechar.

Um truque de pivot que uso em todos os casos: filtrar por registos FileCreate cujo nome começa por ~$. Isso dá todos os documentos do Office que o utilizador abriu na janela. Subtraia FileDelete dos mesmos nomes e fica com os documentos que ainda estavam abertos no momento da aquisição, o que numa captura ao vivo corresponde a documentos que o utilizador tinha abertos quando a máquina foi imagada. Esse último ponto já entrou em mais de um relatório como a resposta a «o que estava o utilizador efectivamente a fazer no momento em que entrámos».

Actividade no browser

Os browsers modernos mantêm caches pesadas no filesystem. Chrome e Edge usam \Users\<u>\AppData\Local\<browser>\User Data\Default\Cache\Cache_Data\ (mais Code Cache\). O Firefox usa \Users\<u>\AppData\Local\Mozilla\Firefox\Profiles\<id>\cache2\. Durante a navegação:

  • Uma taxa baixa e sustentada de FileCreate | Close e DataExtend | Close no directório de cache.
  • FileDelete | Close ocasional à medida que o LRU expulsa entradas antigas.
  • A cada poucos minutos, RenameNewName de ficheiros de cache à medida que o índice é compactado.

Rajadas de escritas em cache correlacionam-se com visitar sites pesados em media ou single-page-applications. Períodos quietos correlacionam-se com o utilizador estar ausente ou numa página que demora a carregar. A reprodução activa de vídeo produz uma forma diferente — DataExtend grande e sustentado num único ficheiro de cache em vez de muitas criações pequenas.

Os nomes dos ficheiros de cache não codificam URLs. Para isso, pivote para as próprias bases de dados SQLite do browser via ferramentas forenses de browser. A contribuição do journal é a cadência — que o utilizador estava activamente a navegar durante uma janela específica — mais os eventos explícitos FileCreate em \Users\<u>\Downloads\ para downloads deliberados.

Actividade de código

Se o utilizador for desenvolvedor, a actividade de IDE e ferramentas de build produz rajadas altamente características:

  • Webpack, Vite, Turbopack — muitos FileCreate em node_modules\.cache\, node_modules\.vite\, .next\ e dist\. Centenas por build.
  • Visual Studio C++FileCreate de .obj e .pdb em sub-árvores Debug\ ou Release\.
  • Cargo (Rust) — builds incrementais tocam pesadamente em target\debug\incremental\; builds completos tocam também em target\debug\deps\.
  • Go — rajadas curtas e intensas em $GOPATH\pkg\ e na cache de build sob \Users\<u>\AppData\Local\go-build\.
  • npm install e yarn install — milhares de registos FileCreate sob node_modules\ em dezenas de segundos. A actividade isolada mais barulhenta do utilizador no journal.

Uma rajada de cinco minutos de FileCreate em node_modules\ seguida de um enxame de DataExtend em dist\bundle.js é «correu o build, depois um dev server fez reload». Leia a secção de exclusões abaixo — estas rajadas vão abafar tudo o resto se não as filtrar para análises não-de-desenvolvimento.

Downloads e instalações

Um download directo via Chrome:

FileCreate | Close             \Users\<u>\Downloads\<file>.crdownload
DataExtend | Close             \Users\<u>\Downloads\<file>.crdownload  × N
RenameNewName | Close          \Users\<u>\Downloads\<file>
BasicInfoChange | Close        \Users\<u>\Downloads\<file>

O Firefox usa .part, o Edge usa .download. O rename atómico no fim é o que faz o ficheiro aparecer «completo» ao Explorador e a outros leitores.

A instalação de um novo programa segue tipicamente: FileCreate de um instalador (.exe, .msi, .appx) em Downloads, depois uma rajada de registos FileCreate sob \Program Files\, \Program Files (x86)\ ou \Users\<u>\AppData\Local\Programs\. O histograma por minuto torna as instalações trivialmente identificáveis. Cruze com AmCache e Prefetch para o lado da execução.

Pondo tudo junto: a receita da timeline diária

A receita para um relatório «o que fez o utilizador hoje»:

  1. Puxe o journal parseado do utilizador para o dia. Restrinja a registos cujo caminho resolvido começa por \Users\<u>\ (o utilizador alvo). Isto elimina o Windows Update, caches de sistema e ruído do SO que de outra forma domina.
  2. Calcule, por balde de 10 minutos: contagens de FileCreate, DataExtend, BasicInfoChange.
  3. Trace as três séries. A forma diz-lhe a actividade aproximada:
    • Muitas criações mais extend. Escrita ou gravação de conteúdo.
    • Muito BasicInfoChange sozinho. Navegação, scrolling, edição leve em que o Office ou o editor toca no ficheiro sem escritas significativas.
    • Muito extend com pouca criação. Download grande ou reprodução de media.
    • Criações sustentadas em caminhos Cache\. Navegação.
    • Criações sustentadas em node_modules\ ou target\ ou Debug\. Programar.
  4. Anote picos inspeccionando os cinco nomes de ficheiros principais em cada balde. Nomes de ficheiros Office e ficheiros de bloqueio ~$ são óptimas âncoras. Nomes de cache pode normalmente ignorá-los.

O parser desta página expõe o histograma por minuto no seu componente de timeline. Clicar numa barra filtra a tabela a essa janela, que é o fluxo acima sem escrever código.

Para atribuição — que utilizador estava ao teclado — combine a timeline do journal com logons interactivos 4624 do Security.evtx (LogonType=2) e logoffs 4647 iniciados pelo utilizador a partir do parser EVTX. Isso delimita as fronteiras da sessão e dá-lhe um nome para pôr na actividade.

Exclusões e armadilhas

Scans de backup e AV produzem rajadas de BasicInfoChange ao nível do volume que se parecem superficialmente com actividade do utilizador. Seguem horários agendados e visitam cada directório em vez de se focarem numa sub-árvore. Fáceis de identificar pela cobertura de caminhos e de excluir.

Agentes de sincronização (OneDrive, Dropbox, Google Drive Backup and Sync) geram tráfego de journal que parece actividade do utilizador mas é o trabalho do próprio agente. Filtre para registos fora da pasta de sincronização para actividade iniciada pelo utilizador, ou olhe especificamente dentro da pasta de sincronização para o padrão de exfiltração via cloud documentado no artigo de exfiltração.

Indexadores em background. SearchIndexer.exe toca em ficheiros em \Users\<u>\AppData\Roaming\Microsoft\Windows\Recent\ e \ProgramData\Microsoft\Search\. MsMpEng.exe (Defender) produz eventos BasicInfoChange quando faz scans. Ambos são fáceis de classificar como ruído de sistema.

Chrome Software Reporter, Edge updater, Windows Update. Todos produzem rajadas previsíveis de FileCreate e DataExtend em \Program Files\ e \Windows\SoftwareDistribution\. Filtre por caminho.

node_modules\ e outras saídas de build dominam qualquer timeline que os inclua. Para casos não-de-desenvolvimento, exclua node_modules\, target\, Debug\, Release\, obj\, bin\, .next\, dist\, build\ por prefixo de caminho.

O que o journal não consegue reconstruir

  • A identidade do utilizador. Correlacione timestamps com logons 4624 do Security.evtx.
  • As URLs que o utilizador visitou. As bases de dados de histórico do browser detêm-nas — o journal só conhece a cadência das escritas em cache.
  • O conteúdo de qualquer ficheiro. Apenas metadados.
  • Qualquer coisa fora da janela do buffer circular. Um $J de 32 MB cobre alguns dias num desktop. Tudo o que for mais antigo desapareceu deste artefacto; puxe Shadow Copies e $LogFile se precisar de mais alcance.

Para 80% das perguntas «o que estava o utilizador a fazer entre X e Y», $J e $MFT juntos respondem directamente. Os restantes 20% pedem Sysmon, EVTX, SRUM para uso de rede e CPU ao nível da aplicação, e uma super-timeline em condições.

Leituras adicionais