John Uhlmann

カーネル ETW は最高の ETW です

この調査は、セキュリティ・バイ・デザイン・ソフトウェアにおけるネイティブ監査ログの重要性に焦点を当て、改ざん防止対策を強化するために、ユーザーモードのフックよりもカーネルレベルのETWロギングの必要性を強調しています。

14分で読めます展望
カーネルETWこそ最高のETW

前文

セキュア・バイ・デザイン・ソフトウェアの重要な機能は、特権操作が実行されたときに監査ログを生成することです。 これらのネイティブ監査ログには、内部ソフトウェアの状態の詳細が含まれている可能性がありますが、サードパーティのセキュリティベンダーが事後的に追加することは現実的ではありません。

ほとんどの Windows コンポーネントは 、Event Tracing for Windows (ETW) を使用してログを生成します。 これらのイベントは Windows の内部動作の一部を公開し、エンドポイント セキュリティ製品がそれらをサブスクライブすることでメリットを得るシナリオがあります。 ただし、セキュリティ上の理由から、すべての ETW プロバイダーが同じように作成されているわけではありません。

通常、最初の考慮事項は、イベント プロバイダー自体の信頼性 (特に、ログ記録が行われる場所) です。 それはクライアント プロセス内にあり、 ETW 改ざんに対して簡単に脆弱ですか? それとも、RPCサーバープロセスの方が少し安全ですか? ただし、テレメトリは カーネルから取得するのが理想的です。 ユーザーとカーネルのセキュリティ境界を考えると、これにより、インプロセステレメトリに対する改ざん防止の保証が強化されます。 これは、Microsoft が推奨するアプローチです。 Elastic Endpoint と同様に、Microsoft Defender for Endpoint も、脆弱なユーザー モード ntdll フックよりもカーネル ETW を使用します。

たとえば、敵対者は ntdll!NtProtectVirtualMemoryのインプロセス ユーザー モード フックを簡単に回避できる可能性がありますが、カーネル PROTECTVM ETW イベントをバイパスするのは非常に困難です。 あるいは、少なくとも、 そうあるべきです

セキュリティ イベント ログは、実質的には Microsoft-Windows-Security-Auditing ETW プロバイダーからのイベントの永続ストレージにすぎません。 驚いたことに、プロセス作成のセキュリティ イベント 4688 はカーネル イベントではありません。 カーネルは、データをローカル セキュリティ機関 (lsass.exe) サービスにディスパッチし、イベント ログで使用する ETW イベントを生成します。 そのため、そのサーバープロセス内からデータが改ざんされる可能性があります。 これとは対照的に、Microsoft-Windows-Kernel-Process プロバイダーからの ProcessStart イベントは、カーネルによって直接ログに記録され、干渉するにはカーネル レベルの特権が必要です。

2 つ目の考慮事項は、ログに記録される情報の信頼性です。 イベント ソースは信頼できますが、ログに記録されるイベントに外部から発生する クライアント提供のデータを 盲目的にログに記録 している場合はどうでしょうか。

この記事では、カーネル ETW イベントに焦点を当てます。 これらは、バイパスするのが難しく、多くの場合、クライアントスレッドの代わりに実行される特権アクションに関連しているため、セキュリティに最も関連します。

Microsoft がカーネル パッチ保護を導入したとき、セキュリティ ベンダはカーネルを監視する能力に大きな制約を受けていました。 Microsoftが提供するカーネル拡張ポイントの数が限られているため、マルウェアに代わって実行されるカーネルアクションの事後的な可視性のために、非同期ETWイベントに依存することを余儀なくされるようになりました。

この依存関係を考えると、Windows カーネル テレメトリ ソースの公開ドキュメントは残念ながらややまばらです。

カーネル ETW イベント

現在、考慮する必要がある ETW プロバイダーには 4 種類 あります。

まず、「イベントプロバイダー」にはレガシーなバリエーションと最新のバリエーションがあります。

  • レガシー (MOF ベース) イベント プロバイダー
  • 最新の (マニフェスト ベース) イベント プロバイダー

そして、「トレースプロバイダー」のレガシーと現代のバリエーションがあります。

  • 従来の Windows ソフトウェア トレース プリプロセッサ (WPP) トレース プロバイダー
  • 最新の TraceLogging トレース プロバイダー

「イベント」と「トレース」の区別は、ほとんどが意味論的です。 通常、イベント プロバイダーはオペレーティング システムに事前に登録され、使用可能なテレメトリ メタデータを検査できます。 これらは通常、システム管理者がトラブルシューティングの目的で使用し、多くの場合、半ば文書化されています。 しかし、何かが本当に、 本当に うまくいかない場合、(隠された)トレースプロバイダーがあります。 これらは通常、元のソフトウェア作成者のみが高度なトラブルシューティングのために使用し、文書化されていません。

実際には、それぞれがわずかに異なる形式のファイルを使用してイベントを記述および登録するため、イベントのログ記録方法、さらに重要なことに、潜在的なイベントの列挙方法にわずかな違いが生じます。

最新のカーネル イベント プロバイダー

最新のカーネル ETW プロバイダーは、厳密には文書化されていません。 ただし、登録されたイベントの詳細は、 Trace Data Helper API を介してオペレーティング システムからクエリできます。 Microsoft の PerfView ツールは、これらの API を使用してプロバイダー の登録マニフェストを再構築し、Pavel Yosifovich の EtwExplorer はこれらのマニフェストを単純な GUI にラップします。 これらの タブ区切りの値ファイルは 、後続の Windows バージョンから登録されたマニフェストのファイルとして使用できます。 イベントごとに 1 行は grep に非常に便利ですが、他の XML マニフェストはその後に公開されています。

ただし、これらは考えられるすべての Windows ETW イベントではありません。 これらは、デフォルトでオペレーティングシステムに登録されているもののみです。 たとえば、多くのサーバーの役割の ETW イベントは、その機能が有効になるまで 登録されません

従来のカーネル イベント プロバイダー

従来のカーネル イベントは、Microsoft によって文書化されています。大概。

レガシ プロバイダーは、WMI EventTrace クラスとしてオペレーティング システム内にも存在します。 プロバイダーはルート クラス、グループは子、イベントは孫です。

モダン イベントと同じ方法でレガシ イベントを検索するには、モダン イベントと同じ方法でレガシ イベントを検索するために、これらのクラスが解析され、元の MOF が (ほとんど) 再構築されました。 この MOF サポートは EtwExplorer に追加され、 レガシ イベントの タブ区切り値の概要 は、これらのクラスが解析され、元の MOF が (ほとんど) 再構築されました。 この MOF サポートは、EtwExplorer と 、パブリッシュされたレガシ イベントの タブ区切り値の概要 に追加されました。

完全に再構築された Windows カーネル トレース MOF は 、こちら (または表形式) にあります ( こちら)。

登録された 340 レガシーイベントのうち、文書化されたのは 116 つだけでした。 通常、各レガシーイベントは特定のフラグを使用して有効にする必要がありますが、これらも文書化されていませんでした。 カーネルの オブジェクト マネージャー トレース イベントに関する手がかりは、ドキュメントにありました。 最新のSDKのヘッダーで定義されていない定数である PERF_OB_HANDLEについて説明しました。 幸いなことに、 Geoff Chappell 氏と Windows 10 1511 WDK が救いの手を差し伸べてくれました。 この情報は、Microsoft の KrabsETW ライブラリに PERFINFO_GROUPMASK カーネル トレース フラグのサポートを追加するために使用されました。また、オブジェクトトレースのドキュメントが間違っていたことも判明しました。 その非公開定数は、文書化されていないAPI拡張でのみ使用できます。 さいわい、 PerfView などの公開 Microsoft プロジェクトでは、 多くの場合、文書化されていない API の使用方法の例が提供されています。

マニフェストと MOF の両方が GitHub で公開されているため、ほとんどのカーネル イベントを このクエリで見つけることができるようになりました。

興味深いことに、Microsoft はセキュリティ関連のイベントの名前を 難読 化することが多いため、 task_ などの汎用的な名前プレフィックスを持つイベントを検索すると、 興味深い結果が得られます。

キーワードがイベントの目的を示唆している場合があります。 たとえば、Microsoft-Windows-Kernel-Generaltask_014 はキーワード [KERNEL_GENERAL_SECURITY_ACCESSCHECK.] で有効になります

そしてありがたいことに、パラメーターにはほとんどの場合、適切な名前が付けられています。 Microsoft-Windows-Kernel-Audit-API-Callstask_05 は、 TargetProcessIdDesiredAccessという名前のフィールドをログに記録するため、OpenProcess に関連していると推測できます。

別の便利なクエリ は、明示的な ProcessStartKey フィールドを持つイベントを検索することです。 ETW イベントは、ログ プロセスにこのフィールドを含める ように構成 でき、別のプロセスのこの情報を含むイベントは、多くの場合、セキュリティに関連しています。

特定の API を念頭に置いている場合は、その名前やパラメーターをクエリできます。 たとえば、名前付きパイプ イベントが必要な場合は、 このクエリを使用できます。

ただし、この場合、 Microsoft-Windows-SEC Microsoft Defender for Endpoint (MDE) が利用する組み込みの Microsoft セキュリティ ドライバーに属しています。 このプロバイダは MDE のみが公式に利用できますが、 Sebastian Feldmann と Philipp Schmied は、 AutoLogger を使用してセッションを開始し、そのセッションのイベントにサブスクライブする方法を示しました。 これは現在、MDE ユーザーにとってのみ有用であり、それ以外の場合、ドライバーはイベントを出力するように構成されていません。

しかし、トレースプロバイダーはどうでしょうか?

最新のカーネルトレースプロバイダー

TraceLogging メタデータは、ログ バイナリ内に不透明な BLOB として格納されます。 ありがたいことに、この形式は マット・グレーバーによって逆転されました。 Matt のスクリプトを使用して、 ntoskrnl.exeのすべての TraceLogging メタデータをダンプできます。 Windows 11 TraceLogging メタデータのサンプル ダンプは 、こちらにあります。

残念ながら、メタデータ構造だけでは、プロバイダーとイベントの間の相関関係は保持されません。 Microsoft.Windows.Kernel.SecurityAttackSurfaceMonitorなどの興味深いプロバイダー名がありますが、メタデータ ダンプからは、これらのプロバイダーに属するイベントはまだ明確ではありません。

レガシ カーネル トレース プロバイダー

WPP メタデータは、シンボル ファイル (PDB) 内に格納されます。 Microsoft では 、この情報を一部のドライバー (すべてではない) のパブリック シンボルに含めています。 ただし、カーネル自体は WPP イベントを生成しません。 代わりに、従来の Windows カーネル トレース イベント プロバイダーに文書化されていないフラグを渡して、通常は Microsoft カーネル開発者のみが使用できる従来の "トレース" イベントを有効にすることができます。

プロバイダードキュメントイベント メタデータ
最新のイベントプロバイダーなし登録済みの XML マニフェスト
レガシーイベントプロバイダーパーシャルEventTrace WMI オブジェクト
最新のトレースプロバイダーなしバイナリの文書化されていない BLOB
レガシートレースプロバイダーなしシンボル内の文書化されていないブロブ

次のステップ

現在、ETW プロバイダーの 4 つのフレーバーのそれぞれについてカーネル イベント メタデータがありますが、ETW イベントの一覧は出発点にすぎません。 プロバイダーとイベントキーワードを知っているだけでは、期待するイベントを生成するのに十分ではない場合があります。 場合によっては、追加の構成レジストリ キーまたは API 呼び出しが必要になります。 ただし、多くの場合、イベントがログに記録される正確な条件を理解する必要があります。

どこで何がログに記録されているかを正確に把握することは、テレメトリとその制限を真に理解するために重要です。 そして、逆コンパイラがすぐに利用できるようになったおかげで、私たちはちょうど十分な逆転のオプションを利用できるようになりました。 IDAでは、これを「F5を押す」と呼んでいます。 Ghidraはオープンソースの代替手段であり、スクリプトをサポートしています...Javaで。

カーネル ETW では、システム コールから到達可能な EtwWrite 呼び出しに特に関心があります。 コール サイトのパラメーター情報 (関連するパブリック シンボル情報を含む) をできるだけ多くする必要があります。 つまり、コールグラフをたどるだけでなく、特定のパラメータの可能な値を解決しようとする必要がありました。

必要なパラメータは、 RegHandleEventDescriptorでした。 前者はプロバイダーの不透明なハンドルであり、後者はイベント ID やそれに関連するキーワードなどのイベント固有の情報を提供します。 ETW キーワードは、一連のイベントを有効にするために使用される識別子です。

さらに良いことに、これらのイベント記述子は通常、公開シンボルを持つグローバル定数に格納されていました。

十分なイベント メタデータがありましたが、実行時に割り当てられた不透明なプロバイダー ハンドルをプロバイダーに関するメタデータに解決する必要がありました。 そのためには、 EtwRegister コールも必要でした。

カーネルの最新のイベント プロバイダーの一般的なパターンは、定数プロバイダー GUID とランタイム ハンドルをパブリック シンボルを使用してグローバルに格納することでした。

別のパターンは、 EtwRegisterEtwEwrite、および EtwUnregisterの呼び出しがすべて同じ関数で行われたことです。 この場合、ローカリティを利用して、イベントのプロバイダー GUID を見つけました。

ただし、最新の TraceLogging プロバイダーには、各プロバイダーの目的のヒントを提供するプロバイダーごとのパブリック シンボルが関連付けられていませんでした。 ただし、Matt Graeber は TraceLogging メタデータ形式を逆にして 、プロバイダー名がプロバイダー GUID からの 固定オフセット に格納されることを文書化しました。 正確なプロバイダー名を持つことは、現代のイベントのために回復した公開シンボルよりもさらに優れています。

これにより、従来のプロバイダーが残されました。 公開シンボルもメタデータブロブも持っていないようでした。 一部の定数は、最終的な ETW 書き込み呼び出しをラップする EtwTraceKernelEvent という名前のドキュメントに記載されていない関数に渡されます。

これらの定数は Windows 10 1511 WDK ヘッダー (および System Informer ヘッダー) に存在するため、これらのイベントに定数名でラベルを付けることができます。

このスクリプトは最近 Ghidra 11 用に更新され、TraceLogging イベントと Legacy イベントのサポートが改善されました。 GitHubのこちらの https://github.com/jdu2600/API-To-ETW で見つけることができます

Windows 11 カーネルのサンプル出力は 、こちらです。

以前は匿名だった Microsoft-Windows-Kernel-Audit-API-Calls イベントは、このスクリプトによってすぐにマスクが解除されます。

IDEVENT_DESCRIPTORシンボル関数
1KERNEL_AUDIT_API_PSSETLOADIMAGENOTIFYROUTINEPsSetLoadImageNotifyRoutineEx
2KERNEL_AUDIT_API_TERMINATEPROCESSNtTerminateProcess (英語)
3KERNEL_AUDIT_API_CREATESYMBOLICLINKOBJECTObCreateSymbolicリンク
4KERNEL_AUDIT_API_SETCONTEXTTHREADNtSetContextThreadの
5KERNEL_AUDIT_API_OPENPROCESSPsOpenProcess
6KERNEL_AUDIT_API_OPENTHREADPsOpenThreadの
7KERNEL_AUDIT_API_IOREGISTERLASTCHANCESHUTDOWNNOTIFICATIONIoRegisterLastChanceShutdownNotification
8KERNEL_AUDIT_API_IOREGISTERSHUTDOWNNOTIFICATIONIoRegisterShutdownNotification

Microsoft-Windows-Kernel-Audit-API-Calls イベントのシンボルとそれを含む関数

スクリプトによって回復された呼び出しパスとパラメータ情報を使用すると、前の SECURITY_ACCESSCHECK イベントが SeAccessCheck カーネル API に関連付けられていることがわかりますが、 SeLogAccessFailureという名前の関数内にのみ記録されていることもわかります。 エラー状態のログ記録のみが ETW イベントで非常によく発生します。 トラブルシューティングの目的で、元の ETW のユース ケースであるこれらは通常最も便利であり、ほとんどのコンポーネントでの実装はこれを反映しています。 残念ながら、セキュリティ上の理由から、その逆がしばしば当てはまります。 通常、成功した操作ログは、悪意のあるアクティビティを見つけるのに便利です。 そのため、これらのレガシーイベントの一部は価値が低いことがよくあります。

最新の セキュリティ保護バイデザインの 実践は、セキュリティ関連のアクティビティの成功と失敗の両方を監査ログに記録することであり、Microsoft はこれを行う新しいセキュリティ関連の ETW イベントを継続的に追加しています。 たとえば、Windows 11 24H2 のプレビュー ビルドには、Microsoft-Windows-Threat-Intelligence プロバイダーに興味深い新しい ETW イベントがいくつか含まれています。うまくいけば、これらはリリースに先立ってセキュリティベンダー向けに文書化されます。

この逆コンパイラ スクリプトを興味深い Windows ドライバーとサービス DLL に対して実行することは、読者の演習として残されています。

この記事を共有する