Spectre-v2の再燃:JITエンジンを狙うBTR攻撃の概要

数年前に大きな話題となったSpectre脆弱性が、再び開発者の間で注目を集めています。今回、VUSecの研究者たちが発表したのは「Branch Target Reuse(BTR)」と名付けられた新たなSpectre-v2攻撃手法です。この攻撃は、Webブラウザ、言語ランタイム、さらにはOSカーネル内で使用されるJust-In-Time(JIT)コンパイラを標的としています。

モダンCPUがコードの自己変更後にアーキテクチャ上のコード整合性を回復しても、古い間接分岐予測エントリ(すなわち分岐ターゲット)が必ずしも無効化されない点が、この攻撃の鍵となります。(出典)

BTR攻撃の核心は、JITエンジンがコードキャッシュを再利用する際、古い分岐予測エントリが残存し、投機的実行時に悪用される可能性がある点です。これにより、攻撃者は投機的な制御フローをハイジャックし、機密データを漏洩させる恐れがあります。

BTR攻撃の具体的なメカニズム

BTR攻撃のメカニズムは、以下のステップで説明されます。

  1. トレーニングチャンクの割り当てと分岐の訓練: 攻撃者はJITエンジンに新しいコードセクション(トレーニングチャンク)を割り当てさせ、間接分岐を訓練します。
  2. トレーニングチャンクの解放とターゲットチャンクの割り当て: 次に、攻撃者はトレーニングチャンクの解放を強制し、そのアドレスの一部を再利用するターゲットチャンクを割り当てさせます。
  3. 古い分岐ターゲットの再利用: 攻撃者が再び間接分岐をトリガーすると、CPUは古くなった分岐ターゲットバッファ(BTB)エントリを使用し、投機的に古いトレーニングチャンクのエントリポイントにジャンプします。

これにより、制御フローがハイジャックされ、秘密データが漏洩する可能性があります。これは「投機的なuse-after-free」プリミティブと表現されており、ソフトウェアによる強化策を迂回したり、不適切な配置のガジェットに到達したりすることが可能になります。

Linux cBPFとSpiderMonkeyでの実証済み攻撃

研究者らは、このBTR攻撃をLinuxカーネルのcBPF(classic BPF)とFirefoxブラウザのSpiderMonkey(JavaScriptおよびWebAssemblyエンジン)で実証しました。

項目 Linux cBPF SpiderMonkey
攻撃対象 Linuxカーネル FirefoxブラウザのJavaScript/WebAssemblyエンジン
影響 任意のメモリからの情報漏洩 投機的な任意のコード実行
緩和策の回避 bpf_jit_hardenオプション(定数ブラインド)をバイパス WebAssemblyの定数プールを悪用
データ漏洩速度 毎秒8バイト(Intel CPU上で) 未公表(PoCを構築し、攻撃が実行可能であることを確認)

Linux cBPFに対する攻撃では、現代のIntel CPU上で、すべての緩和策をバイパスして毎秒 8バイト の速度で任意のメモリからデータを漏洩させることに成功しています。デモでは、suプロセスからrootパスワードハッシュを抜き出す様子が示されています。これは一見遅いように見えますが、ポインタチェイシングを駆使することで、必要な機密情報に到達するためには少量のデータで十分であると説明されています。

SpiderMonkeyにおいても、WebAssemblyのf64.constのような命令が定数を実行可能コードバッファ内のリテラルプールに保存する性質を悪用し、投機的にそのプールにジャンプすることで「投機的な任意のコード実行」を可能にすることを確認しています。

JITを利用するシステム全体のセキュリティ強化が課題

BTR攻撃は、既存のSpectre緩和策をバイパスする新たな手法として、JITエンジンを標的にしている点が特徴です。これにより、Webブラウザ、言語ランタイム、OSカーネルといった、現代のソフトウェアスタックの基盤となる多くのコンポーネントが影響を受ける可能性があります。特に、Webアプリケーション開発者にとっては、ブラウザのJavaScriptエンジンが攻撃対象となるため、ユーザーの機密情報保護の観点から、より一層の注意が求められます。

この脆弱性への対応は、CPUベンダーによるマイクロコードアップデート、OSベンダーによるカーネルパッチ、そしてブラウザや言語ランタイムの開発者によるJITコンパイラの改善など、多岐にわたる協調が不可欠となるでしょう。パフォーマンスとセキュリティのトレードオフの中で、いかに効果的な緩和策を導入できるかが、今後の大きな課題になると考えます。また、サイト隔離のようなセキュリティ機能のさらなる普及も、この種の攻撃に対する防御力を高める上で重要になるのではないでしょうか。

エンジニア目線で見ると:JIT利用環境での全面的な見直しが必要か

今回のBTR攻撃は、JITコンパイラを利用している全ての開発者にとって、かなり衝撃的なニュースです。PythonやTypeScriptをメインで書いている私にとっても、JavaScriptエンジンやWebAssemblyエンジンのセキュリティは無視できない領域です。特に、Webブラウザのような信頼性の低いコードを実行する環境では、この種の投機的実行脆弱性は常に頭を悩ませる問題だと感じます。

毎秒8バイトという漏洩速度は、確かに高速ではありません。しかし、研究者も指摘しているように、ターゲットを絞ったポインタチェイシングによって、例えば機密性の高いAPIキーやセッション情報のような、小さなデータ塊であれば十分に窃取できる可能性を秘めています。

GCPのCloud Runで動かすようなアプリケーションでも、内部でJITコンパイルされる言語ランタイムを使っていれば、理論的には攻撃対象になりうるのではないでしょうか。また、ローカルでLLMを動かす際、WebUIがJITコンパイラを使う場合もあるので、そうした環境でも注意が必要かもしれません。

この問題は、特定のCPUベンダーに限定されず、複数のCPUベンダーに影響を与えるとされています。これまでのSpectreやMeltdownの経験から、ファームウェアのアップデートだけでなく、ソフトウェアレベルでの緩和策も必要になるでしょう。

既存のコードやインフラでJITを多用している場合、パフォーマンスへの影響を考慮しつつ、セキュリティ対策の見直しを迫られる可能性が高いと感じます。特に、サンドボックス環境や隔離機構が十分でないと、影響はより大きくなるのではないでしょうか。