ディスクイメージ (またはライブシステム) から $UsnJrnl:$J を抽出する方法

NTFS の USN ジャーナルを、フォレンジックイメージ、マウント済みボリューム、稼働中の Windows ホストから取り出す実践ガイドです。FTK Imager、X-Ways、The Sleuth Kit、fsutil、PowerShell を使います。

著者: 約 2 分で読了

USN ジャーナルを扱う作業で最も難しいのは、通常パースそのものではありません。まずファイルを手に入れることです。$UsnJrnl:$J は通常のファイルではなく代替データストリームなので、エクスプローラには表示されず、単純な copy でも生き残らず、robocopy は黙ってウソをついてあなたがそれを取れたかのように振る舞います。これは、典型的に遭遇する 3 つの場所 — フォレンジックイメージ、マウント済みボリューム、稼働中のマシン — に分けてバイトを取り出す実地ガイドです。

探しているもの

ジャーナルは次の場所にあります:

\$Extend\$UsnJrnl:$J

$Extend は隠し NTFS メタデータディレクトリで、$J$UsnJrnl メタデータファイル上の二つの代替ストリームのうちの一つです。もう一つのストリームは $Max で、ジャーナルの設定済み最大サイズと割り当てデルタしか保持しません。レコードはありません。誤って $Max をカービングすると、数バイトの無用な設定が得られるだけです。常に $J を選んでください。

Microsoft は Change Journals リファレンスUSN_RECORD_V2 構造体リファレンス でレイアウトを文書化しています。典型的な $J は、インストール時に fsutil usn がどう設定されていたかにより 30 MB から数 GB です。Windows クライアントの既定は約 32 MB、サーバは 1 GB 以上にされていることが多いです。

$J を取り出しながら、同じボリュームから $MFT も取り出してください。それがなければ、パーサはリーフのファイル名しか表示できません。各レコードは親 MFT エントリ番号にバインドされており、パスではありません。両ファイルが揃えば、フルパスが無料で得られます。

フォレンジックディスクイメージ (E01、dd、AFF4) から

DFIR で最もよくあるケースです。すでにライセンスを持っているツールを選んでください。

FTK Imager (無料、GUI)

  1. File → Add Evidence Item でイメージを開きます。
  2. [root]/$Extend/$UsnJrnl まで掘ります。
  3. 画面には $J$Max が兄弟行として表示されます。$J を右クリックし Export Files を選びます。

「兄弟行」という細部は新人がよく間違える部分です。親ファイルを右クリックして既定のストリーム (空) をエクスポートしてしまいがちです。$J の行を具体的に選んでください。

X-Ways Forensics (商用)

Root directory → $Extend → $UsnJrnl を展開します。配下に $J ストリームが現れます。Recover/Copy で書き出します。同じ経路、同じ落とし穴です。

The Sleuth Kit (無料、CLI、クロスプラットフォーム)

Mac/Linux のアナリストの大半が手を伸ばすツールです。TSK の icat が標準ツールです:

# $UsnJrnl の MFT エントリを見つける
fls -r -p image.dd | grep '\$UsnJrnl'

# 例として inode 81 が報告され、$J ストリームが属性 128-2 だとします:
icat image.dd 81-128-2 > UsnJrnl-J.bin

<inode>-<type>-<id> の三つ組は、TSK が代替ストリームをアドレッシングする方法です。属性名が :$J で終わるものを選んでください。fls の長文出力に表示されます。

Velociraptor と KAPE

幅広いトリアージ収集には、Velociraptor の Windows.NTFS.MFT アーティファクトパックと Kroll の KAPE が自動的にジャーナルを取得します。KAPE はターゲットファイル (!ALL または USNJournal) を使用します。Velociraptor は parse_ntfs プラグインを使用します。どちらも同じスイープで $MFT$LogFile も取得します — これがまさに欲しいものです。

マウント済みボリュームから

イメージが Linux の ntfs-3g または Windows の Arsenal Image Mounter を介して読み取り専用でマウントされている場合、メタデータパスは通常のファイルとして表示されますが、ほとんどのツールは代替ストリームを透過的に読むことを拒否します。

ntfs-3g を使った Linux では、ストリームを直接読めます:

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

streams_interface のマウントオプションによっては、:$J が別パスコンポーネントとして現れることもあります。まず ls -la /mnt/image/\$Extend/ を確認してください。

稼働中の Windows ホストから

管理者権限と NTFS を理解するリーダが必要です。Windows は管理者プロセスからでもメタデータファイルへの通常のアクセスをブロックするためです。

RawCopy

Eric Zimmerman の ツール一式 には RawCopy.exe (および RawCopy64.exe) が含まれます。これは標準のファイル API を回避します:

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

KAPE はその USNJournal ターゲットを実行するときに、内部でこれを使用しています。

PowerForensics (純 PowerShell)

バイナリを置けないなら、PowerForensics が純 PowerShell で生の NTFS 構造を読みます:

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

組み込みの fsutil (検証用、抽出用ではない)

fsutil usn はジャーナルのサポート対象の制御サーフェスですが、抽出ツールでは ありません。レコードの読み取り、クエリ、削除はできますが、フルの $J ブロブをストリーミングすることはできません。役に立つのは、抽出を試みる前にジャーナルが有効でサイズが設定されていることを検証することです:

fsutil usn queryjournal C:

Status: 0x00000000Maximum Size がゼロでなければ、ジャーナルはアクティブです。0x80000005 は無効を意味し、fsutil usn createjournal で作成するまで抽出するものはありません。ライフサイクルコマンドとその権限要件は fsutil usn リファレンス を参照してください。

抽出後

$J ファイルが手に入ったら、本ページ上部のパーサにドロップするか、信頼しているオフラインツールに与えてください: usnrsPoorBillionaire/USN-Journal-Parser、または Eric Zimmerman の MFTECmd (名前に反して $J もパースします) などです。

同時に $MFT (エントリ 0、同じ $Extend に隣接する場所) を取得してください。両方のファイルが供給されれば、上記のいずれのパーサも親参照チェーンを辿ってすべてのジャーナルレコードのフルパスを解決します。$MFT がなければ、ファイル名を単独で読むことになります。

NTFS メタデータを取得するついでに、可能なら $LogFile も取得してください。小さく、ローテーションが速く、ジャーナル単独では十分過去まで届かないインシデントでは $LogFile が backstop になります。USN ジャーナル vs MFT vs LogFile の記事で、それぞれがいつ役に立つかを解説しています。

よくある落とし穴

エクスプローラのコピー。 $UsnJrnl のドラッグ&ドロップは既定の無名ストリームをコピーし、これは空です。警告も出ません。上記のツールを使ってください。

ジャーナルが無効。 ワークグループのマシンや過度に Debloat されたビルドでは、ジャーナルがオフになっていることがあります。fsutil usn queryjournal が最も安価な事前チェックです。

先頭のスパースなゼロ。 ジャーナルはスパースストリームです。新たにカービングした $J の最初の数百メガバイトが、最初の本物のレコードまで全部ゼロというのもあり得ます。usnrs、本ページのパーサ、その他の多くは自動的にスキップします。パーサをゼロから書くなら、最初の非ゼロワードをスキャンし、妥当な RecordLength 値を探してください。

リングバッファのラップ。 活動量によってはジャーナルがラップしていて、古いエントリが消えていることがあります。ファイル中の最小 USN が、そのボリュームの履歴が実際にどこまで遡れるかを教えます。それをハードな下限として扱ってください。

誤って $Max をつかむ。 同じ親ファイルですが、レコードがありません。カービングで小さなファイル (数バイトから数 KB) ができたら、ほぼ確実に間違ったストリームをつかんでいます。

参考資料

  • Microsoft Learn — API サーフェスとライフサイクルについては Change Journals
  • Eric Zimmerman のツールドキュメント — RawCopy とその他一式 はライブホスト取得をエンドツーエンドでカバーしています。
  • The Sleuth Kit の flsicatman ページ — イメージレベル抽出の決定版 CLI リファレンスです。
  • KAPE ドキュメント — Kroll は USNJournal!BasicCollection を含む ターゲットファイル を公開しています。ターゲット XML を読むのが、徹底したトリアージ取得がどんなものかを学ぶ最速の方法です。