マルウェア感染などのインシデントにおいて、特定のプログラムの実行有無および実行日時を確認したいことがあります。
[確認したい状況の例]- マルウェアに感染した日時を特定したい(マルウェアが実行された日を知りたい)
- 不審メールに添付されていたマルウェアの実行有無を確認したい(利用者の記憶が曖昧なため調査したい)
Windowsでは、プログラム実行の痕跡がさまざまな形で残りますが、今回はお手軽に調べることができる「Prefetch」(プリフェッチ)の調査方法を紹介します。
Prefetchの概要
Prefetchは、利用頻度が高いアプリケーションの起動を高速化する仕組みで、WindowsXPから導入されました。
[主な特徴]- プログラムが起動された10秒後に、C:\Windows\Prefetchフォルダに、ファイル名が「プログラム名-フルパスのハッシュ値.pf」のファイルが作成される。
- ハッシュ値は、プログラムのフルパスから計算される。「プログラム名」部分が同一でハッシュ値が異なるPFファイルは、異なるフォルダから実行されたと判断できる
- PFファイルには、プログラムのフルパス、実行日時、実行回数、プログラムが起動時に読み込んだファイル名(DLLファイルなど)、ボリューム関連情報が記録される。
- コマンドラインやオートラン機能(autorun.inf)などにより実行したプログラムもPFファイルが作成される。
- PFファイルは最大で128個程度作成される(参考文献では最大128個との記載がありますが、私の環境では129個まで作成されることを確認しています)
- Windows7以降で、SSDを搭載しているとPrefetchが無効化される場合がある(私のDynabook R632 2012年モデルでは無効化されていません)
(注記)条件は不明ですが、PFファイルが作成されない場合もあります。 そのため,PFファイルが存在していないことで、「過去に実行されたことはない」と判断することはできません。 (Prefetchに限らず、フォレンジック調査では「存在していなかったこと」を証明することは難しいです)
参考文献
Forensics Wiki - Prefetch(英語)
http://www.forensicswiki.org/wiki/Prefetch
Forensics Wiki - Windows Prefetch File Format(英語)
http://www.forensicswiki.org/wiki/Windows_Prefetch_File_Format
調査方法
エクスプローラーによるお手軽調査方法
エクスプローラーで、Prefetchフォルダを確認してみましょう。なお,このフォルダにアクセスするには管理者権限が必要です。 PFファイルの存在から、プログラム実行の痕跡を確認できます。 また、PFファイルの作成日時・更新日時から、実行日時を推測することができます。
(注記)PFファイルのタイムスタンプは、プログラム実行の10秒後に更新されることにご注意ください
「WinPrefetchView」による調査方法
NirSoft「WinPrefetchView」は、PFファイルの解析結果を表示してくれるフリーソフトです。
起動には管理者権限が必要です。起動すると、C:\Windows\Prefetchフォルダに格納されているPFファイルの解析結果が表示されます。
任意のフォルダに格納したPFファイルを解析したい場合は、メニューから「Options」-「Advanced Options」をクリックすると、フォルダ指定ダイアログが表示されます。
[説明]- 表示されるタイムスタンプは、すべてローカルタイム(日本時間)
(設定を変更すればUTCでの表示も可能) - 「Last Run Time」は、PFファイルに記録されている最終実行日時
- 「Run Counter」は、プログラム実行回数
- 「Created Time」、「Modified Time」は、PFファイルのタイムスタンプ
(PFファイルのコピーなどの操作により、タイムスタンプが更新されるので注意)
バイナリエディタによる調査方法
参考文献のPFファイルのフォーマットを読むと、PFファイルには、ボリュームシリアルも記録されることが分かります。
ボリュームシリアルとは、ファイルシステムをフォーマットした時刻情報をもとに生成されるランダムな値のことです。 現在接続されているディスクなどのボリュームシリアルは、コマンドプロンプトからdirコマンドを実行することで簡単に調べることができます。
E:\>dir ドライブ E のボリューム ラベルは LABUSB です ボリュームシリアル番号は 523E-8109 です (表示内容は省略) E:\>
調査対象機器のボリュームシリアルが同じ値となる可能性は低いため、例えば起動されたプログラムが格納されていたUSBメモリの特定などに役立ちます。
残念なことに、WinPrefetchViewでは、ボリュームシリアルを表示することができません。
しかし、バイナリエディタを使って手動でPFファイルを解析すれば、ボリュームシリアルを特定することが可能ですので、挑戦してみましょう。
注意事項
今回は、USBメモリにFTK Imager Liteを格納し、WindowsXP SP3に接続して実行したPFファイルを解析してみます。
それでは、適当なバイナリエディタでPFファイルを開いてみましょう。
ファイルの先頭(Offset 0x00)のデータが、「0x11」(10進数で17)となっています。 これは、PFファイルのバージョン情報で、WindowsXPのPFファイルであることを示しています。 もしも、0x11以外の値だった場合、他のOSで作成されたPFファイルのため、USBメモリに関する情報は含まれない可能性が高いため、ご注意ください。
次に、ファイルの先頭から0x6cバイトの位置(Offset 0x6cと表現します)に記録されている4バイトの値を確認します。 Bzエディタの場合、上部にある検索ボックスに「> 6c」と入力してエンターキーを押すと、指定したアドレスにカーソルがジャンプします。
この例では、Offset 0x6cから「B8 33 00 00」となっています。 リトルエンディアン(アドレスが大きいほうから、小さいほうに記録する形式)で記録されているため、右から左にバイトずつ読み取り「0x000033b8」と解釈します。
読み取った「0x33b8」に「0x10」を加算したアドレス「0x33c8」が、ボリュームシリアルへのオフセットです。 それでは、Offset 0x33c8の値を確認してみましょう。「09 81 3e 52」となっています。 これもリトルエンディアンで記録されていますので、右から左に読み取り「52 3e 81 09」と解釈します。
コマンドプロンプトで確認したボリュームシリアルと一致しました。
また、プログラムのフルパスも記録されていますので、プログラム名で検索してみましょう。 Bzで検索する場合は、メニュー「表示」-「文字コード」を「Unicode(UTF-16)」にしないと検索がヒットしないので注意してください。 (Bzは現在表示している文字コードで検索する仕様です)
フルパスはハードディスクから実行した場合と異なる形式で記録されており、USBストレージから起動したことが分かります。 ハードディスクから起動した場合にどのように記録されているかは、ぜひ皆さんの環境でご確認ください。
なお、今回はボリュームシリアルをdirコマンドで確認しましたが、FTK Imager Liteなどで、 USBメモリ(またはUSBメモリのイメージファイル)を参照することでも確認することができます。 ボリュームシリアルは、ディスクのあるオフセットに書き込まれているのですが、今回は詳細な説明は割愛します。
Windows7環境におけるUSBメモリからの実行痕跡
冒頭で述べたとおり、Windows7環境では、PFファイルにUSBメモリの痕跡が残りませんので、注意が必要です。
具体的には、次のように記録されます。
- ボリュームシリアルは、OS起動ドライブのものが記録される
- プログラム本体やDLLファイルなど、USBメモリに格納したファイルのパスは一切記録されない
- ボリューム作成日時は、OS起動ドライブの$MFTのタイムスタンプが記録される
(本記事では説明していない内容のため、ご参考まで)