USN ジャーナルで timestomping とアンチフォレンジックを見抜く

MFT タイムスタンプを編集する攻撃者も、チェンジジャーナルからは隠れられません。$STANDARD_INFORMATION と $FILE_NAME の不一致、想定外の BasicInfoChange レコードがアンチフォレンジックな活動を露呈させる仕組みを解説します。

著者: 約 2 分で読了

技巧を気にするオペレータは証拠を削除するだけではありません。残してしまったものを偽装します。最もよくある手口が timestomping です。NTFS ファイルのタイムスタンプを書き換えて、無害に見せたり、捜査ウィンドウから外したりします。かつては確実に機能していました。現代のすべての Windows ホストで既定で有効な USN ジャーナルが入っていると、単一のフィルタと親パスの解決でそれを浮かび上がらせるほど特徴的なシグネチャを残します。

本記事では、timestomping がディスクに何をするか、ジャーナルがそれをどう露呈させるか、そして同じアーティファクトで無料でついでに捕捉できる他のアンチフォレンジック手段を順に見ていきます。

NTFS タイムスタンプの簡単な復習

すべての MFT エントリ は、二つの属性にタイムスタンプを保持します。

  • $STANDARD_INFORMATION (SI)。ユーザ空間ツールと大半の API が読み書きするタイムスタンプです。dir、エクスプローラ、Get-ChildItemos.statGetFileTime はすべて SI を返します。Microsoft は NTFS ファイルタイムリファレンス でレイアウトを文書化しています。
  • $FILE_NAME (FN)。NTFS が各 $FILE_NAME 属性 (ハードリンクされていればファイルは複数の名前を持ち得ます) について内部的に設定するタイムスタンプです。FN の値は変更がはるかに困難です。特定の操作でしか更新されず、カーネルはそれを書き換える綺麗な API を公開していません。

timestomping ツールは既定で SI を標的にします。レガシーな Metasploit timestomp.exe、SetMACE、そして並程度の技巧を持つオペレータが書いた多数のカスタムインプラントは、FileBasicInformation ペイロードを使った NtSetInformationFile 経由で $STANDARD_INFORMATION を書き換えます。現代のインプラント (Cobalt Strike の timestomp コマンドを含む) は MFT を直接操作することで FN も書き換えることができ、これはより込み入っていて追加の $LogFile の証拠を生成します。

いずれにせよ、MFT エントリを書く行為自体がジャーナルを点灯させます。

タイムスタンプ編集に対してジャーナルが記録するもの

SI のタイムスタンプが書かれると、NTFS はファイルの FileReferenceNumber に対して BasicInfoChange | Close レコードを発行します。そのレコードが診断のポイントです。

  • 正当な touch は、タイムスタンプ更新を引き起こした実際の書き込みからの DataExtendDataOverwrite と一緒に BasicInfoChange | Close を生成します。
  • timestomping は、同じ FileReferenceNumber 上で 書き込みが先行しない裸の BasicInfoChange | Close を生成します。

同じハンドルセッション内で DataOverwriteDataExtendFileCreate、リネームを伴わない BasicInfoChange | Close を見たとき、それはメタデータ操作を見ています。大多数は timestomping で、残りは属性の切り替え (+H+R、圧縮のオン/オフ) と EFS の状態変更です。

SI 対 FN の比較

最も信頼性の高い timestomping 検出は、各ファイルの SI タイムスタンプを FN タイムスタンプと比較するものです。このパターンは Mandiant の初期の Windows フォレンジック研究にまで遡り、Brian Carrier 著 File System Forensic Analysis でも扱われています。立ち止まるべき形状は次のとおりです。

  • SI が FN より前。 名前が存在する前にファイルが正当に変更されることはあり得ません。これは典型的な動かぬ証拠です。
  • SI が非現実的なマージンで FN の未来にある。 オペレータが見かけの年齢を、クリーンインストール時のシステムファイルに見えるように前方へ押し出したケースです。
  • SI と FN の両方が不自然なほど整っている — 切り捨てられた秒、M/A/C/B が同一、すべて既知の Windows インストール日と一致など。個別のペアがフラグされなくても、よく見る価値があります。

ジャーナルは比較を置き換えるのではなく補完します。MFT 比較は 何か がタイムスタンプを改変したことを教えます。ジャーナルは いつ SI 書き換えが発生したか を正確に教えます。これがレポートに記載するタイムスタンプです。両者を組み合わせれば、案件は自ずと書き上がります。

  1. MFT 比較が \Windows\System32\drivers\suspicious.sys で SI < FN をフラグ。
  2. ジャーナルにそのファイルの FileReferenceNumber に対する BasicInfoChange | Close2026-04-12 03:08:14Z に存在し、周囲に書き込みなし。
  3. そのタイムスタンプがオペレータが timestomp コマンドを実行した時刻です。Sysmon イベント 1 と相関させればプロセスも特定できます。

$LogFile とジャーナルは一致するはず

ジャーナルはファイル単位で書き込みを記録します。$LogFile は基礎となる MFT トランザクションをメタデータ書き込みレベルで記録します。timestomping は次を生成します。

  • ターゲットエントリの $STANDARD_INFORMATION 属性を変更する、$LogFile 内の 1 件の MFT 書き込みトランザクション。
  • ジャーナル内の 1 件の BasicInfoChange | Close

ジャーナルに対応する BasicInfoChange | Close がないのに $LogFile にあるファイルの MFT 更新トランザクションが残っているなら、オペレータは $UsnJrnl を消して新しいものを作ることでジャーナルレコードを削除した可能性があります。その操作は可能 (fsutil usn deletejournal /D /N C: の後に fsutil usn createjournal /m ... /a ... C:) ですが、それ自体が騒がしいです。

ジャーナルが捕捉する他のアンチフォレンジック手段

ジャーナルの無効化または抹消

fsutil usn deletejournal /D /N C: はジャーナルを完全に削除します。実行後:

  • ジャーナルファイルが空で再構築されます。呼び出し前のレコードは永久に失われます。
  • $UsnJrnl の MFT エントリが新たに書かれます。$LogFile がそれを記録します。
  • セキュリティログは SeRestorePrivilege または SeManageVolumePrivilege の Sensitive Privilege Use イベントを記録します — SACL が設定されていた場合 (通常は未設定)。

ジャーナルは以前の内容を教えてくれませんが、それを無効化する行為自体が強力なアンチフォレンジックのシグナルです。Microsoft は fsutil usn リファレンス で管理コマンドを文書化しています。

ジャーナルの存在を知っているオペレータは、出際に消す (騒がしい) か、選択的に証拠を残さないようにする (より難しく、ディスクに触れないことが求められる) のどちらかをしがちです。既知のインシデントウィンドウ周辺でジャーナルが疑わしく空になっているホストでは、それを検証すべき仮説として扱ってください。

代替データストリーム

ADS を使った隠蔽は私より古い手法で、ジャーナルはそれをきれいに記録します。StreamChange reason ビットは、ファイル上で代替データストリームが追加、リネーム、削除されたときに発火します。StreamChange でフィルタすれば、ボリューム上のすべての ADS 作成/変更イベントが浮かび上がります。

予想される偽陽性: ブラウザダウンロードによる正当な Zone.Identifier ストリーム (ホストファイルの FileCreate とペア)、メールクライアントによる Mark-of-the-Web ストリーム、SmartScreen の状態。それ以外で署名済みシステムバイナリ、\Windows\System32\ 内のファイル、または通常のブラウザダウンロードフロー外のユーザプロファイルバイナリに StreamChange レコードが発生したものは、調査する価値があります。

ハードリンクの細工

HardLinkChange は、ハードリンクが追加または削除されたときに発火します。オペレータはハードリンクを使って、悪意のあるバイナリを 2 つの親からアクセス可能にし、AppLocker のルールやパスベースの EDR 制御をかわすことがあります。FileReferenceNumber でピボットして、特定の inode に対するすべての親を確認します。

リパースポイントの悪用

ReparsePointChange は、リパースポイント (ジャンクション、シンボリックリンク、マウントポイント) が追加、変更、削除されたときに発火します。\$Recycle.Bin\\Users\Default\\ProgramData\ など、通常存在しない場所に作成されるリパースポイントを探してください。ゴミ箱パーサ$Recycle.Bin 側の補完的なアーティファクトです。

セキュリティとオブジェクト ID の変更

SecurityChange は ACL とオーナーの書き換えを露呈します。ObjectIdChange はより稀なオブジェクト ID 操作を露呈します。いずれも健全なホストでは静かです。ユーザプロファイルバイナリやシステムファイルでのバーストは追跡する価値があります。

実践的なスキャン手順

パース済みのジャーナルを使った最速の timestomping スクリーニング:

  1. reason マスクが 正確に BasicInfoChange | Close のレコードにフィルタします。ほとんどのパーサのデフォルトは「そのビットを含む」ですが、このスキャンには厳密一致が必要です。
  2. 各候補について、同じ FileReferenceNumber に対する直前 5 分間のレコードを確認します。DataOverwriteDataExtendFileCreate、リネームがなければ、そのレコードをフラグします。
  3. フラグされたレコードについて、MFT の SI 対 FN の差分を計算します。絶対差でソートします。

リストの先頭が timestomping です。残りのフラグ済みエントリは通常 attrib +Hattrib +R の呼び出し、または read-only を切り替えるスクリプトです。文脈依存で、典型的な IR 調査ではほとんど興味を引きませんが、完全性のためにランクされた出力に残しておく価値はあります。

本ページのパーサは厳密マスクフィルタリングを公開しています。ステップ 3 には、パース済みの $MFT を傍らに開いておく必要があります。多くのアナリストは Eric Zimmerman の MFTECmd で CSV エクスポートし、スプレッドシートでピボットしています。

この方法で捕捉できないもの

ジャーナルを完全にバイパスするアンチフォレンジック手段の短いリスト:

  • 外部メディアからブートしてディスクを書き換える。 ライブ OS に触れず、ジャーナルに書き込みもしません。
  • SI 更新なしで同じオフセットでコンテンツサイズを保持するユーザランドファイル書き換え。 DataOverwrite レコードを生成しますが、以前のコンテンツは失われます。ジャーナルは書き込みを見ますが、以前そこにあったものは見ません。
  • 何かをする 前に ジャーナルを無効化する。 ジャーナルは稼働している間にしか何が起きたかを記録できません。

これらについては、$LogFile、ボリュームシャドウコピー、ホスト外の遠隔測定、あるいはインシデントに十分近い時点で取得し関連状態をまだ含む RAM ダンプ が必要です。

参考資料

  • Microsoft Learn — File TimesNtSetInformationFile API リファレンス。後者は、あらゆる timestomping ツールが最終的に呼び出すシステムコールです。
  • Eric Zimmerman の MFTECmd — SI と FN のタイムスタンプをフラットな CSV にする決定版のオフラインパーサです。
  • Joachim Metz の libfsntfs のドキュメント — ジャーナル単独では不十分な場合の二番目の証人である $LogFile の内部構造に関する、最も網羅的な公開資料です。
  • Brian Carrier 著 File System Forensic Analysis — NTFS メタデータ属性に関する章は、異なる操作下で SI と FN がどう振る舞うかについての決定版リファレンスです。