Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
CVE-2026-8389 — Analisi tecnica e proof-of-concept exploit per CVE-2026-8389, una vulnerabilità di type confusion in SpiderMonkey BaselineJIT di Firefox, dimostrata con troncamento del bytecode e manipolazione dello svolgimento delle eccezioni. | Kitploit
Strumenti/GitHubGitHub/crixpwn/cve-2026-8389
Analisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebCTFApprendimento e FormazioneBinary Exploitation
GitHubcrixpwn/cve-2026-8389

CVE-2026-8389

Analisi tecnica e proof-of-concept exploit per CVE-2026-8389, una vulnerabilità di type confusion in SpiderMonkey BaselineJIT di Firefox, dimostrata con troncamento del bytecode e manipolazione dello svolgimento delle eccezioni.

Vedi Repository
4072 mesi faRevisionato da Kitploit

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

CVE-2026-8389

Questa vulnerabilità era destinata a essere utilizzata al Pwn2Own 2026 Berlin, ma è stata corretta nella versione 150.0.3.

SpiderMonkey BaselineJIT: troncamento del bitfield pcOffset nel percorso di baseline-compile eager off-thread, che porta a un pc bytecode errato ma entro i limiti durante lo svolgimento delle eccezioni e una successiva confusione di tipo.

Sommario

RetAddrEntry memorizza l'offset del bytecode pcOffset_ come un bitfield a 28 bit. La costante BaselineMaxScriptLength = 0x0fffffff definita nello stesso header è dimensionata per corrispondere esattamente a quell'intervallo di bitfield.

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");
}

Prima della correzione, questo limite superiore veniva applicato nelle build di rilascio solo all'interno di CanEnterBaselineJIT (js/src/jit/BaselineJIT.cpp), che è il percorso di riscaldamento/OSR del thread principale. Il percorso di baseline-compile eager off-thread non passava attraverso quel controllo, quindi uno script il cui bytecode supera 256 MB poteva completare la baseline compilation mentre il suo pcOffset veniva silenziosamente troncato dal store a 28 bit (pcOffset & 0x0FFFFFFF). I due MOZ_ASSERT informativi sopra (pcOffset_ == pcOffset e pcOffset <= BaselineMaxScriptLength) sono no-op nelle build di rilascio, quindi il troncamento passava inosservato.

Percorso interessato

Il percorso di baseline-compile eager off-thread:

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

Prima della patch, MaybeDoEagerBaselineCompilations bloccava solo su script->baselineDisabled() e jit::CanBaselineInterpretScript(script). Nessuno dei due convalida la lunghezza dello script, quindi uno script troppo lungo raggiungeva la baseline compilation attraverso questo percorso.

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

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

Al contrario, il percorso del thread principale applicava il limite (questo blocco è stato successivamente spostato nel CanBaselineCompileScript condiviso):

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

Conseguenza

Il pcOffset troncato viene riconvertito in un puntatore a bytecode in JSJitFrameIter::baselineScriptAndPc, tramite 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_);
}

Tale pc viene passato al gestore di eccezioni HandleExceptionBaseline. Poiché l'offset troncato è più piccolo della lunghezza reale dello script, offsetToPC restituisce un pc errato ma entro i limiti, quindi il fallimento è silenzioso anziché un evidente crash fuori dai limiti.

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);

Quel pc errato guida un'errata corrispondenza try-note durante lo svolgimento delle eccezioni (HandleExceptionBaseline si basa su script->trynotes()), portando a una lettura errata di uno slot dello stack. Uno slot che non è un JSObject* può quindi essere trattato come tale e inviato attraverso la sua vtable, producendo una confusione di tipo che è la base per ulteriori sfruttamenti.

Scarica lo strumento