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-84118-who-labeled-the-crit-as-a-high — Proof-of-concept per CVE-2026-84118, una use-after-free nella GC di SpiderMonkey che porta a lettura/scrittura fuori dai limiti e potenziale esecuzione di codice. Include un trigger SEGV deterministico e ricerca sull'escalation a lettura arbitraria e bypass di ASLR. | Kitploit
Strumenti/GitHubGitHub/sneakynachos/cve-2026-84118-who-labeled-the-crit-as-a-high
Memory ForensicsAnalisi delle VulnerabilitàExploitSicurezza WebBinary Exploitation
GitHubsneakynachos/cve-2026-84118-who-labeled-the-crit-as-a-high

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

Proof-of-concept per CVE-2026-84118, una use-after-free nella GC di SpiderMonkey che porta a lettura/scrittura fuori dai limiti e potenziale esecuzione di codice. Include un trigger SEGV deterministico e ricerca sull'escalation a lettura arbitraria e bypass di ASLR.

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
Vedi Repository
111 ore faNon ancora revisionato

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

Questo è uno di quei casi in cui Mozilla ha etichettato una Critica come Alta. Quindi qualcuno potrebbe voler andare a chiedere a Firefox di aggiornare il pagamento dei cacciatori di bug originali, se è questo il caso.

IN BREVE: Puoi eseguire una primitiva R di OOB su un puntatore controllato e poi iniziare a salire e scendere da quel puntatore. Quindi se punti il puntatore controllato a un array, congratulazioni, puoi fare cose divertenti.

La POC ha solo la parte SEGV, quindi il resto è un'avventura divertente nel puntare a un array e saltare nella WASM che preferisci.

Prova di concetto SEGV deterministica su build release per Firefox/SpiderMonkey 154.0.1. Corretto nella 155 (rifacimento AtomMarking). Gravità Mozilla: ALTA.

Esecuzione della PoC

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

Riprodotta su 154.0.1: 3/3 su una shell ottimizzata semplice (SIGSEGV, exit 139), 5/5 su una shell release+gczeal, stesso errore a ogni esecuzione:

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

Causa principale

La 154 confonde le bitmap di mark degli atom per-zone con il tracciamento dei riferimenti. Un Symbol tenuto solo debolmente — qui, catturato come campo Value debole all'interno di uno stub IC CacheIR di Baseline — e referenziato da una zona non raccolta non viene mai ri-marcato quando la zona degli atom viene raccolta in una GC con ambito di zona. Il risultato è un bordo stantio verso una cellula spazzata/rilocata.

Il colpo letale della build release è un secondo bug statico: MightBeForwarded<JS::Symbol> è hardcoded false, quindi IsForwarded restituisce false senza controllare (gc/Marking-inl.h:92-97) e ogni percorso di correzione dei puntatori che ne dipende salta silenziosamente il bordo. Quando la zona degli atom viene compattata, i bordi forti vengono aggiornati correttamente, ma questo bordo CacheIR debole rimane permanentemente pendente al vecchio indirizzo del Symbol vittima. (Le build di debug lo rilevano come Assertion failure: !t->isForwarded(), gc/Marking-inl.h:94.)

Come la PoC trasforma il bordo pendente in un SEGV

La PoC non lascia semplicemente un puntatore stantio verso heap riutilizzabile — fa sì che la pagina sottostante venga munmappata, così la dereferenziazione successiva va in errore.

  1. Isolamento dei chunk per-zone. I pool di chunk della GC sono per-zone (Zone::availableChunks/fullChunks), quindi i chunk della zona degli atom contengono solo arena della zona degli atom. Il destino di un chunk può essere controllato puramente da cicli di vita di atom/symbol.
  2. Grooming dell'heap. 300 Symbol "magnete" (tenuti vivi) occupano un chunk iniziale e servono come destinazione della compattazione. 150.000 Symbol usa-e-getta riempiono poi ~4 nuovi chunk da 1 MB, così il Symbol vittima atterra a metà spray in un chunk contenente solo symbol spray condannati.
  3. La danza del symbol tenuto debolmente (righe 21-31, fragile a livello di bytecode — deve rimanere verbatim): c.eval(b) fa sì che la IC della chiamata di livello superiore catturi il Symbol in un campo stub debole; b = undefined rilascia l'ultima root forte; lo spray viene rilasciato; due GC con ambito di zona (gc("zone"), schedulezone(c) + schedulezone("") + gc("zone") — la stringa vuota pianifica la zona degli atom) spazzano lo spray morto, compattano la vittima nell'arena dei magneti, saltano la correzione del bordo debole, e liberano l'arena della vittima. Il suo chunk ora è completamente vuoto.
  4. munmap. gcparam("minEmptyChunkCount", 0) rende ogni chunk vuoto espirabile; durante sleep(0.5) il BackgroundDecommitTask esegue -> -> — un vero munmap del chunk vittima. (Il decommit a livello di arena è solo — zeri leggibili — il rilascio dell'intero chunk è l'unico percorso munmap, motivo per cui l'isolamento dei chunk nel passaggio 1 è importante.)

Oltre il crash della pagina nulla

Questa non è solo una DoS. Escalation dimostrate (PoC e log nelle directory di ricerca GC-NDAY/ e CHAIN/):

  • Indirizzo di errore scelto dall'attaccante (segv9): dopo il munmap, un flip del semispazio minorgc() fa sì che la nursery rivendichi il VA liberato; uno spray grezzo di double densi scrive una qword dell'attaccante sul campo zone dell'header dell'arena stantia. La spazzatura dereferenzia poi attacker_ptr + 0x14 — deterministico 3/3 a 0x424242424256.
  • Controllo del verdetto + letture ripetibili: il valore caricato seleziona il verdetto di liveness del bordo debole; un verdetto "LIVE" mantiene il bordo pendente e lo dereferenzia di nuovo a ogni successiva GC maggiore (letture scelte dall'attaccante + un oracolo osservabile dallo script a 1 bit). Un verdetto "DEAD" si auto-ripara.
  • Catena di due bug: un vero js::Zone* divulgato tramite un canale laterale speculativo separato è stato piantato attraverso questo refill; il collector ha consumato i metadati dell'arena contraffatti senza andare in errore (una piantagione di controllo perturbata a 1 bit va in crash), dimostrando la composizione sconfitta-ASLR -> piantagione-UAF.
  • Negativo limitato: il fakeobj diretto attraverso questa famiglia di stub è architettonicamente bloccato — la compattazione corregge correttamente i bordi forti, solo i bordi deboli restano pendenti, e i loro consumatori di spazzatura sono solo a rami.
Scarica lo strumento
expireEmptyChunkPool
FreeChunkPool
UnmapPages
madvise(MADV_DONTNEED)
  • La dereferenziazione che va in errore. La gc() finale spazza i dati JIT: sweepJitDataOnMainThread -> ICEntry::traceWeak -> TraceWeakCacheIRStub legge il puntatore Symbol stantio, poi SweepingTracer::onEdge (gc/Marking.cpp:3195) esegue l'aritmetica dei chunk sull'indirizzo stantio per caricare il campo zone dell'header dell'arena. La pagina è sparita/azzerata, quindi zone == nullptr, e zone->isGCSweeping() legge nullptr + 0x14 (shadow::Zone::gcState) -> SIGSEGV. Al momento dell'errore, rcx contiene il puntatore Symbol stantio e rdx la base del chunk munmappato.