← ブログに戻る

レビューに耐える $MFT ベースのタイムライン構築

· 読了 2 分

$MFT から Windows のタイムラインを初めて構築したとき、私はレコードごとに 8 行を出力し、タイムスタンプでソートして Excel で開き、現実を再構築した気になりました。そうではありませんでした。NTFS メタデータ変更の整列されたログを得ただけです。それは有用なものです。それ自体は調査ではありません。

これは、最初のレポートを出す前に MFT タイムライニングについて誰かに教えてほしかった内容です。

MFT タイムラインとは実際に何か

すべてのアクティブおよび削除済み MFT レコードは、確実に抽出可能な 8 個のタイムスタンプを保持しています。$STANDARD_INFORMATION(SI)に 4 個、$FILE_NAME(FN)に 4 個です。両方の属性で、created、modified、accessed、MFT-modified の 4 つです。テーブルを走査し、null でないタイムスタンプごとに 1 行を出力し、時刻でソートすれば、NTFS が特定のレコードの特定のバイトをいつ書き込んだかのタイムラインが得られます。これが下限です。

上限はスーパータイムラインです。MFT を USN journal$LogFile、Prefetch、SysmonShimcacheAmcacheレジストリハイブブラウザ履歴SRUM と融合させたものです。MFT が背骨となるのは、それが最も密で、攻撃者が完全に偽造するのが最も困難だからです。他のすべては MFT に対して整列させます。

私が実際に使うレイアウト

mactime を最終的な出力形式として考えないでください。中間形式として使います。法廷で持ちこたえる形は、出処を防御できるイベントごとに 1 行というものです。

timestamp_utc | source | attribute | mft_record | seq | path | event
2026-05-15T10:23:01.123Z | MFT | SI | 12345 | 3 | /Users/alice/notes.txt | created
2026-05-15T10:23:01.123Z | MFT | FN | 12345 | 3 | /Users/alice/notes.txt | name_created
2026-05-15T10:24:18.456Z | MFT | SI | 12345 | 3 | /Users/alice/notes.txt | modified
2026-05-15T10:24:18.501Z | USN | -   | 12345 | 3 | /Users/alice/notes.txt | DATA_OVERWRITE | CLOSE

source とレコード/シーケンスのペアは、アナリストが省略しがちで、後で省略を後悔する列です。シーケンス番号があってこそ、同じレコード番号を共有する 2 つのイベントが同じ実体のファイルを指しているのか、それともスロットが再利用された削除済みの先代を指しているのかが分かります。シーケンス番号がないと、タイムラインはそれらを暗黙のうちに混同してしまいます。

MFTECmd の CSV 出力は、市販のなかでこれに最も近いレイアウトです。source=MFT を追加してタイムスタンプごとに 1 行を出力する薄いスクリプトに通せば、作業用のコーパスができあがります。

どれだけ嘘をつくかの順に並べたタイムスタンプ

SI は Windows がファイルに対して行うほぼすべての操作で動きます。読み取りは、NTFS がそう判断すれば accessed を更新します(Windows 7 以降は性能のため accessed をデフォルトで更新しません。fsutil behavior set disablelastaccess 0 で有効化しない限り)。書き込みは modifiedMFT-modified を更新します。リネームは MFT-modified を更新します。SetFileTime を使った timestomping は、攻撃者が指定した 4 つのいずれかを更新します。

FN はリネーム、ハードリンク作成、ファイルの初回作成時に更新されます。それ以降、FN はほとんど動きません。Windows による FN 更新の粒度も粗く、多くのファイルは作成時に FN が設定されてそれ以降一度も触られていないため、正当に .0000000 で終わります。

実務的には次のとおりです。

  • FN created は、MFT 単独で得られる「このファイルがこのディレクトリに最初に現れた」シグナルとして最も信頼できます。
  • SI created は偽造が最も簡単です。ヒントとして扱い、事実として扱ってはいけません。
  • SI modified は主力です。対応する USN の DATA_OVERWRITE と組み合わせれば、ファイルのバイトがその瞬間に実際に変化したことが分かります。
  • SI accessed は Windows 7 以降ではデフォルトで無効です。変化しているのが見える場合、管理者が再有効化したか、ボリュームが Server SKU 上にあるか、何かがボリュームをマウントしてファイルを走査している(バックアップソフト、AV スキャン、EDR の内省など)かのいずれかです。

サブ秒の粒度が決め手です。NTFS はタイムスタンプを 100 ナノ秒のティックで保持しています。ネイティブな Windows 操作は下位桁にノイズを残します。SetMACE や有名な timestomp.exe のような timestomping ツールは秒単位に丸めます。.0000000 のサフィックスがきちんと揃った列はフィンガープリントです。

USN ジャーナルとのマージ

MFT は現在と、凍結されたメタデータの履歴を示します。USN ジャーナルは動詞を示します。両者を組み合わせると、タイムラインの 1 行が文になります。

私のマージ方法はこうです。$UsnJrnl:$J を別に解析し、レコードごとに 1 行を source=USN で出力し、結合したストリームをタイムスタンプでソートします。USN の reason コード(FILE_CREATEDATA_OVERWRITERENAME_OLD_NAMERENAME_NEW_NAMEFILE_DELETECLOSE)が操作を、MFT が結果状態を提供します。同じ USN で RENAME_OLD_NAME の直後に RENAME_NEW_NAME が続くと、リネームが見えてきます。ジャーナルがなければ、2 つのスナップショット間の MFT 差分はファイルが移動したことは教えてくれますが、順序までは教えてくれません。

落とし穴がひとつ。同じイベントについて USN のタイムスタンプと MFT SI のタイムスタンプはミリ秒単位でずれます。整列に過度に依存しないでください。秒単位でソートし、USN reason コードをタイブレーカーとして使います。

MFT タイムラインを台無しにするもの

順序のずれた取得。 MFT と USN を稼働中のシステムで 10 分間隔で収集すると、ジャーナルはその間も動き続けています。同じ時点から組にして取得すべきです。理想的には、自分でトリガーした VSS スナップショットから取得します。

fixup 配列を忘れる。 使う価値のあるパーサはすべてこれを扱いますが、自前で実装している場合(学習目的でない限りやめてください)、生の 1,024 バイトのチャンクを読むと各レコードのオフセット 510 と 1022 にゴミが入ります。最初に fixup を適用してください。

シーケンス境界を越えてレコード番号を混同する。 レコード 12345 シーケンス 3 はレコード 12345 シーケンス 5 と同じファイルではありません。スロットが再利用されたのです。タイムラインがレコード番号だけでグループ化されていると、削除済みファイルとそのスロットを引き継いだファイルを混同します。

システムバイナリの SI を信用する。 Windows Update はパッチを当てたファイルの SI を更新します。C:\Windows\System32\svchost.exe の SI 変更は、ほぼ常に侵入ではなく CBS のインストールです。主張する前に setupapi.dev.logCBS.log と相互参照してください。

タイムラインを結論として扱う。 タイムラインは分析への入力です。各イベントがホスト、ユーザー、ケースの文脈で何を意味するかは、依然として知る必要があります。

耐久性のあるワークフロー

  1. $MFT$UsnJrnl:$J$LogFile、および入手可能な VSS スナップショットからの同じファイルを取得します。すべて直ちにハッシュ化(SHA-256)します。
  2. MFTECmd または mft_dump と USN パーサで MFT と USN を解析します。パーサが警告なしに実行されたことを確認します。
  3. 正規化された行を出力します。MFT のタイムスタンプごとに 1 行、USN のレコードごとに 1 行、それぞれ明示的に sourcemft_recordseqpath を持たせます。
  4. タイムスタンプで単一のストリームにソートします。まだ重複排除しないでください。ほぼ重複するエントリにはシグナルがあります。
  5. 関心のある期間に絞り込みます。疑わしいイベントの前後 2 時間のウィンドウを取り出します。
  6. 残りをレイヤーで重ねます。PrefetchAmcacheSysmon 1/11/15、LNKジャンプリスト のアーティファクト、ごみ箱$I レコード、ネットワークとプロセスリソース使用について SRUM
  7. 不可能な順序を探します。FN created の前の SI created。MFT に対応する SI modified の変化がない DATA_OVERWRITE USN reason。同じシーケンスの同じレコード番号で FILE_CREATE が 2 回(パーサのバグ)。

最後のステップが MFT タイムラインの真価を発揮するところです。不可能性を露わにします。あらゆる不可能性はパーサのバグか攻撃者のアーティファクトのどちらかであり、どちらも追跡する価値があります。

MFT が教えてくれないこと

どのプロセスがファイルに触れたかは教えてくれません。どのユーザーかも教えてくれません。削除されて部分的に上書きされた、数百バイトを超えるファイルの中身も教えてくれません。それらには周辺のアーティファクトが必要です。コマンドライン監査付きの 4688(または Sysmon 1)、Security ログのログオン ID チェーン、運が良ければプロセスがまだ常駐していた RAM ダンプ などです。

MFT は背骨です。他のアーティファクトは筋肉です。どちらか片方では歩けません。

参考資料

  • Eric Zimmerman, MFTECmd。標準的な CSV レイアウトと、ほとんどの IR チームが標準化しているパーサです。
  • SANS, Windows Forensic Analysis Poster。MFT イベントを広範なタイムラインに正しく組み込んでいます。
  • Harlan Carvey, Investigating Windows Systems。タイムライン構築の章は依然として実務的な参考書です。

外部リソース