本文の内容は、2024年2月2日にNIGEL DOUGLAS が投稿したブログ(https://sysdig.com/blog/kernel-introspection-from-linux-to-windows/)を元に日本語に翻訳・再構成した内容となっております。
サイバーセキュリティの状況は大きく変化しており、ユーザー空間で実行されるアプリケーションを監視するセキュリティツールから、eBPFを使用してカーネル内でシステムアクティビティを直接かつ安全に監視する高度なリアルタイムアプローチへと移行しています。カーネル・イントロスペクションにおけるこの進化は、Linux環境におけるFalco、Tetragon、Traceeのようなプロジェクトの採用において特に明らかです。これらのツールは、Kubernetesの下でコンテナ化されたワークロードを実行するシステムで特に普及しており、動的でエフェメラルなワークロードのリアルタイム監視において重要な役割を果たしています。
オープンソースプロジェクトFalcoは、この傾向を体現しています。このプロジェクトは、システムのワークロードを精査し、セキュリティイベントをカーネルからユーザー空間に中継するために、さまざまな計測技術を採用しています。これらのインストゥルメンテイションは、カーネル空間での動作を反映して、Falco 内では「ドライバー」と呼ばれています。ドライバーは、システムコールコンテキストと密接に結びついた活動を監視するために不可欠なシステムコールイベントソースを提供するため、極めて重要です。Falco をデプロイする際、カーネルモジュールは通常バイナリーパッケージに含まれる falco-driver-loader スクリプトを介してインストールされます。このプロセスは、Falcoの監視機能をシームレスにシステムに統合し、カーネル レベルでのセキュリティ脅威に対するリアルタイムの検知と対応を可能にします。
システムコールはどのように機能しますか?
システムコール(略してシスコール)は、ソフトウェアがオペレーティングシステムと どのように相互作用するかの基本的な側面をなすものです。システムコールは、オペレーティングシステムのカーネルにおいて不可欠なメカニズムであり、ユーザー空間のアプリケーションとカーネルの間の主要なインターフェースとして機能します。
シスコールは、アプリケーションがオペレーティングシステムのカーネルにサービスを要求するために使用するファンクションです。これらのサービスには、ファイルの読み書き、ネットワークデータの送信、ハードウェアデバイスへのアクセスなどの操作が含まれます。
- ユーザー空間のアプリケーションがカーネルの介入を必要とする操作を実行する必要がある場合、そのアプリケーションはシステムコールを行います。
- アプリケーションは通常、オペレーティングシステムが提供する高レベルAPIを使用し、システムコールの詳細を抽象化します。
- システムコールはプロセッサをユーザーモードからカーネルモードに切り替えます。
- カーネルは要求されたサービスを実行し、その結果をユーザースペースアプリケーションに返し、ユーザモードに戻ります。
システムコールの種類
システムコールは、次のようないくつかの種類に分類できます:
- ファイル管理:ファイルのオープン、読み取り、書き込み、クローズなどの操作
- プロセス制御: プロセスの作成と終了、プロセスのスケジューリング
- メモリ管理: メモリの割り当てと解放
- デバイス管理: ハードウェアデバイスへのアクセス要求
- 情報メンテナンス: システム情報の要求と更新
- コミュニケーション: 通信チャネルの作成と管理
Linuxシステムコールの例
- open() :ファイルを開くために使用
- read() :ファイルまたはネットワークからデータを読み込むときに使用します。
- write():ファイルまたはネットワークにデータを書き込むときに使用します。
- fork() :新しいプロセスを作成するときに使用します。
カーネル・イントロスペクションにシステムコールが必要な理由
システムコールは、ユーザー空間のアプリケーションがカーネルによって管理されるハードウェアやリソースにアクセスするための制御されたインターフェースを提供します。システムコールは、悪用されるとシステムに損害を与える可能性のある重要なシステムリソースにアプリケーションが直接アクセスできないようにすることで、セキュリティと安定性を確保します。
カーネル・イントロスペクションのパフォーマンスに関する考慮事項
システムコールは、ユーザーモードとカーネルモード間のコンテキスト切り替えを伴います。したがって、システムコールを効率的に使用することは、アプリケーション開発において重要です。
LinuxにおけるeBPFへの移行
要約すると、システムコールは、アプリケーションがオペレーティングシステムのカーネルにサービスを要求したり、サービスを受け取ったりするゲートウェイとして機能し、あらゆるコンピュータシステムの動作にとって極めて重要です。システムコールは、リソース管理、セキュリティ、および抽象化において重要な役割を果たし、ハードウェアやオペレーティングシステム内部の低レベルの詳細と直接やり取りすることなく、アプリケーションが複雑な 操作を実行できるようにします。
近年、拡張バークレー・パケット・フィルタ(eBPF)と呼ばれる技術への移行が見られます。eBPFはLinuxカーネルに起源を持つ画期的な技術で、サンドボックス化されたプログラムをオペレーティングシステムカーネルなどの特権コンテキストで実行できます。カーネルソースコードの変更やカーネルモジュールのロードを必要とせず、安全かつ効率的にカーネルの機能を拡張するために使用され、従来のカーネルモジュールに代わる安全な選択肢となります。
歴史的に、オペレーティングシステムは、システム全体を監督し制御するカーネルの特権的な能力により、可観測性、セキュリティ、およびネットワーク機能を実装するのに常に理想的な場所でした。同時に、オペレーティングシステムのカーネルは、その中心的な役割と安定性とセキュリティに対する高い要求のために進化しにくい事があります。そのため、オペレーティングシステムレベルでの技術革新の速度は、オペレーティングシステムの外部で実装される機能に比べ、伝統的に低くなっています。
ホストに最も顕著な影響を与えるのは、イベントがユーザー空間に送信される回数と、このイベントを処理するためにユーザー空間で実行する必要がある作業量です。言い換えれば、イベントを確実にドロップして無視するには、早ければ早いほどよいということです。これが、eBPFやカーネルモジュールのようなプログラマブルソリューションが有益な理由です。カーネル空間からユーザ空間へ送信されるデータ量を制御するために、きめ細かなインカーネルフィルターを開発する能力を持つことは、Linux において大きな利点です。
例えばFalcoは、アダプティブシスコールセレクション(Adaptive Syscall Selection)により、監視する特定のシステムコールを選択する能力を持っています。これにより、ユーザはきめ細かな制御が可能となり、選択的なシスコールモニタを通じてCPU負荷を軽減し、システムパフォーマンスを最適化することができます。ルールからのイベント文字列を対応するシスコール ID にマッピングした後、Falcoは専用の eBPF マップを使用して、この情報をドライバ内の sys_enter および sys_exit トレースポイントに注入します。
Falcoの最新のeBPFプローブは、デフォルトのカーネルモジュールに代わるドライバーです。それがもたらす主な利点は、それが Falco に組み込まれていることであり、それはあなたが何もダウンロードしたりビルドしたりする必要がないことを意味します。もしあなたのカーネルが十分に新しいものであれば、Falco は自動的にそれをインジェクトし、エンドユーザに移植性の向上を提供します。
Windows と Linux におけるカーネルイントロスペクションの扱い方
Windows と Linux のシスコールは、基本的には同じように動作し、ユーザースペースアプリケー ションとオペレーティングシステムのカーネルとの間のインターフェースを提供します。しかし、その実装と使用方法には顕著な違いがあり、それがシステムコールモニタリングツールのバリエーションや、これらの環境におけるeBPFのような技術の採用にもつながっています。ここでは、WindowsとLinuxのシステムコールの明確な違いをいくつか紹介します:
実装とAPIの違い
- Linux:異なるディストリビューション間で一貫したシステムコールセットを使用。Linuxシステムコールは十分に文書化されており、バージョン間で比較的安定しています。
- Windows: Win32 APIコールとして知られるWindowsのシステムコールは、より幅広い機能とレガシーサポートのため、より複雑になる可能性があります。Windows APIには、Windowsアプリケーションを構築するための関数、インターフェース、プロトコルのセットが含まれています。
シスコール呼び出し
- Linux では、システムコールは通常ソフトウェア割り込みを使用して呼び出されます。例えば、Linux プログラムがファイルを読み取る必要がある場合、カーネルのファイル読み取り機能への簡単なインターフェースである read システムコールを直接呼び出します。
- 対照的に、Windowsは同様のメカニズムを使用しますが、さらにAPIのレイヤーを追加することで、基礎となるシステムコールをより大幅に抽象化することができます。例えば、Windowsでは、プログラムはWin32 APIからReadFile関数を使用してファイルを読み取ります。
この関数は、低レベルのシステム・コールと相互作用して処理を実行します。Win32 APIはよりユーザーフレンドリーなインターフェースを提供し、システムコールを直接使用する複雑さを隠します。
シスコール監視ツール
- Linux: Linuxはオープンソースであり、システムコールインターフェースが標準化されているため、システムコール監視ツールの開発と使用が容易です。Linuxのシステムコール監視には、auditd、Sysdig Inspect、eBPFベースのテクノロジーなどのツールが一般的に使用されています。
- Windows: システムコール監視ツールは、Windows APIとカーネルの複雑さと可変性のため、Windowsではあまり一般的ではありません。Windowsはクローズドソースであるため、外部監視ツールの開発も制限されています。ProcmonやSysmonのようなSysinternalsスイートから提供されているツールがいくつかあります。言うまでもなく、どちらもクローズドソースで、マイクロソフト独自のソフトウェアです。しかし、Windowsは、Event Tracing for Windows (ETW)やWindows Management Instrumentation (WMI)のような、監視のためにカーネルの可視性を拡張する独自のツールとAPIのセットを提供しています。
Windowsにおけるユーザー空間フッキング技術の実装
- ProcmonとSysmonに加えて、多くのWindows製品は、システムコールを監視するために、多くの場合、ユーザースペースフッキング技術で補強されたカーネルドライバーを利用します。ユーザースペースフッキングとは、カーネルの外部にあるユーザースペー スで、ソフトウェアコンポーネント間で受け渡されるファンクションコール、メッセージ、イベント を傍受する方法を指します。この技術により、基本的なオペレーティングシステム・カーネルに変更を加えることなく、アプリケーション内の相互作用の監視と操作が可能になります。
- ユーザースペースフッキングは、セキュリティアプリケーション、システムユーティリティ、パフォーマンスモニタリングツールを扱う場合など、カーネルレベルのアクセスが実行不可能であるか、リスクが高すぎるシナリオで特に有用です。ユーザースペースフッキングを活用することで、開発者はアプリケーションの動作に関する貴重なデータを収集したり、セキュリティ対策を強化したり、オペレーティングシステムのコアに深く統合することなく機能を変更したりすることができます。
- このようなアプローチにもかかわらず、Windowsは監視目的のためにカーネルの可視化を促進する独自のツールとAPIのセットも提供しています。ETWとWMIがその代表例です。ETWは詳細なイベントロギングとトレース機能を提供し、診断とパフォーマンス情報の収集を可能にし、一方、WMIは企業環境で管理情報にアクセスするためのフレームワークを提供します。どちらも、カーネル・イントロスペクションの可視性を拡張するのに役立っていますが、しかし、エンドポイント検出ツールが、限定的なシステムの可視性を提供するユーザー空間のフッキング技術に依存している可能性があることは、まだ注目に値します。
WindowsのためのeBPF
eBPF for Windowsイニシアチブは、主にLinux環境で使用されているeBPFの機能をWindowsに導入するために設計された進行中のプロジェクトです。基本的に、このプロジェクトは既存のeBPFツールとAPIをWindowsプラットフォームに統合します。これは、既存のeBPFプロジェクトをサブモジュールとして組み込み、Windows上での操作を可能にする中間レイヤーを作成することによって行われます。
このプロジェクトの主な目標は、異なるオペレーティングシステム間で共通である標準フックとヘルパーを利用するプログラムのソースコードレベルでの互換性を確保することです。要するに、eBPF for Windowsは、もともとLinux用に書かれたアプリケーションがWindowsと互換性を持つことを可能にすることを目的としています。
Linuxは幅広いフックとヘルパーを提供していますが、内部構造に非常に特化したものもあり、他のプラットフォームには移行できない可能性があります。しかし、より一般的なアプリケーションには多くのフックやヘルパーがあり、eBPF for Windowsプロジェクトは、クロスプラットフォームのeBPFプログラムでこれらをサポートすることに重点を置いています。
さらに、プロジェクトはLibbpf APIをWindowsで利用できるようにしています。これは、eBPFプログラムと相互作用するアプリケーションのソースコードの互換性を維持し、eBPFプログラムの開発と実行の面でLinuxとWindows環境のギャップをさらに埋めることを目的としています。
2024年現在、eBPF for Windowsプロジェクトはまだ進行中です。もちろん、Windows eBPFの採用には課題があります。Windows用eBPFのベータステータスは、Linuxシステムで観察されるような広範な普及がまだ見られないことを意味します。課題には、Windowsカーネルアーキテクチャーとの互換性の確保、既存のWindowsセキュリティツールや監視ツールとの統合、Linux中心のeBPFツールチェーンをWindows環境に適応させることなどがあります。
しかし、eBPF for Windowsの実装に成功すれば、Linuxと同様の強力なカーネル・イントロスペクション機能とプログラマビリティ機能をWindows環境にもたらすことができます。これにより、高度なeBPFベースのツールを使用してWindowsシステムを監視し、セキュアにする能力が大幅に強化されます。
WindowsとLinuxにおけるシステムコールの実装と監視方法には本質的な違いがありますが、eBPF for Windowsプロジェクトのような取り組みは、これらのギャップを埋めるための継続的な取り組みです。Linuxの高度な監視機能をWindowsに導入することで、システムセキュリティと管理に新たな可能性が開ける可能性がありますが、それは大きな開発上の課題に直面しています。現在のところ、WindowsはLinuxのシステムコールを解釈することができません。
Windowsのためのカーネル・イントロスペクション
もちろん、Windowsのカーネル・イントロスペクションには別のアプローチもあります。Fibratus.io というプロジェクトは、セキュリティに焦点を当てた Windows カーネルの探索と観測のための最新のツールです。Fibratus はシステムイベントをキャプチャーするために ETW (Event Tracing for Windows) として知られるアプローチを使用します。多くのカーネル開発者は、Windows でカーネルドライバーを構築するプロセスが、認証や品質ラボテストなどに関する様々な厳しい Microsoft の要件のために非常に退屈であることに気づくでしょう。それだけでなく、一般的に、カーネルコードを書くプロセスそのものが、より時間のかかるプロセスであり、単一のカーネルドライバーのクラッシュがシステム全体をクラッシュさせる可能性があります。
Windows用のeBPFの実装は、DDoSミティゲーション用のXDP(Xpress Data Path)のようなネットワークスタックの可観測性のユースケースにやや限定されているためです。ETWはWindowsオペレーティングシステムに実装され、開発者に高速で信頼性が高く、パフォーマンスにほとんど影響を与えない多機能なイベントトレース機能を提供します。コンピュータを再起動したり、アプリケーションやドライバーをリロードすることなく、動的にトレースを有効または無効にすることができます。開発中にコードに追加するデバッグステートメントとは異なり、 プロダクションコードでETWを使用することができます。Linux システムで言及した syscall アプローチと同様に、ETW はユーザーモードアプリケーションやカーネルモードドライバによって発生するイベントをトレースし、ログに記録するメカニズムを提供します。
カーネル・イントロスペクション – まとめ
Windows セキュリティベンダーは、通常、自社のエンドポイント検出および対応(EDR)製品の内部動作について、機密性を保持します。しかし、これらの製品の多くは、カーネルドライバーやEvent Tracing for Windows(ETW)フレームワークを活用し、時にはユーザースペースフッキング技術で補完していることは広く知られています。具体的な方法論や実装は、独占的な技術に対する業界の規範に沿うように、しばしば非公開のままです。
Linuxカーネルにルーツを持つ技術であるeBPFのWindows環境への導入は、重要かつ有望な発展です。カーネルを再起動することなく、動的にプログラムをロードしたりアンロードしたりできる機能は、大きな進歩です。この機能はシステム管理を非常に容易にし、ライブ環境でのデバッグや問題解決をより効率的に行えるようにします。WindowsにおけるeBPFの段階的な展開は、より柔軟で強力なシステム診断と管理ツールへの一歩を意味し、Linuxシステムで長年利用されてきた先進的な機能の一部を反映したものです。この進化は、LinuxとWindowsの運用パラダイムとツールセットの継続的な収束を反映しており、複雑なプロダクショングレードのアプリケーションにおけるWindowsシステムの機能と実用性を強化しています。