← ブログに戻る

$UsnJrnl と $MFT を組み合わせて真のタイムラインを作る

· 読了 2 分

$MFT はファイルシステムが今どう見えるかを教えてくれます。この状態を生んだ操作の順序は教えてくれません。そのために NTFS は 2 つ目のアーティファクト、Update Sequence Number Journal($UsnJrnl)を保持します。両者を組み合わせると、静的なスナップショットが動画になります。ジャーナル固有の深掘りは 専用の USN パーササイト を読んでください。この投稿は、なぜ MFT と一緒に読むのか、そして組み合わせがどちらか一方では示せないものを何を示すかについてです。

$UsnJrnl が記録するもの

ファイルが作成、変更、リネーム、削除されるたびに、NTFS はイベントを記述する固定サイズのレコードをジャーナルに追加します。各 USN レコードのフィールド。

  • USN: 単調増加する 64 ビットカウンタ。ジャーナル内の位置。
  • 変更されたファイルの MFT レコード番号
  • 変更時のそのレコードの シーケンス番号
  • 親ディレクトリの MFT レコード番号(とシーケンス)。
  • Reason マスク: このエントリをトリガーした操作のビット単位の OR。完全なリストは Microsoft の USN reason コード にあります。最もよく読むもの。
    • FILE_CREATE (0x00000100)
    • FILE_DELETE (0x00000200)
    • DATA_OVERWRITE (0x00000001)
    • DATA_EXTEND (0x00000002)
    • DATA_TRUNCATION (0x00000004)
    • RENAME_OLD_NAME (0x00001000)
    • RENAME_NEW_NAME (0x00002000)
    • OBJECT_ID_CHANGE (0x00080000)
    • REPARSE_POINT_CHANGE (0x00100000)
    • STREAM_CHANGE (0x00200000)
    • CLOSE (0x80000000)
  • Source info: 特殊なソース(データ管理、インデックス化、レプリケーション)を示すビットマスク。通常はゼロ。
  • Security ID
  • 変更時の ファイル名
  • 変更の タイムスタンプ

CLOSE は知っておくべきビットです。ほとんどの USN エントリはこれをセットしており、イベントが記録されたときにファイルハンドルが閉じられたことを示します。CLOSE のないエントリは、まだ開いているハンドルで、変更がフラッシュされた状態です。同じレコードに対して、最終的な CLOSE を持つ後続のエントリが見えることがあります。このパターンはランサムウェア分析で重要です。.locked ファイルの FILE_CREATE | DATA_EXTEND | CLOSE とオリジナルの FILE_DELETE | CLOSE のペアが、1 つのジャーナル系列での暗号化パターンです。

どこに存在するか

$UsnJrnl は通常の NTFS ファイルで、データは名前付きデータストリーム $J にあります。それの MFT レコードは $Extend ディレクトリ配下にあります(MFT レコード 11 が $Extend)。ボリュームルートからのパスは \$Extend\$UsnJrnl:$J です。ジャーナル構成(最大サイズ、アロケーションデルタ、最初の有効エントリの USN)を保持する小さな $Max ストリームもあります。

$MFT を取得するのと同じツールで取得します。

  • KAPE の MFT ターゲットは自動的に $UsnJrnl:$J を含みます。
  • FTK Imager は [NTFS volume]/$Extend/$UsnJrnl:$J 経由でエクスポートできます。ファイルはスパースです。「サイズ」が巨大で実際の内容がずっと小さい場合に驚かないでください。
  • ディスクイメージ上の Sleuth Kit。icat -o <partition_offset> image.dd <inode>。ここで inode は $UsnJrnl の MFT レコード番号です。fls -p で inode を見つけます。
  • mft_dump と MFTECmd は両方とも $J 解析モードを持っています。

どう $MFT を補完するか

MFT は現在の状態を示します。USN ジャーナルはそれを生んだ動詞を示します。両者を組み合わせると、どちらか単独では示せないパターンが浮かび上がります。

  • ディスク上にもう存在しないが $UsnJrnl に現れるファイル。 スナップショット間で作成され削除されましたが、ジャーナルがレコードを保持しています。MFT スロットはその後再利用されている可能性がありますが、USN エントリは依然としてファイルを命名し、元のレコード/シーケンスを指しています。
  • ランサムウェア実行中のリネームの正確な順序。 OPENDATA_OVERWRITERENAME_OLD_NAMERENAME_NEW_NAMECLOSE。スナップショット間の MFT 差分はファイルが移動したことを教えてくれます。ジャーナルは移動した順序を教えてくれます。
  • 「変更された」ファイルが実際に書き換えられたのか触れられただけなのか。 DATA_OVERWRITE は内容が変更されたことを意味します。メタデータのみの変更(ACL 更新、属性セット)は異なる reason フラグを示し、データ関連のフラグはありません。
  • どのプロセスグループがどのファイルを書いたか。 ジャーナルはプロセスを直接記録しませんが、Sysmon Event ID 11(ファイル作成)と Event ID 23(ファイル削除)のタイムスタンプと組み合わせると、ジャーナルエントリを特定のプロセスにほぼ常に帰属できます。

マージワークフロー

私が MFT と USN データをタイムライニングのためにマージする方法。

  1. $MFT をフラットなレコードごとに 1 行の CSV(MFTECmd、mft_dump -o csv、またはブラウザパーサのエクスポート)に解析します。
  2. $UsnJrnl:$J をフラットなイベントごとに 1 行の CSV に解析します。
  3. それぞれに source 列(MFTUSN)を追加します。
  4. 連結してタイムスタンプでソートします。
  5. ケースに一致するレコード(特定のレコード番号、特定のファイル名、特定の親ディレクトリ)に絞り込みます。
  6. タイムラインを散文として読みます。各レコード番号について、イベントを順に列挙します。

単一ファイルの出力は次のようになります。

2026-05-15T10:23:01.123Z USN  FILE_CREATE | DATA_EXTEND | CLOSE  rec=12345 seq=3 parent=99 name=secret.docx
2026-05-15T10:23:01.123Z MFT  IN_USE=1 SI_created=10:23:01.123Z FN_created=10:23:01.123Z
2026-05-15T10:24:18.456Z USN  DATA_OVERWRITE | CLOSE             rec=12345 seq=3 name=secret.docx
2026-05-15T10:24:18.456Z MFT  SI_modified=10:24:18.456Z
2026-05-16T08:11:02.000Z USN  RENAME_OLD_NAME                    rec=12345 seq=3 name=secret.docx
2026-05-16T08:11:02.000Z USN  RENAME_NEW_NAME | CLOSE            rec=12345 seq=3 name=secret.docx.locked
2026-05-16T08:11:02.001Z USN  FILE_DELETE | CLOSE                rec=12345 seq=3 name=secret.docx.locked

そのシーケンスはファイルの全人生です。作成、変更、リネーム(.locked 拡張子を追加するため)、削除。5 つの操作、1 つのファイル、24 時間未満。

限界と落とし穴

ジャーナルはローテーションします。 ほとんどのインストールでデフォルトサイズは 32 MB、Server SKU と最近の Windows 11 ビルドではより大きいことがあります。忙しいホストではこれは数日に収まります。新しいエントリが入ってくると古いイベントは末尾から落ちます。インシデントの 1 週間後に到着するとギャップが予想されます。

ジャーナルは削除できます。 fsutil usn deletejournal /D C: で完全に削除します。新しいものが新鮮なカウンタで開始します。再作成はフットプリントを残します(NTFS アンチフォレンジック を参照)が、履歴エントリは失われます。

ラップアラウンドは通常のローテーションのように見えます。 キャプチャされた $J で見える最初の USN は、その瞬間にジャーナルがたまたま開始していた場所です。「先週ここに何があったか」の履歴はありません。より長いウィンドウが欲しい場合、VSS スナップショット で古い $UsnJrnl のコピーを探してください。各スナップショットはスナップショット時の独自のジャーナルコピーを持ちます。

タイムスタンプは MFT タイムスタンプから数ミリ秒ずれます。 整列に過度に依存しないでください。秒単位でソートし、USN reason コードをタイブレーカーとして使用します。

レコード番号の再利用。 USN エントリは rec=12345 seq=3 を参照します。現在の MFT がそのレコードをシーケンス 4 で示している場合、スロットはその後再利用されています。USN エントリは依然として元のファイルを命名しており、現在の MFT は後継を示します。常にシーケンス番号をクロスチェックしてください。

ドライバのミニフィルタはエントリを抑制できます。 一部の EDR とバックアップソフトウェアは、ノイズを減らすために特定の USN reason を抑制します。ジャーナルはこれらを記録しません。USN データが、頻繁であるべき操作のカテゴリ(たとえばファイルアクセス)について疎に見える場合、インストールされているミニフィルタを確認してください。

$LogFile について簡単に

$LogFile はトランザクションレベルの操作を記録します。この属性をアロケート、あの属性を解放、このインデックスエントリを更新。USN より粒度は細かく、レベルは低いです。クラッシュやメタデータ集中型イベントの直前直後の秒に有用です。MFTECmd が解析します。他に一般的なものは解析しません。改ざんされた USN ジャーナルがある場合、$LogFile が実際に何が起こったかの唯一残存する記録であることがあります。

耐えうるワークフロー

  1. 常に $MFT$UsnJrnl:$J$LogFile、および 3 つすべての VSS スナップショットコピーを一緒に取得します。
  2. すべて直ちにハッシュ化(SHA-256)します。
  3. 3 つすべてを解析します。
  4. MFT と USN を単一のタイムラインにマージします。関心のあるイベントの周囲の秒について、$LogFile をその上にレイヤーします。
  5. SysmonSecurity イベントログPrefetchAmcache とクロスリファレンスします。
  6. 結論したものと同様に、除外したものを文書化します。

MFT + USN のペアは、NTFS が提供する完全なファイルシステム活動ログに最も近いものです。そう扱ってください。

参考資料

  • Microsoft, USN Record Structures。レコードフォーマットと reason コードの権威あるリファレンス。
  • Eric Zimmerman, MFTECmd USN parsing modes。部分的またはラップしたジャーナルへの耐性を含む、最も完全なパーサ。
  • TZWorks jp および usnparser.com ブラウザツール。MFTECmd が利用できない場合の代替パーサ。

外部リソース