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-84118-who-labeled-the-crit-as-a-high — Preuve de concept pour CVE-2026-84118, une utilisation après libération du ramasse-miettes (GC) de SpiderMonkey menant à une lecture/écriture hors limites et à une exécution de code potentielle. Inclut un déclencheur SEGV déterministe et des recherches sur l'escalade vers une lecture arbitraire et la neutralisation de l'ASLR. | Kitploit
Outils/GitHubGitHub/sneakynachos/cve-2026-84118-who-labeled-the-crit-as-a-high
Criminalistique MémoireAnalyse des VulnérabilitésExploitationSécurité WebExploitation de Binaires
GitHubsneakynachos/cve-2026-84118-who-labeled-the-crit-as-a-high

CVE-2026-84118-who-labeled-the-crit-as-a-high

Voir le dépôt

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 →

À propos

Preuve de concept pour CVE-2026-84118, une utilisation après libération du ramasse-miettes (GC) de SpiderMonkey menant à une lecture/écriture hors limites et à une exécution de code potentielle. Inclut un déclencheur SEGV déterministe et des recherches sur l'escalade vers une lecture arbitraire et la neutralisation de l'ASLR.

1il y a 11 heuresPas encore vérifié
Partager

CVE-2026-84118 — Use-after-free du GC SpiderMonkey (Bug 2057457)

C'est l'un de ces cas où Mozilla a qualifié de « High » une faille « Critical ». Donc si c'est le cas, quelqu'un voudra peut-être aller demander à Firefox de mettre à jour le paiement des chasseurs de bugs d'origine.

EN BREF : Vous pouvez réaliser une primitive de lecture hors limites (OOB R) sur un pointeur contrôlé, puis commencer à monter et descendre à partir de ce pointeur. Donc si vous pointez le pointeur contrôlé vers un tableau, félicitations, vous pouvez faire des choses amusantes.

Le POC ne contient que la partie SEGV, le reste est une aventure amusante qui consiste à pointer dans un tableau et à sauter dans le WASM de votre choix.

Preuve de concept déterministe de SEGV en build release pour Firefox/SpiderMonkey 154.0.1. Corrigé dans la 155 (refonte d'AtomMarking). Sévérité Mozilla : HIGH.

Exécution du PoC

root@kitploit:~
/path/to/release/js poc.js

Reproduit sur 154.0.1 : 3/3 sur un shell optimisé simple (SIGSEGV, exit 139), 5/5 sur un shell release+gczeal, faute identique à chaque exécution :

root@kitploit:~
SEGV à l'adresse 0x000000000014 (READ)
JS::shadow::Zone::gcState()  <- zone == nullptr, offset +0x14

Cause racine

La 154 confond les bitmaps de marquage des atomes par zone avec le suivi des références. Un Symbole détenu uniquement faiblement — ici, capturé comme champ Value faible à l'intérieur d'un stub IC CacheIR Baseline — et référencé depuis une zone non collectée n'est jamais re-marqué lorsque la zone des atomes est collectée lors d'un GC limité à une zone. Le résultat est une arête obsolète vers une cellule balayée/relocalisée.

Le coup fatal en build release est un second bug statique : MightBeForwarded<JS::Symbol> est codé en dur à false, donc IsForwarded renvoie false sans vérifier (gc/Marking-inl.h:92-97) et chaque chemin de correction de pointeur qui en dépend ignore silencieusement l'arête. Lorsque la zone des atomes est compactée, les arêtes fortes sont mises à jour correctement, mais cette arête CacheIR faible reste définitivement pendante à l'ancienne adresse du Symbole victime. (Les builds debug la détectent comme Assertion failure: !t->isForwarded(), gc/Marking-inl.h:94.)

Comment le PoC transforme l'arête pendante en SEGV

Le PoC ne se contente pas de laisser un pointeur obsolète vers un tas réutilisable — il fait munmapper la page sous-jacente, de sorte que la toute prochaine déréférence provoque une faute.

  1. Isolation des chunks par zone. Les pools de chunks GC sont par zone (Zone::availableChunks/fullChunks), donc les chunks de la zone des atomes ne contiennent que des arènes de la zone des atomes. Le sort d'un chunk peut être contrôlé purement par les durées de vie des atomes/symboles.
  2. Grooming du tas. 300 Symboles « aimants » (maintenus vivants) occupent un chunk précoce et servent de destination de compaction. 150 000 Symboles jetables remplissent ensuite ~4 nouveaux chunks de 1 Mo, de sorte que le Symbole victime atterrit au milieu du spray dans un chunk ne contenant que des symboles de spray condamnés.
  3. La danse du symbole faiblement détenu (lignes 21-31, fragile au niveau du bytecode — doit rester verbatim) : c.eval(b) fait capturer le Symbole par l'IC d'appel de niveau supérieur dans un champ de stub faible ; b = undefined supprime la dernière racine forte ; le spray est supprimé ; deux GC limités à une zone (gc("zone"), schedulezone(c) + schedulezone("") + gc("zone") — la chaîne vide planifie la zone des atomes) balayent le spray mort, compactent la victime dans l'arène des aimants, sautent la correction de l'arête faible, et libèrent l'arène de la victime. Son chunk est désormais complètement vide.
  4. munmap. gcparam("minEmptyChunkCount", 0) rend chaque chunk vide expirable ; pendant , la BackgroundDecommitTask exécute -> -> — un véritable munmap du chunk de la victime. (La désactivation au niveau de l'arène n'est que — des zéros lisibles — la libération de chunk entier est le seul chemin munmap, c'est pourquoi l'isolation des chunks à l'étape 1 est importante.)

Au-delà du crash de page nulle

Ce n'est pas qu'un simple DoS. Escalades démontrées (PoCs et journaux dans les répertoires de recherche GC-NDAY/ et CHAIN/) :

  • Adresse de faute choisie par l'attaquant (segv9) : après le munmap, un basculement de semi-espace minorgc() fait réclamer l'AV libéré par la nursery ; un spray brut de doubles denses écrit un qword d'attaquant sur le champ zone de l'en-tête d'arène obsolète. Le balayage déréférence alors attacker_ptr + 0x14 — déterministe 3/3 à 0x424242424256.
  • Contrôle du verdict + lectures répétables : la valeur chargée sélectionne le verdict de vivacité de l'arête faible ; un verdict « LIVE » conserve l'arête pendante et la déréférence à nouveau lors de chaque GC majeur ultérieur (lectures choisies par l'attaquant
    • un oracle observable par script d'1 bit). Un verdict « DEAD » s'auto-répare.
  • Chaîne de deux bugs : un vrai js::Zone* divulgué via un canal secondaire spéculatif distinct a été planté via ce réapprovisionnement ; le collecteur a consommé les métadonnées d'arène forgées sans faute (une plantation de contrôle perturbée d'1 bit crashe), démontrant la composition contournement-d'ASLR -> plantation-UAF.
  • Négatif borné : le fakeobj direct via cette famille de stubs est architecturalement bloqué — la compaction corrige correctement les arêtes fortes, seules les arêtes faibles pendent, et leurs consommateurs de balayage sont uniquement des branches.
Télécharger l’outil
sleep(0.5)
expireEmptyChunkPool
FreeChunkPool
UnmapPages
madvise(MADV_DONTNEED)
  • La déréférence fautive. Le gc() final balaie les données JIT : sweepJitDataOnMainThread -> ICEntry::traceWeak -> TraceWeakCacheIRStub lit le pointeur de Symbole obsolète, puis SweepingTracer::onEdge (gc/Marking.cpp:3195) effectue une arithmétique de chunk sur l'adresse obsolète pour charger le champ zone de l'en-tête d'arène. La page a disparu/est zéroée, donc zone == nullptr, et zone->isGCSweeping() lit nullptr + 0x14 (shadow::Zone::gcState) -> SIGSEGV. Lors de la faute, rcx contient le pointeur de Symbole obsolète et rdx la base du chunk munmappé.