はじめに
「FlipSwitch」と名付けられた新しいルートキットフッキング手法が登場し、最新のLinux 6.9カーネルのディスパッチ防御を回避し、カーネルレベルの侵害に関する懸念を再燃させています。この手法は、非推奨となったsys_call_table
ではなく、新しいシステムコールディスパッチャの機械語コードを操作することで、システムコールフッキングの古典的な力を取り戻し、kill
やgetdents64
などの重要なシステムコールをステルス的に傍受することを可能にします。
従来のルートキットとLinux 6.9の変更
長年にわたり、DiamorphineやPUMAKITのようなLinuxルートキットは、関数ポインタの単純な配列であるsys_call_table
を悪用して、システムコールを攻撃者制御下の関数にリダイレクトしていました。これにより、悪意のあるファイルをls
の出力から隠したり、プロセスの終了試行を阻止したりすることができました。
しかし、Linuxカーネル6.9のリリースは、このアプローチに致命的な打撃を与えました。カーネルは、直接的な配列ルックアップ(例: sys_call_table[__NR_kill](regs);
)を、x64_sys_call
内のswitch
文ディスパッチに置き換えました。これにより、実際のシステムコール処理においてsys_call_table
への変更は事実上無視されるようになりました。
FlipSwitchの革新的なアプローチ
FlipSwitchの重要な洞察は、元のシステムコールロジックがswitch
文の背後にコンパイルされた形で依然として存在するという点です。FlipSwitchは、sys_call_table
を改ざんする代わりに、x64_sys_call
内でターゲットのシステムコール関数を呼び出す機械レベルのcall
命令を特定し、パッチを適用します。このプロセスは以下の4つの段階で展開されます。
- 元の関数アドレスの発見:
sys_call_table
は互換性のために有効なポインタを保持しているため、sys_call_table[__NR_kill]
のようなエントリを読み取ることで、元のsys_kill
ルーチンのアドレスを取得します。 kallsyms_lookup_name
の特定: カーネルシンボルをプログラム的に見つけるために、FlipSwitchは既知のシンボルにkprobeを使用し、kallsyms_lookup_name
のアドレスを抽出します。これにより、直接的なエクスポート制限を回避して、エクスポートされた任意のシステムコール関数ポインタをルックアップできます。- 固有の呼び出し命令のスキャン:
x64_sys_call
関数の機械語コードは、1バイトのオペコード0xe8
と、sys_kill
をターゲットとする正確な4バイトの相対オフセットが続くパターンをバイトごとに検索されます。この単一のシグネチャが、ハイジャックする正確な命令を特定します。 - ディスパッチャのパッチ適用: リング0で動作するFlipSwitchは、CR0レジスタのWPビットをクリアすることでCPUの書き込み保護を無効にします。その後、特定された
call
命令の4バイトオフセットを、悪意のあるfake_kill
ハンドラを指すように上書きします。モジュールのアンロード時には、保護が再有効化され、元のオフセットが復元されるため、フォレンジックな痕跡は最小限に抑えられます。
影響と防御戦略
FlipSwitchは、カーネルの強化と攻撃者の革新との間の絶え間ないいたちごっこを浮き彫りにします。Linux開発者がシステムコールディスパッチを強化し続ける一方で、攻撃者はコンパイルされたディスパッチロジック自体を標的にすることで適応しています。緩和策としては、以下のようなものが考えられます。
- ランタイム整合性検証:
x64_sys_call
の機械語コードを定期的にハッシュ化し、検証することで、不正な変更を検出します。 - Kprobe制限の強化: 重要なシンボルアドレスを特定するためのkprobeの使用をさらに制限または監査します。
- 制御フロー整合性 (CFI): カーネル内でCFI技術を採用し、すべての間接呼び出しが正当なターゲットと一致するように強制します。
YARAによるFlipSwitchの検出
カーネルの制御フローを可視化し、シグネチャベースの検出を活用することは、Linuxカーネルの整合性をめぐる継続的な戦いで優位に立つために不可欠です。カーネルレベルのルートキットの検出は、そのステルス的なインメモリ操作のため、依然として困難です。防御者を支援するため、Elastic SecurityはFlipSwitchの概念実証を標的とするYARAルールを公開しました。このルールは、パッチ適用プロセス中に導入される固有の機械語パターンをスキャンします。
rule Linux_Rootkit_Flipswitch_821f3c9e { meta: author = "Elastic Security" description = "Detect FlipSwitch rootkit PoC" os = "Linux" arch = "x86" strings: $all_a = { FF FF 48 89 45 E8 F0 80 ?? ?? ?? } $main_b = { 41 54 53 E8 ?? ?? ?? ?? 48 C7 C7 ?? ?? ?? ?? } condition: #all_a >= 2 and 1 of ($main_b) }
このルールをメモリ・スキャン・ツールやエンドポイント保護プラットフォームに展開することで、セキュリティチームはFlipSwitchによってパッチが適用されたディスパッチャの存在を検出し、重大な損害が発生する前に対処することができます。
結論
カーネル防御が進化するにつれて、FlipSwitchのような研究は、多層防御とプロアクティブな監視が、Linuxカーネルの整合性を保護するための継続的な戦いにおいて極めて重要であることを強調しています。