Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2026-8389 — CVE-2026-8389の技術的分析および概念実証エクスプロイト。FirefoxのSpiderMonkey BaselineJITタイプ混同脆弱性に対するもので、バイトコードの切り詰めと例外アンワインド操作を用いて実証されています。 | Kitploit
ツール/GitHubGitHub/crixpwn/cve-2026-8389
脆弱性分析エクスプロイトウェブアプリケーション悪用CTF学習と教育バイナリエクスプロイト
GitHubcrixpwn/cve-2026-8389

CVE-2026-8389

CVE-2026-8389の技術的分析および概念実証エクスプロイト。FirefoxのSpiderMonkey BaselineJITタイプ混同脆弱性に対するもので、バイトコードの切り詰めと例外アンワインド操作を用いて実証されています。

リポジトリを見る
40723ヶ月前Kitploit レビュー済み

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

CVE-2026-8389

この脆弱性はPwn2Own 2026 Berlinで使用される予定でしたが、バージョン150.0.3でパッチが当てられました。

SpiderMonkey BaselineJITのpcOffsetビットフィールドが、eager off-thread baseline-compileパスで切り詰められ、例外アンワインディング中に範囲内だが間違ったバイトコードpcを引き起こし、その後の型混乱に至る。

概要

RetAddrEntryはバイトコードオフセットpcOffset_を28ビットのビットフィールドとして格納します。同じヘッダーで定義されている定数BaselineMaxScriptLength = 0x0fffffffは、そのビットフィールドの範囲に正確に一致するサイズです。

root@kitploit:~
// js/src/jit/BaselineJIT.h:73
static constexpr uint32_t BaselineMaxScriptLength = 0x0fffffffu;

// js/src/jit/BaselineJIT.h:100-105
class RetAddrEntry {
  // Offset from the start of the JIT code where call instruction is.
  uint32_t returnOffset_;

  // The offset of this bytecode op within the JSScript.
  uint32_t pcOffset_ : 28;
root@kitploit:~
// js/src/jit/BaselineJIT.h:141-156 (RetAddrEntry constructor)
RetAddrEntry(uint32_t pcOffset, Kind kind, CodeOffset retOffset)
    : returnOffset_(uint32_t(retOffset.offset())),
      pcOffset_(pcOffset),
      kind_(uint32_t(kind)) {
  MOZ_ASSERT(returnOffset_ == retOffset.offset(),
             "retOffset must fit in returnOffset_");

  // The pc offset must fit in at least 28 bits, since we shave off 4 for
  // the Kind enum.
  MOZ_ASSERT(pcOffset_ == pcOffset);
  static_assert(BaselineMaxScriptLength <= (1u << 28) - 1);
  MOZ_ASSERT(pcOffset <= BaselineMaxScriptLength);

  MOZ_ASSERT(kind < Kind::Invalid);
  MOZ_ASSERT(this->kind() == kind, "kind must fit in kind_ bit field");
}

修正前、この上限はリリースビルドではCanEnterBaselineJIT(js/src/jit/BaselineJIT.cpp)内でのみ強制されていました。これはウォームアップ/OSRメインスレッドのエントリパスです。eager off-thread baseline-compileパスはこのチェックを通過しなかったため、バイトコードが256MBを超えるスクリプトは、pcOffsetが28ビットストア(pcOffset & 0x0FFFFFFF)によって暗黙的に切り詰められても、ベースラインコンパイルをクリアできました。上記の2つの情報提供用MOZ_ASSERT(pcOffset_ == pcOffsetおよびpcOffset <= BaselineMaxScriptLength)はリリースビルドではノーオペレーションであるため、切り詰めは検出されませんでした。

影響を受けるパス

eager off-thread baseline-compileパス:

root@kitploit:~
CompilationStencil::instantiateStencils
  -> MaybeDoEagerBaselineCompilations        (js/src/frontend/Stencil.cpp:2720)
    -> DispatchOffThreadBaselineBatchEager    (js/src/jit/BaselineJIT.cpp:386)
      -> BaselineCompileTask::runTask         (js/src/jit/BaselineCompileTask.cpp:69)
        -> BaselineCompile

パッチ前、MaybeDoEagerBaselineCompilationsはscript->baselineDisabled()とjit::CanBaselineInterpretScript(script)のみでゲートされていました。どちらもスクリプト長を検証しないため、長すぎるスクリプトがこのパスを通じてベースラインコンパイルに到達しました。

root@kitploit:~
// js/src/frontend/Stencil.cpp, MaybeDoEagerBaselineCompilations (pre-patch)
    if (script->baselineDisabled()) {
      continue;
    }

    if (!jit::CanBaselineInterpretScript(script)) {
      continue;
    }

対照的に、メインスレッドパスはバインドを強制していました(このブロックは後で共有のCanBaselineCompileScriptに移動されました)。

root@kitploit:~
// js/src/jit/BaselineJIT.cpp, CanEnterBaselineJIT (pre-patch)
  if (script->length() > BaselineMaxScriptLength) {
    script->disableBaselineCompile();
    return Method_CantCompile;
  }

結果

切り詰められたpcOffsetは、JSJitFrameIter::baselineScriptAndPc内で、RetAddrEntry::pc -> JSScript::offsetToPCを経由してバイトコードポインタに変換されます。

root@kitploit:~
// js/src/jit/JSJitFrameIter.cpp:155-160
  // address.
  uint8_t* retAddr = resumePCinCurrentFrame();
  const RetAddrEntry& entry =
      script->baselineScript()->retAddrEntryFromReturnAddress(retAddr);
  *pcRes = entry.pc(script);
}
root@kitploit:~
// js/src/jit/BaselineJIT.h:162-164 (RetAddrEntry::pc)
jsbytecode* pc(JSScript* script) const {
  return script->offsetToPC(pcOffset_);
}

そのpcは例外ハンドラHandleExceptionBaselineに渡されます。切り詰められたオフセットは実際のスクリプト長より小さいため、offsetToPCは範囲内だが間違ったpcを返すので、明らかな範囲外クラッシュではなく、静かに失敗します。

root@kitploit:~
// js/src/jit/JitFrames.cpp:584-591
static void HandleExceptionBaseline(JSContext* cx, JSJitFrameIter& frame,
                                    CommonFrameLayout* prevFrame,
                                    ResumeFromException* rfe) {
  MOZ_ASSERT(frame.isBaselineJS());
  MOZ_ASSERT(prevFrame);

  jsbytecode* pc;
  frame.baselineScriptAndPc(nullptr, &pc);

その間違ったpcは、例外アンワインディング中に誤ったtry-noteマッチングを引き起こし(HandleExceptionBaselineはscript->trynotes()をキーとします)、誤ったスタックスロット読み取りにつながります。JSObject*ではないスロットがJSObject*として扱われ、そのvtableを介してディスパッチされ、さらなる悪用の基礎となる型混乱を生み出します。

ツールをダウンロード