Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2026-8389 — Analyse technique et exploit de preuve de concept pour CVE-2026-8389, une vulnérabilité de confusion de types dans SpiderMonkey BaselineJIT de Firefox, démontrée avec une troncature de bytecode et une manipulation de déroulement d'exceptions. | Kitploit
Outils/GitHubGitHub/crixpwn/cve-2026-8389
Analyse des VulnérabilitésExploitationExploitation d'Applications WebCTFApprentissage et ÉducationExploitation de Binaires
GitHubcrixpwn/cve-2026-8389

CVE-2026-8389

Analyse technique et exploit de preuve de concept pour CVE-2026-8389, une vulnérabilité de confusion de types dans SpiderMonkey BaselineJIT de Firefox, démontrée avec une troncature de bytecode et une manipulation de déroulement d'exceptions.

Voir le dépôt
407il y a 2 moisVérifié par Kitploit

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

CVE-2026-8389

Cette vulnérabilité était destinée à être utilisée lors du Pwn2Own 2026 Berlin, mais a été corrigée dans la version 150.0.3.

Truncature du champ de bits pcOffset de SpiderMonkey BaselineJIT sur le chemin de compilation de base hors thread précoce, conduisant à un pc de bytecode erroné mais dans les limites lors du déroulement d'exception et à une confusion de type subséquente.

Résumé

RetAddrEntry stocke le décalage du bytecode pcOffset_ comme un champ de bits de 28 bits. La constante BaselineMaxScriptLength = 0x0fffffff définie dans le même en-tête est dimensionnée pour correspondre exactement à cette plage de champs de bits.

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

Avant le correctif, cette limite supérieure n'était appliquée dans les versions release qu'à l'intérieur de CanEnterBaselineJIT (js/src/jit/BaselineJIT.cpp), qui est le chemin d'entrée du thread principal pour le warmup / OSR. Le chemin de compilation de base hors thread précoce ne passait pas par cette vérification, donc un script dont le bytecode dépasse 256 Mo pouvait effacer la compilation de base tandis que son pcOffset était silencieusement tronqué par le stockage sur 28 bits (pcOffset & 0x0FFFFFFF). Les deux MOZ_ASSERT informatifs ci-dessus (pcOffset_ == pcOffset et pcOffset <= BaselineMaxScriptLength) sont des no-op dans les versions release, donc la troncature n'a pas été détectée.

Chemin affecté

Le chemin de compilation de base hors thread précoce :

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

Avant le correctif, MaybeDoEagerBaselineCompilations ne filtrait que sur script->baselineDisabled() et jit::CanBaselineInterpretScript(script). Aucun ne valide la longueur du script, donc un script trop long atteignait la compilation de base via ce chemin.

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

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

En revanche, le chemin du thread principal appliquait la limite (ce bloc a ensuite été déplacé dans le partagé CanBaselineCompileScript) :

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

Conséquence

Le pcOffset tronqué est reconverti en pointeur de bytecode dans JSJitFrameIter::baselineScriptAndPc, via 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_);
}

Ce pc est transmis au gestionnaire d'exceptions HandleExceptionBaseline. Comme le décalage tronqué est plus petit que la longueur réelle du script, offsetToPC renvoie un pc dans les limites mais incorrect, donc l'échec est silencieux plutôt qu'un crash évident hors limites.

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

Ce mauvais pc entraîne une correspondance incorrecte des notes try lors du déroulement d'exception (HandleExceptionBaseline est basé sur script->trynotes()), conduisant à une lecture incorrecte d'un emplacement de pile. Un emplacement qui n'est pas un JSObject* peut alors être traité comme tel et distribué via sa vtable, produisant une confusion de type qui est la base pour une exploitation ultérieure.

Télécharger l’outil