← Zurück zum Blog

Wie man $UsnJrnl:$J aus einem Disk-Image (oder einem laufenden System) extrahiert

Praktischer Leitfaden, um das NTFS-USN-Journal aus einem forensischen Image, einem gemounteten Volume oder einem laufenden Windows-Host herauszuziehen — mit FTK Imager, X-Ways, The Sleuth Kit, fsutil und PowerShell.

4 Min. Lesezeit

Das Schwierigste am Arbeiten mit dem USN-Journal ist oft nicht das Parsen — sondern die Datei überhaupt in die Finger zu bekommen. $UsnJrnl:$J ist ein alternativer Datenstrom, keine normale Datei: er taucht nicht im Explorer auf und überlebt kein naives copy. Dieser Beitrag geht die realistischen Wege durch, ihn aus den drei Kontexten herauszuziehen, in denen man ihn antrifft: einem forensischen Disk-Image, einem gemounteten Volume und einem laufenden Rechner.

Wonach man sucht

Das Journal wohnt unter dem Pfad:

\$Extend\$UsnJrnl:$J

$Extend ist ein verstecktes NTFS-Metadatenverzeichnis und $J ist einer der zwei alternativen Streams der Metadatendatei $UsnJrnl (der andere, $Max, hält nur Größen-Metadaten). Microsoft dokumentiert das Layout in der NTFS-internen Referenz und der Struktur USN_RECORD_V2.

Ein realistisches $J ist je nach Konfiguration von fsutil usn typischerweise 30 MB bis mehrere GB groß.

Aus einem forensischen Disk-Image (E01, dd, AFF4)

Der häufigste Fall in der DFIR.

FTK Imager (kostenlos, GUI)

  1. Image öffnen (File → Add Evidence Item).
  2. Zu [root]/$Extend/$UsnJrnl navigieren.
  3. Rechtsklick auf den $J-Stream → Export Files.

FTK Imager behandelt alternative Datenströme als gleichrangige Einträge — sie erscheinen als Geschwister-Zeilen neben der Datei. Unbedingt die $J-Zeile auswählen (nicht $Max).

X-Ways Forensics (kommerziell)

X-Ways legt den gleichen Pfad offen. Im Verzeichnisbaum Root directory → $Extend → $UsnJrnl ausklappen, den $J-Stream auswählen und Recover/Copy.

The Sleuth Kit (kostenlos, CLI, plattformübergreifend)

Das ist es, wonach die meisten Mac-/Linux-Analysten greifen. Das relevante Tool ist icat aus TSK:

# Den MFT-Eintrag von $UsnJrnl finden
fls -r -p image.dd | grep '\$UsnJrnl'
# Angenommen Inode 81, $J-Stream als Attribut 128-2:
icat image.dd 81-128-2 > UsnJrnl-J.bin

Das Tripel <inode>-<type>-<id> ist TSKs Adressierung für alternative Streams. Type/Id ist das, dessen Attributname auf :$J endet — fls zeigt das in der Langausgabe.

Velociraptor / KAPE

Für breite Triage-Sammlungen wissen Velociraptors Windows.NTFS.MFT-Artefakt und KAPE das Journal automatisch zu ziehen. KAPE arbeitet mit Targets (!ALL oder USNJournal); Velociraptor nutzt das parse_ntfs-Plugin.

Aus einem gemounteten Volume

Ist das Image gemountet (read-only, via mount -t ntfs-3g oder Arsenal Image Mounter unter Windows), erscheint der Pfad als normale Datei, aber die meisten Tools weigern sich, alternative Streams transparent zu lesen.

Unter Linux mit ntfs-3g lässt sich der Stream direkt lesen:

sudo cat '/mnt/image/$Extend/$UsnJrnl:$J' > UsnJrnl-J.bin

Je nach Mount-Option streams_interface kann :$J als separater Pfadbestandteil statt als Suffix erscheinen — mit ls -la /mnt/image/\$Extend/ prüfen.

Auf einem laufenden Windows-Host

Du brauchst Administrator-Rechte und einen NTFS-bewussten Reader, weil Windows den gewöhnlichen Zugriff auf Metadatendateien blockiert.

PowerShell mit Raw-Volume-Lesen

Eric Zimmermans Tools enthalten RawCopy.exe (bzw. RawCopy64.exe), das die Standard-Datei-API umgeht:

RawCopy.exe /FileNamePath:"C:\$Extend\$UsnJrnl:$J" /OutputPath:"D:\Out"

Falls du keine Binärdatei ablegen kannst, macht PowerForensics dasselbe in reinem PowerShell:

Import-Module PowerForensics
Get-ForensicFileRecord -Path 'C:\$Extend\$UsnJrnl' |
  ForEach-Object { $_.GetContent() } |
  Set-Content -Path 'C:\Out\UsnJrnl-J.bin' -Encoding Byte

Eingebautes fsutil

fsutil usn ist die unterstützte Steuerschnittstelle für das Journal, aber kein Extraktionswerkzeug — es kann Einträge lesen, abfragen und löschen, nicht den gesamten $J-Blob streamen. Nützlich ist es, um vor der Extraktion zu verifizieren, dass das Journal aktiv und passend dimensioniert ist:

fsutil usn queryjournal C:

Status: 0x00000000 mit einer Maximum Size ungleich Null bedeutet aktives Journal. 0x80000005 o. ä. heißt: Journal deaktiviert, es gibt nichts zu extrahieren — siehe die fsutil-usn-Referenz für die Lifecycle-Befehle.

Nach der Extraktion

Sobald du die $J-Datei hast, legst du sie auf diese Seite ab oder schickst sie an dein Werkzeug der Wahl. Die geschnitzten Bytes sind genau das Eingabeformat, das Parser wie usnrs, PoorBillionaire/USN-Journal-Parser oder Eric Zimmermans MFTECmd erwarten.

Wenn du auch die $MFT greifst (gleiche $Extend-Nachbarschaft, MFT-Eintrag 0), kannst du vollständige Pfade statt nur Dateinamen auflösen — siehe die Pfadauflösung in usnrs und den $MFT-Eingang unseres Parsers.

Häufige Stolpersteine

  • Mit dem Explorer kopieren: Drag-and-Drop von $UsnJrnl kopiert stillschweigend den unbenannten Standard-Stream (leer) und nicht $J. Immer ein forensisches Tool nutzen.
  • Journal deaktiviert: Workgroup-Maschinen haben das Journal manchmal deaktiviert. fsutil usn queryjournal ist die billigste Prüfung.
  • $J beginnt mit sparsen Nullen: Das Journal ist ein Sparse-Stream — die ersten paar hundert MB können nur Nullen sein, bevor der erste echte Eintrag kommt. usnrs, unser Parser und die meisten anderen überspringen sie automatisch. Wer einen eigenen Parser schreibt, findet in Skip::find_first_record aus usnrs die kürzeste Referenzimplementierung.
  • Stream wrappt: Je nach Volume-Aktivität kann der Ringpuffer übergelaufen sein — ältere Einträge sind weg. Die kleinste USN, die du findest, sagt dir, wie weit die Historie reicht.