過去を掘り起こす: Windows レジストリ フォレンジックの再訪

A malicious actor creates a value in the Run key news

序章

FireEye のコンサルタントは、インシデント対応および侵害評価ミッションの一環としてコンピュータ ネットワークのフォレンジック分析を実行する際に、Windows レジストリ データを頻繁に利用します。これは、悪意のあるアクティビティを発見し、ネットワークから盗まれた可能性のあるデータを特定するのに役立ちます。レジストリにはさまざまな種類のデータが存在し、プログラムの実行、アプリケーションの設定、マルウェアの永続性、およびその他の貴重なアーティファクトの証拠を提供できます。

過去の攻撃のフォレンジック分析を実行することは、特に困難な場合があります。高度で持続的な脅威アクターは、アンチフォレンジック技術を頻繁に利用して痕跡を隠し、インシデント対応者の仕事をより困難にします。コンサルタントに可能な限り最高のツールを提供するために、既存のレジストリ フォレンジック手法を再検討し、過去のレジストリ データと削除されたレジストリ データを復元する新しい方法を特定しました。私たちの分析は、次の履歴レジストリ データの既知のソースに焦点を当てています。

  • レジストリ トランザクション ログ (.LOG)
  • トランザクション レジストリ トランザクション ログ (.TxR)
  • レジストリ ハイブの削除されたエントリ
  • バックアップ システム ハイブ (REGBACK)
  • システムの復元でバックアップされたハイブ

Windows レジストリ形式

Windows レジストリは、ハイブ ファイルのコレクションに格納されます。ハイブは、キー、値、データ、および関連するメタデータを格納するために使用される一連のセルを含む単純なファイル システムを含むバイナリ ファイルです。レジストリ ハイブは、4KB ページ (ビンとも呼ばれます) で読み書きされます。

Windows レジストリ ハイブ形式の詳細な説明については、この研究論文とこのGitHub ページを参照してください。

レジストリ トランザクション ログ (.LOG)

レジストリの信頼性を最大化するために、Windows はレジストリ ファイルへの書き込みを実行するときにトランザクション ログを使用できます。ログは、ハイブ ファイルに書き込まれる前にレジストリに書き込まれるデータを格納するジャーナルとして機能します。トランザクション ログは、ロックまたは破損のためにレジストリ ハイブに直接書き込むことができない場合に使用されます。

トランザクション ログは、対応するレジストリ ハイブと同じディレクトリ内のファイルに書き込まれます。ハイブと同じファイル名に.LOG拡張子を付けて使用します。 Windows は複数のログを使用する場合があり、その場合は.LOG1および.LOG2拡張子が使用されます。

トランザクション ログ形式の詳細については、このGitHub ページを参照してください。

レジストリ トランザクション ログは、Windows 2000 で初めて導入されました。元のトランザクション ログ形式では、データは常にトランザクション ログの先頭に書き込まれます。ログに存在するページを示すためにビットマップが使用され、ページが順番に続きます。ファイルの先頭は頻繁に上書きされるため、これらのログから古いデータを復元することは非常に困難です。使用ごとに異なる量のデータがトランザクション ログに書き込まれるため、複数の使用で古いページがファイルに残る可能性があります。ただし、各ページの場所は、現在のハイブで同様のページを検索して推測する必要があり、一貫したデータ回復の可能性は非常に低くなります。

Windows 8.1 では、新しいレジストリ トランザクション ログ形式が導入されました。新しいログは同じように使用されますが、形式が異なります。新しいログは、ログ内の最も古いデータが新しいデータで上書きされるリング バッファーのように機能します。新しいログ形式の各エントリには、シーケンス番号とレジストリ オフセットが含まれているため、書き込みの順序とページが書き込まれた場所を簡単に判断できます。ログ形式が変更されたため、データが上書きされる頻度が大幅に低下し、多くの場合、これらのログ ファイルから古いトランザクションを回復できます。

復元できるデータの量は、レジストリ アクティビティによって異なります。実世界のシステムからのトランザクション ログのサンプリングは、数日から数週間までの範囲の回復可能なデータを示しました。実際の回復可能性は大きく異なる場合があります。 Windows Update などのレジストリを多用する操作では、回復可能な範囲が大幅に減少する可能性があります。

新しいログ形式にはより多くの回復可能な情報が含まれていますが、一連のレジストリ ページを有用なデータに変換するのは非常に困難です。まず、レジストリ内のすべてのページを追跡し、特定の書き込みで何が変更されたかを判断する必要があります。また、その変更がハイブの後のリビジョンに存在しない何かをもたらしたかどうかを判断して、一意のデータが含まれているかどうかを評価する必要もあります。

レジストリ トランザクション ファイルを処理するための現在のアプローチでは、次のアルゴリズムを使用します。

  1. 最新の書き込みが最初に処理されるように、すべての書き込みをシーケンス番号の降順に並べ替えます。
  2. 割り当てられたセルと割り当てられていないセルの解析を実行して、割り当てられたエントリと削除されたエントリを見つけます。
  3. エントリを元のハイブと比較します。存在しないエントリは、削除済みとしてマークされ、ログに記録されます。

トランザクション ログの例

この例では、Run キーの下にレジストリ値を作成し、ユーザーがシステムにログインしたときに、malware.exe を起動します。

A malicious actor creates a value in the Run key
図 1: 悪意のあるアクターが Run キーに値を作成する

その後、マルウェアはシステムから削除されます。レジストリ値は、削除される前に上書きされます。

悪意のある値が上書きされ、削除されます
図 2: 悪意のある値が上書きされて削除される

削除された値はまだハイブに存在しますが、元のデータは上書きされているため、既存のフォレンジック ツールでは復元できません。

上書きされた値がレジストリ ハイブに存在する
図 3: 上書きされた値がレジストリ ハイブに存在する

ただし、この場合、データはまだトランザクション ログに存在し、回復することができます。

トランザクション ログには元の値が含まれています
図 4: トランザクション ログには元の値が含まれています

トランザクション レジストリ トランザクション ログ (.TxR)

トランザクション ログ ジャーナルに加えて、トランザクション レジストリ サブシステムによって使用されるログもあります。アプリケーションはトランザクション レジストリを利用して、複合レジストリ操作をアトミックに実行できます。これは、失敗した操作のロールバックを簡素化するため、アプリケーションのインストーラーによって最も一般的に使用されます。

トランザクション レジストリ ログは、共通ログ ファイル システム (CLFS) 形式を使用します。ログは<hive><GUID>.TxR.<number>.regtrans-msの形式のファイルに保存されます。ユーザーハイブの場合、これらのファイルはハイブと同じディレクトリに保存され、ユーザーのログアウト時に消去されます。ただし、システム ハイブの場合、ログは%SystemRoot%System32configTxRに保存され、ログは自動的に消去されません。その結果、通常、システム トランザクション ログから履歴データを復元できます。

トランザクション ログの形式は、十分に理解されていないか、文書化されていません。 Microsoft は、CLFS ログと API の概要を提供しています。

いくつかの実験により、基本的なレコード形式を決定することができました。レジストリ キーの作成と削除、およびレジストリ値の書き込みと削除のレコードを特定できます。関連するキー パス、値の名前、データ型、およびデータがログ エントリ内に存在します。トランザクション ログ レコード フォーマットの詳細については、付録を参照してください。

レジストリ トランザクション ログに存在するほとんどのデータは、侵入調査にとって特に価値のあるものではありませんが、データが役立つ場合があります。特に、スケジュールされたタスクの作成と削除では、レジストリ トランザクションが使用されることがわかりました。レジストリ トランザクション ログを解析することで、稼働中のシステムで攻撃者がスケジュールされたタスクを作成した証拠を見つけることができました。このデータは、他の場所では入手できませんでした。

タスク スケジューラは、Windows Vista から Windows 8.1 までのトランザクション レジストリ操作を使用して確認されています。 Windows 10 のタスク スケジューラは、この動作を示しません。 Windows 10 の動作が異なる理由は不明です。

トランザクション レジストリの例

この例では、スケジュールされたタスクを作成します。スケジュールされたタスクは定期的にマルウェアを実行します。

マルウェアを実行するスケジュールされたタスクの作成
図 5: マルウェアを実行するスケジュールされたタスクの作成

スケジュールされたタスクに関する情報はレジストリに保存されます。

タスク スケジューラによって作成されたレジストリ エントリ
図 6: タスク スケジューラによって作成されたレジストリ エントリ

スケジュールされたタスクはトランザクション レジストリ操作を使用してレジストリに書き込まれたため、トランザクション レジストリ トランザクション ログでデータのコピーを使用できます。スケジュールされたタスクがシステムから削除された後も、データはログに残ることがあります。

TxR ログの悪意のあるスケジュールされたタスク
図 7: TxR ログ内の悪意のあるスケジュールされたタスク

削除されたエントリの回復

トランザクション ログに加えて、レジストリ ハイブ ファイルから削除されたエントリを回復する方法も調べました。より正確なアプローチを特定することを期待して、今日のフォレンジック ツールで使用されているいくつかの一般的な手法の詳細な分析から始めました。

削除されたエントリの回復には、ハイブ ファイル内のレジストリ セルの解析が必要です。これは比較的簡単です。 FireEye には、未加工のレジストリ ハイブ ファイルを読み取り、関連するキー、値、およびセルのデータを解析できるツールが多数あります。要素が削除されると一部の情報が失われるため、削除されたデータの回復はより複雑になります。結果として生じるあいまいさに対処するには、より洗練されたアプローチが必要です。

セルを解析する場合、共通のフィールドは 1 つだけです: セル サイズです。一部のセル タイプには、タイプの判別に役立つマジック ナンバー識別子が含まれています。ただし、データ リストや値リストなど、他のセル タイプには識別子がありません。それらの型は、他のセルからの参照に従って推測する必要があります。さらに、セル内のデータのサイズは、セルのサイズとは異なる場合があります。セルの種類によっては、参照セルからの情報を活用してデータ サイズを決定する必要がある場合があります。

レジストリ要素が削除されると、そのセルは未割り当てとしてマークされます。セルはすぐには上書きされないため、削除された要素は多くの場合、レジストリ ハイブから復元できます。ただし、割り当てられていないセルを隣接する割り当てられていないセルと合体させて、走査効率を最大化することができます。これにより、セル サイズが変更される可能性があるため、削除されたセルの回復がより複雑になります。その結果、元のセルの境界は明確に定義されておらず、セルの内容を調べて暗黙的に決定する必要があります。

削除されたエントリを回復するための既存のアプローチ

公開文献とソース コードを確認したところ、レジストリ ハイブ ファイルから削除された要素を復元するための既存の方法が明らかになりました。次のアルゴリズムのバリエーションが一般的に見つかりました。

  1. 割り当てられていないすべてのセルを検索して、削除されたキー セルを探します。
  2. 削除されたキーから参照された削除された値を見つけます。
  3. 参照されていない削除された値のセルを探して、残りのすべての未割り当てのセルを検索します。
  4. 削除されたすべての値から参照データ セルを検索します。

同様のアルゴリズムを実装して、その有効性を実験しました。この単純なアルゴリズムは、削除された多くのレジストリ要素を復元できましたが、いくつかの重大な欠点がありました。大きな問題の 1 つは、削除されたセルからの参照を検証できないことでした。参照されたセルはすでに複数回上書きまたは再利用されている可能性があるため、プログラムは値とデータの識別で頻繁に間違いを犯し、誤検出や無効な出力が発生しました。

また、プログラムの出力を一般的なレジストリ フォレンジック ツールと比較しました。私たちのプログラムはほとんど同じ出力を生成しましたが、既存のレジストリ フォレンジック ツールがより多くのデータを回復できることは明らかでした。特に、既存のツールは、まだ上書きされていない、割り当てられたセルのスラック スペースから削除された要素を復元できました。

さらに、孤立した割り当てられたセルも削除されたと見なされることがわかりました。関連するすべてのセルが削除時に同時に割り当て解除される必要があるため、参照されていない割り当てられたセルがレジストリ ハイブにどのように存在する可能性があるかは不明です。特定のタイプの障害により、削除されたセルが適切に未割り当てにならない可能性があります。

実験を通じて、既存のレジストリ ツールがより優れた検証を実行できるため、誤検知が少なくなることがわかりました。ただし、既存のツールが削除された値の関連付けを誤って作成し、無効なデータを出力するケースも多数確認されました。これは、セルが複数回再利用され、慎重に精査しないと参照が有効に見える可能性がある場合に発生する可能性があります。

削除されたエントリを回復するための新しいアプローチ

アルゴリズムを改善する可能性を考慮して、削除されたレジストリ要素を最大の精度と効率で回復するために大幅な再設計を行いました。何度も実験と改良を重ねた結果、パフォーマンスを最大化しながら、削除されたレジストリ要素を正確に復元できる新しいアルゴリズムにたどり着きました。これは、レジストリ ハイブ内のすべてのセルを検出して追跡し、セルのスラック スペースを処理して、孤立したキーと値を検出することによって、より良い検証を実行することによって達成されました。テスト結果は、既存のレジストリ フォレンジック ツールとほぼ一致しましたが、検証が改善され、誤検知が少なくなりました。

以下は、改善されたアルゴリズムの概要です。

  1. すべての割り当て済みおよび未割り当てのセルに対して基本的な解析を実行します。可能であれば、セルの種類とデータ サイズを決定します。
  2. 割り当てられたすべてのセルを列挙し、次の操作を行います。
    • 割り当てられたキーについては、参照された値リスト、クラス名、およびセキュリティ レコードを見つけます。参照されるセルのデータ サイズを設定します。キーの祖先を検証して、キーが孤立しているかどうかを判断します。
    • 割り当てられた値については、参照データを見つけてデータ サイズを設定します。
  3. 割り当てられたすべてのセル スラック スペースを未割り当てセルとして定義します。
  4. 割り当てられたキーを列挙し、値リストに存在する削除された値を見つけようとします。また、値リストのスラック スペースで古い削除された値の参照を見つけようとします。
  5. 割り当てられていないセルを列挙し、削除されたキー セルを見つけようとします。
  6. 割り当てられていないキーを列挙し、参照されるクラス名、セキュリティ レコード、および値の定義を試みます。
  7. 割り当てられていないセルを列挙し、参照されていない削除された値のセルを見つけようとします。
  8. 割り当てられていない値を列挙し、参照されているデータ セルを見つけようとします。

削除された回復の例

次の例は、削除されたエントリの回復アルゴリズムがより正確なデータ回復を実行し、誤検知を回避する方法を示しています。図 8 は、一般的なレジストリ フォレンジック ツールによるデータ リカバリ エラーの例を示しています。

誤って復元されたレジストリ データ
図 8: 誤って復元されたレジストリ データ

このキーから復元された ProviderName は、上書きされた場所を参照しているため、ごちゃ混ぜになっていることに注意してください。削除されたレジストリの回復ツールを同じハイブに対して実行すると、データが上書きされたことを認識し、文字化けを出力しません。図 9 のdata_presentフィールドの値が 0 であることは、削除されたデータをハイブから復元できなかったことを示しています。

キー: CMI-CreateHive{2A7FB991-7BBE-4F9D-B91E-7CB51D4737F5}
ControlSet002ControlClass{4D36E972-E325-11CE-BFC1-08002BE10318}

Key: CMI-CreateHive{2A7FB991-7BBE-4F9D-B91E-7CB51D4737F5}
     ControlSet002ControlClass{4D36E972-E325-11CE-BFC1-08002BE10318}019
Value: ProviderName  Type: REG_SZ  (value_offset=0x137FE40) (data_size=20)
     (data_present=0) (data_offset=0x10EAF68) (deleted_type=UNALLOCATED)

19
値: ProviderName タイプ: REG_SZ (value_offset=0x137FE40) (data_size=20)
( data_present=0 ) (data_offset=0x10EAF68) (deleted_type=UNALLOCATED)

図 9: 適切に検証されたレジストリ データ

レジストリのバックアップ

Windows には、システム レジストリ ハイブを定期的にバックアップする簡単なメカニズムが含まれています。ハイブは、既定で 10 日ごとに実行されるようにスケジュールされている RegIdleBackup と呼ばれるスケジュールされたタスクでバックアップされます。バックアップされたハイブは%SystemRoot%System32configRegBackに保存されます。この場所には、最新のバックアップのみが保存されます。これは、システムでの最近のアクティビティを調査するのに役立ちます。

RegIdleBackup 機能は、Windows Vista で最初に組み込まれました。それ以降、Windows のすべてのバージョンに存在しますが、Windows 10 システムではデフォルトで実行されず、手動で実行してもバックアップは作成されません。 RegIdleBackup が Windows 10 から削除された理由は不明です。

RegBack に加えて、レジストリ データは System Restore でバックアップされます。デフォルトでは、Windows Update を含むソフトウェアがインストールまたはアンインストールされるたびに、システムの復元のスナップショットが作成されます。その結果、システムの復元のスナップショットは通常、少なくとも毎月作成されます。システム復元のスナップショットを操作する高度な永続的脅威グループがいくつか知られていますが、通常、攻撃者が活動していたときにスナップショットが作成されていれば、過去の攻撃者の活動の証拠を見つけることができます。システムの復元のスナップショットには、システム ハイブとユーザー ハイブを含むすべてのレジストリ ハイブが含まれています。

ウィキペディアには、システムの復元に関する有益な情報がいくつかあります。

システムの復元スナップショットでのハイブの処理は、システム上に多数のスナップショットが存在する可能性があり、その結果大量のデータが処理される可能性があり、多くの場合、スナップショット間でハイブにわずかな変更しかないため、困難な場合があります。多数のスナップショットを処理する方法の 1 つは、レジストリ ハイブのセルを表す構造を構築し、スナップショットごとにこのプロセスを繰り返すことです。以前の構造にないものはすべて、削除されたと見なされ、適切にログに記録されます。

結論

レジストリは、フォレンジック調査員に豊富なデータを提供できます。削除された履歴データの多数のソースを使用して、調査中に攻撃者の活動のより完全な全体像を組み立てることができます。攻撃者はますます巧妙になり、技術を向上させ続けるため、調査員は攻撃者を発見して防御するために適応する必要があります。

付録 – トランザクション レジストリ トランザクション ログ (.TxR) レコード形式

レジストリ トランザクション ログには、次の形式のレコードが含まれます。

オフセット

分野

サイズ

0

マジックナンバー (0x280000)

4

12

レコードサイズ

4

16

レコードタイプ (1)

4

20

レジストリ操作の種類

2

40

キーパスのサイズ

2

42

繰り返されるキー パス サイズ

2

マジック ナンバーは常に 0x280000 です。
レコードサイズにはヘッダーが含まれます。
レコード タイプは常に 1 です。

操作タイプ 1 は鍵の作成です。
操作タイプ 2 はキーの削除です。
操作タイプ 3 ~ 8 は、値の書き込みまたは削除です。異なるタイプが何を意味するかは不明です。

キー パスのサイズはオフセット 40 で、オフセット 42 で繰り返されます。これは、すべてのレジストリ操作タイプに存在します。

レジストリ キーの書き込み操作と削除操作の場合、キー パスはオフセット 72 にあります。

レジストリ値の書き込みおよび削除操作の場合、次のデータが存在します。

オフセット

分野

サイズ

56

値の名前のサイズ

2

58

値の名前のサイズが繰り返される

2

72

データ・タイプ

4

76

データサイズ

4

値レコードのデータは、オフセット 88 から始まります。これには、キー パスとそれに続く値名が含まれ、その後にオプションでデータが続きます。データ サイズがゼロ以外の場合、レコードは値の書き込み操作です。それ以外の場合は、値の削除操作です。

参照: https://www.mandiant.com/resources/blog/digging-up-the-past-windows-registry-forensics-revisited

Comments

タイトルとURLをコピーしました