La parte más difícil de trabajar con el journal USN no suele ser parsearlo — es ponerle las manos encima al fichero. $UsnJrnl:$J es un flujo de datos alternativo, no un fichero normal: no aparece en el Explorador y no sobrevive a un copy ingenuo. Este artículo recorre las maneras realistas de extraerlo en los tres contextos donde se encuentra: una imagen forense de disco, un volumen montado y una máquina en vivo.
Qué se busca
El journal vive en la ruta:
\$Extend\$UsnJrnl:$J
$Extend es un directorio de metadatos NTFS oculto, y $J es uno de los dos flujos alternativos del fichero de metadatos $UsnJrnl (el otro, $Max, solo guarda metadatos de tamaño). Microsoft documenta el layout en la referencia interna de NTFS y la estructura USN_RECORD_V2.
Un $J del mundo real suele pesar entre 30 MB y varios GB según cómo se haya configurado fsutil usn.
Desde una imagen forense (E01, dd, AFF4)
Es el caso más común en DFIR.
FTK Imager (gratuito, GUI)
- Abrir la imagen (
File → Add Evidence Item). - Navegar a
[root]/$Extend/$UsnJrnl. - Clic derecho sobre el flujo
$J→ Export Files.
FTK Imager trata los flujos alternativos como entradas de primer nivel — aparecen como filas hermanas junto al fichero. Hay que seleccionar la fila $J específicamente (no $Max).
X-Ways Forensics (comercial)
X-Ways expone la misma ruta. En el árbol de directorios, expandir Root directory → $Extend → $UsnJrnl, seleccionar el flujo $J y hacer Recover/Copy.
The Sleuth Kit (gratuito, CLI, multiplataforma)
Es la elección de los analistas en Mac/Linux. La herramienta relevante es icat de TSK:
# Encontrar la entrada MFT de $UsnJrnl
fls -r -p image.dd | grep '\$UsnJrnl'
# Supongamos inode 81 y flujo $J en atributo 128-2:
icat image.dd 81-128-2 > UsnJrnl-J.bin
El triple <inode>-<type>-<id> es la forma en que TSK direcciona los flujos alternativos. El type/id que necesitas es el del atributo cuyo nombre termina en :$J — fls lo muestra en su salida larga.
Velociraptor / KAPE
Para colectas de triage amplias, el artefacto Windows.NTFS.MFT de Velociraptor y KAPE saben recuperar el journal automáticamente. KAPE usa targets (!ALL o USNJournal); Velociraptor usa el plugin parse_ntfs.
Desde un volumen montado
Si la imagen está montada (en solo lectura, vía mount -t ntfs-3g o Arsenal Image Mounter en Windows), la ruta aparece como fichero normal, pero la mayoría de las herramientas se niegan a leer flujos alternativos de forma transparente.
En Linux con ntfs-3g, se puede leer el flujo directamente:
sudo cat '/mnt/image/$Extend/$UsnJrnl:$J' > UsnJrnl-J.bin
Según la opción de montaje streams_interface, :$J puede aparecer como un componente de ruta separado en lugar de un sufijo — comprobar con ls -la /mnt/image/\$Extend/.
Desde un host Windows en vivo
Necesitas privilegios administrativos y un lector consciente de NTFS, porque Windows bloquea el acceso ordinario a los ficheros de metadatos.
PowerShell con lectura raw del volumen
Las herramientas de Eric Zimmerman incluyen RawCopy.exe (o RawCopy64.exe), que pasa por encima de la API de ficheros estándar:
RawCopy.exe /FileNamePath:"C:\$Extend\$UsnJrnl:$J" /OutputPath:"D:\Out"
Si no puedes dejar binarios, PowerForensics hace lo mismo en PowerShell puro:
Import-Module PowerForensics
Get-ForensicFileRecord -Path 'C:\$Extend\$UsnJrnl' |
ForEach-Object { $_.GetContent() } |
Set-Content -Path 'C:\Out\UsnJrnl-J.bin' -Encoding Byte
fsutil nativo
fsutil usn es la superficie de control soportada para el journal, pero no es una herramienta de extracción — sabe leer, consultar y borrar registros, no streamear el blob completo $J. Sí es útil para verificar que el journal está habilitado y bien dimensionado antes de extraer:
fsutil usn queryjournal C:
Un Status: 0x00000000 con Maximum Size no nulo señala un journal activo. Un 0x80000005 o equivalente indica que el journal está deshabilitado y no hay nada que extraer — ver la referencia de fsutil usn para los comandos de ciclo de vida.
Después de la extracción
Ya con el fichero $J en mano, lo sueltas en este sitio o lo pasas a la herramienta de tu elección. Los bytes carvados son exactamente la entrada esperada por usnrs, PoorBillionaire/USN-Journal-Parser o MFTECmd de Eric Zimmerman.
Si además recuperas el $MFT (mismo vecindario $Extend, entrada MFT 0), podrás resolver rutas completas en lugar de solo nombres — ver el mecanismo de resolución de rutas en usnrs y la entrada $MFT de nuestro parser.
Trampas habituales
- Copiar con el Explorador: arrastrar y soltar
$UsnJrnlcopia silenciosamente el flujo sin nombre por defecto (vacío) y no$J. Usar siempre una herramienta forense. - Journal deshabilitado: las máquinas en workgroup a veces tienen el journal deshabilitado.
fsutil usn queryjournales la comprobación más barata. $Jempieza con ceros dispersos: el journal es un flujo sparse — los primeros cientos de MB pueden ser todo ceros antes del primer registro real.usnrs, nuestro parser y la mayoría de los demás saltan automáticamente. Si escribes tu propio parser,Skip::find_first_recorden usnrs es la implementación de referencia más corta.- Wrapping del flujo: según la actividad del volumen, el buffer circular del journal puede haber dado la vuelta — las entradas más antiguas han desaparecido. El USN más pequeño que encuentres marca hasta dónde llega el historial disponible.