
CVE-2024-29943、ただしwasmを使用
CVE-2024-29943 のエンドツーエンドのエクスプロイトチェーンであり、シェルコードをSpiderMonkeyのWebAssembly JITコードページに f64.const の即値として密輸することで、任意のネイティブコード実行を実現します — ROPも VirtualProtect も外部ツールチェーンも不要です。
2024-03-20のmozilla-centralナイトリービルド(JavaScript-C126.0a1、linux x86-64、修正前)のSpiderMonkeyシェルに対して動作確認済み:チェーンは最後まで実行され、ペイロードが実行されます(write(1, "PWNED by wasm!\n"); exit(0))。
CVE-2024-29943は、Pwn2Own 2024でManfred Paulによって使用された、セキュリティ上重大なIonMonkeyの範囲解析バグであり、Firefox < 124.0.1に影響します(Bugzilla 1886849、CVSS 9.8)。
MObjectKeysLength::computeRange は、Object.keys が省略可能にされた後(バグ1845728によるリグレッション)、Object.keys(x).length に対して誤った整数範囲を返していました。Ionの範囲解析は、ループカウンタが負にならないと結論付け、依然として到達可能な境界チェックを除去し、Uint8Array に対する範囲外の読み取り/書き込みを引き起こしました。
Object.keys 範囲解析バグ -> Uint8Array に対する OOB r/w
-> 隣接する ArrayBuffer を破壊 -> addrof / fakeobj / 任意 R/W
-> 手作り WASM モジュールをインスタンス化(シェルコードを f64.const 即値として)
-> WasmInstanceObject -> wasm::Instance -> wasm::Code -> CodeTier
-> ModuleSegment.bytes_(JIT コードページ、RX)
-> ページ内のマーカー定数をスキャン
-> FuncExport.eagerInterpEntryOffset_(通常のヒープ)を
ページ内のシェルコードのオフセットで上書き
-> インタプリタ経由でエクスポートを呼び出す -> ペイロードが実行される
2つの詳細は、それぞれを学ぶのにセグメンテーションフォールトを1回ずつ犠牲にしたので、書き留めておきます:
FuncExport の eagerInterpEntryOffset_ を上書きすることで行われます — インタプリタは codeBase + offset を計算してそこへジャンプします。WASM-JITページシェルコード技術はWasmBlazeFoxによるものです。このリポジトリは、その技術が元の2018年のトレーニングバグの代わりに、現代的で出荷されているブラウザのバグと組み合わせて機能することを実証しています。
poc.js — 範囲解析バグの最小トリガー。exploit.js — 完全なチェーン:プリミティブ + WASM JITシェルコードステージ。gen_wasm.py — シェルコードを埋め込んだWASMモジュールをアセンブルし、定数のラウンドトリップを検証します。別のペイロードを使用するには python3 gen_wasm.py mysc.bin。デフォルトのペイロードは純粋なシステムコールによる write(1, "PWNED by wasm!\n"); exit(0) のプルーフで、シンボル解決を必要としません(そのためベアjsshellでも動作します)。古典的なlibxulベースの system("gnome-calculator") ペイロードについては、WasmBlazeFox ex6を参照してください。test.gdb — 特定のビルドでオブジェクトモデルのオフセットを導出するためのブレークポイントと ptype /o ヘルパー。afbdf6822c9e9f9b6d44b9ea6904cb10878126b1(Firefox ~124、124.0.1以前)をLinux x86-64でビルドする — または修正前のナイトリーjsshellを入手する。例:archive.mozilla.org/pub/firefox/nightly/2024/03/2024-03-20-21-16-35-mozilla-central/jsshell-linux-x86_64.zip。LD_LIBRARY_PATH=<jsshell dir> ./js --no-threads --ion-offthread-compile=off \
--spectre-mitigations=off poc.js # トリガーのみ(セグメンテーションフォールト)
LD_LIBRARY_PATH=<jsshell dir> ./js --no-threads --ion-offthread-compile=off \
--spectre-mitigations=off exploit.js # 完全なチェーン("PWNED by wasm!")
--spectre-mitigations=off が必要なのは、境界チェックの除去がインデックスマスキングが無効であることに依存しているためです(Bugzillaのコメントを参照)。
f64.const 即値がコードセグメント内にインラインで出力されます。Ionコンパイルはそれらを定数畳み込みする可能性があります。WASM_INSTANCE_OFF_CODE = 0xa8、MetadataTier.funcExports + 448、FuncExport + 8 など)は、脆弱なコミットのヘッダーから導出され、2024-03-20のナイトリーjsshellに対して確認されました。他のビルドでは test.gdb で再導出してください。