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
fuzzilli — Un fuzzer per motori JavaScript | Kitploit
Strumenti/GitHubGitHub/googleprojectzero/fuzzilli
Analisi delle VulnerabilitàFuzzingAnalisi di BinariPaper e RicercaApprendimento e Formazione
GitHubgoogleprojectzero/fuzzilli

fuzzilli

Un fuzzer per motori JavaScript

Vedi Repository
2.3k366557 giorni 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

Fuzzilli

Un fuzzzer guidato dalla copertura per interpreti di linguaggi dinamici basato su un linguaggio intermedio personalizzato ("FuzzIL") che può essere mutato e tradotto in JavaScript.

Utilizzo

I passi fondamentali per utilizzare questo fuzzzer sono:

  1. Scaricare il codice sorgente di uno dei motori JavaScript supportati. Consulta la directory Targets/ per l'elenco dei motori JavaScript supportati.
  2. Applicare le patch corrispondenti dalla directory del target. Vedi anche il README.md in quella directory.
  3. Compilare il motore con strumentazione di copertura (richiede clang >= 4.0) come descritto nel README.
  4. Compilare il fuzzzer: swift build [-c release].
  5. Eseguire il fuzzzer: swift run [-c release] FuzzilliCli --profile=<profilo> [altre opzioni CLI] /percorso/del/jsshell. Vedi anche swift run FuzzilliCli --help.

La compilazione e l'esecuzione di Fuzzilli e dei motori JavaScript supportati all'interno di Docker e su Google Compute Engine è anche supportata.

Hacking

Dai un'occhiata a main.swift per vedere un esempio di utilizzo della libreria Fuzzilli e sperimentare con le varie opzioni di configurazione. Successivamente, guarda per la logica di fuzzing di alto livello. Da lì, approfondisci qualsiasi parte che sembri interessante.

Scarica lo strumento
Fuzzer.swift

Patch, aggiunte e altri contributi a questo progetto sono benvenuti! Tuttavia, dai un'occhiata rapidamente alle note per i contributori. Fuzzilli segue approssimativamente la guida di stile del codice di Google per Swift.

Sarebbe molto apprezzato se potessi inviare una breve nota (possibilmente includendo un numero CVE) a [email protected] o aprire una pull request per qualsiasi vulnerabilità trovata con l'aiuto di questo progetto, in modo che possa essere inclusa nella sezione vetrina dei bug. Per il resto, puoi ovviamente rivendicare qualsiasi bounty per bug, crediti CVE, ecc. per le vulnerabilità :)

Concetto

Quando si fuzzza per bug del core dell'interprete, ad esempio nei compilatori JIT, la correttezza semantica dei programmi generati diventa un problema. Questo è in contrasto con la maggior parte degli altri scenari, ad esempio il fuzzing delle API runtime, in cui la correttezza semantica può essere facilmente aggirata racchiudendo il codice generato in costrutti try-catch. Esistono diverse possibilità per ottenere un tasso accettabile di campioni semanticamente corretti, una delle quali è un approccio mutazionale in cui tutti i campioni nel corpus sono anche semanticamente validi. In tal caso, ogni mutazione ha solo una piccola probabilità di trasformare un campione valido in uno non valido.

Per implementare un fuzzzer JavaScript basato su mutazioni, è necessario definire mutazioni per il codice JavaScript. Invece di mutare l'AST o altri elementi sintattici di un programma, viene definito un linguaggio intermedio personalizzato (IL) sul quale le mutazioni al flusso di controllo e di dati di un programma possono essere eseguite più direttamente. Questo IL viene poi tradotto in JavaScript per l'esecuzione. Il linguaggio intermedio ha approssimativamente il seguente aspetto:

root@kitploit:~
v0 <− LoadInteger '0'
v1 <− LoadInteger '10'
v2 <− LoadInteger '1'
v3 <− LoadInteger '0'
BeginFor v0, '<', v1, '+', v2 −> v4
   v6 <− BinaryOperation v3, '+', v4
   Reassign v3, v6
EndFor
v7 <− LoadString 'Result: '
v8 <− BinaryOperation v7, '+', v3
v9 <− LoadGlobal 'console'
v10 <− CallMethod v9, 'log', [v8]

Che può, ad esempio, essere tradotto banalmente nel seguente codice JavaScript:

root@kitploit:~
const v0 = 0;
const v1 = 10;
const v2 = 1;
let v3 = 0;
for (let v4 = v0; v4 < v1; v4 = v4 + v2) {
    const v6 = v3 + v4;
    v3 = v6;
}
const v7 = "Result: ";
const v8 = v7 + v3;
const v9 = console;
const v10 = v9.log(v8);

Oppure al seguente codice JavaScript inlineando le espressioni intermedie:

root@kitploit:~
let v3 = 0;
for (let v4 = 0; v4 < 10; v4++) {
    v3 = v3 + v4;
}
console.log("Result: " + v3);

FuzzIL ha una serie di proprietà:

  • Un programma FuzzIL è semplicemente una lista di istruzioni.
  • Un'istruzione FuzzIL è un'operazione insieme a variabili di input e output e potenzialmente uno o più parametri (racchiusi tra virgolette singole nella notazione sopra).
  • Gli input per le istruzioni sono sempre variabili, non ci sono valori immediati.
  • Ogni output di un'istruzione è una nuova variabile, e le variabili esistenti possono essere riassegnate solo tramite operazioni dedicate come l'istruzione Reassign.
  • Ogni variabile è definita prima di essere utilizzata.

Su questi programmi possono essere eseguite diverse mutazioni:

  • InputMutator: sostituisce le variabili di input delle istruzioni con altre diverse per mutare il flusso di dati del programma.
  • CodeGenMutator: genera codice e lo inserisce da qualche parte nel programma mutato. Il codice viene generato eseguendo un generatore di codice o copiando alcune istruzioni da un altro programma nel corpus (splicing).
  • CombineMutator: inserisce un programma dal corpus in una posizione casuale nel programma mutato.
  • OperationMutator: muta i parametri delle operazioni, ad esempio sostituendo una costante intera con una diversa.
  • e altri...

Una discussione molto più approfondita su come funziona Fuzzilli può essere trovata qui.

Implementazione

Il fuzzzer è implementato in Swift, con alcune parti (ad esempio misurazioni della copertura, interazioni socket, ecc.) implementate in C.

Architettura

Un'istanza del fuzzzer (implementata in Fuzzer.swift) è composta dai seguenti componenti centrali:

  • MutationFuzzer: produce nuovi programmi a partire da quelli esistenti applicando mutazioni. Successivamente esegue i campioni prodotti e li valuta.
  • ScriptRunner: esegue programmi nel linguaggio target.
  • Corpus: memorizza campioni interessanti e li fornisce al fuzzzer centrale.
  • Environment: ha conoscenza dell'ambiente runtime, ad esempio i builtin disponibili, i nomi delle proprietà e i metodi.
  • Minimizer: minimizza i programmi che causano crash o sono interessanti.
  • Evaluator: valuta se un campione è interessante secondo una metrica, ad esempio la copertura del codice.
  • Lifter: traduce un programma FuzzIL nel linguaggio target (JavaScript).

Inoltre, sono opzionalmente disponibili diversi moduli:

  • Statistics: raccoglie varie informazioni statistiche.
  • NetworkSync: sincronizza più istanze sulla rete.
  • ThreadSync: sincronizza più istanze all'interno dello stesso processo.
  • Storage: salva su disco i programmi che causano crash.

Il fuzzzer è guidato da eventi, con la maggior parte delle interazioni tra diverse classi che avvengono tramite eventi. Gli eventi vengono lanciati, ad esempio, a seguito di un crash o del ritrovamento di un programma interessante, dell'esecuzione di un nuovo programma, della generazione di un messaggio di log e così via. Vedi Events.swift per l'elenco completo degli eventi. Il meccanismo degli eventi disaccoppia efficacemente i vari componenti del fuzzzer e rende facile implementare moduli aggiuntivi.

Un programma FuzzIL può essere costruito utilizzando un'istanza di ProgramBuilder. Un ProgramBuilder fornisce metodi per creare e aggiungere nuove istruzioni, aggiungere istruzioni da un altro programma, recuperare variabili esistenti, interrogare il contesto di esecuzione nella posizione corrente (ad esempio se si è all'interno di un ciclo) e altro ancora.

Esecuzione

Fuzzilli utilizza una modalità di esecuzione personalizzata chiamata REPRL (read-eval-print-reset-loop). A tale scopo, il motore target viene modificato per accettare un input di script tramite pipe e/o memoria condivisa, eseguirlo, quindi resettare il suo stato interno e attendere il prossimo script. Questo elimina il sovraccarico derivante dalla creazione del processo e, in gran parte, dall'inizializzazione del motore.

Scalabilità

C'è un'istanza di Fuzzer per processo target. Ciò consente l'esecuzione sincrona dei programmi e semplifica quindi l'implementazione di vari algoritmi come mutazioni consecutive e minimizzazione. Inoltre, evita la necessità di implementare un accesso thread-safe allo stato interno, ad esempio al corpus. Ogni istanza del fuzzzer ha la propria DispatchQueue, corrispondente concettualmente a un singolo thread. Come regola generale, ogni interazione con un'istanza di Fuzzer deve avvenire sulla coda di dispatch di quell'istanza. Ciò garantisce la thread-safety poiché la coda è seriale. Per maggiori dettagli, consulta la documentazione.

Per scalare, le istanze del fuzzzer possono formare una gerarchia ad albero, in cui riportano i campioni interessanti e i crash appena trovati al loro nodo padre. A sua volta, un nodo padre sincronizza il suo corpus con i suoi nodi figli. La comunicazione tra nodi nell'albero può avvenire in diversi modi, ciascuno implementato come modulo:

  • Comunicazione tra thread: sincronizza le istanze nello stesso processo accodando compiti alla DispatchQueue dell'altro fuzzzer.
  • Comunicazione tra macchine: sincronizza le istanze tramite un semplice protocollo basato su TCP.

Questo design consente al fuzzzer di scalare su molti core in una singola macchina e su molte macchine diverse. Poiché un singolo nodo padre può diventare rapidamente sovraccarico se troppe istanze gli inviano programmi, è possibile configurare più livelli di istanze, ad esempio un'istanza radice, 16 nodi intermedi collegati alla radice e 256 "foglie" collegate ai nodi intermedi. Vedi la directory Cloud/ per maggiori informazioni sul fuzzing distribuito.

Risorse

Ulteriori risorse su questo fuzzzer:

  • Una presentazione su Fuzzilli tenuta a Offensive Con 2019.
  • La tesi magistrale per la quale è stata realizzata l'implementazione iniziale.
  • Un articolo di Sensepost sull'uso di Fuzzilli per trovare un bug in v8.
  • Un articolo di Doyensec sul fuzzing del motore JerryScript con Fuzzilli.
  • Un articolo scientifico del NDSS Symposium 2023 su Fuzzilli e come si confronta con altri fuzzer.

Vetrina dei bug

La seguente è una lista di alcuni dei bug trovati con l'aiuto di Fuzzilli. Dovrebbero essere inclusi in questa lista solo i bug con impatto sulla sicurezza che erano presenti almeno in una versione Beta del software interessato. Poiché Fuzzilli viene spesso utilizzato per test di fuzzing continui durante lo sviluppo, molti problemi trovati da esso non sono inclusi in questa lista, poiché vengono tipicamente scoperti prima che il codice vulnerabile raggiunga una versione Beta. Una lista di tutti i problemi recentemente trovati da Fuzzilli in V8 può comunque essere trovata qui.

Un ringraziamento speciale a tutti gli utenti di Fuzzilli che hanno segnalato bug trovati con esso!

WebKit/JavaScriptCore

  • Issue 185328: Il compilatore DFG utilizza un registro di output errato per l'operazione NumberIsInteger
  • CVE-2018-4299: performProxyCall perde un oggetto interno nello script
  • CVE-2018-4359: compileMathIC produce codice macchina errato
  • CVE-2019-8518: Accesso OOB in FTL JIT a causa di LICM che sposta l'accesso all'array prima del controllo dei limiti
  • CVE-2019-8558: UaF di CodeBlock a causa di Watchpoint pendenti
  • CVE-2019-8611: L'ottimizzazione AIR rimuove erroneamente l'assegnazione a un registro
  • CVE-2019-8623: Lo spostamento di codice invariante di ciclo (LICM) in DFG JIT lascia una variabile di stack non inizializzata
  • CVE-2019-8622: doesGC() di DFG è errato riguardo al comportamento dell'operazione HasIndexedProperty su StringObjects
  • CVE-2019-8671: DFG: Lo spostamento di codice invariante di ciclo (LICM) lascia l'accesso alla proprietà dell'oggetto senza guardia
  • CVE-2019-8672: Use-after-free di JSValue in ValueProfiles
  • CVE-2019-8678: JSC non riesce a eseguire haveABadTime() quando alcuni prototipi vengono modificati, portando a confusioni di tipo
  • CVE-2019-8685: JSPropertyNameEnumerator utilizza ID di struttura errati
  • CVE-2019-8765: Confusione di tipo GetterSetter durante la compilazione DFG
  • CVE-2019-8820: Confusione di tipo durante il bailout nella ricostruzione degli oggetti arguments
  • CVE-2019-8844: ObjectAllocationSinkingPhase non dovrebbe inserire hint per allocazioni che non sono più valide
  • CVE-2020-3901: Confusione di tipo GetterSetter nel codice FTL JIT (a causa di LICM non sempre sicuro)
  • CVE-2021-30851: Lock mancante durante la ricerca simultanea in HashTable
  • CVE-2021-30818: Confusione di tipo durante la ricostruzione degli argomenti all'uscita OSR di DFG
  • CVE-2022-46696: Fallimento dell'asserzione a causa di una mancata eccezione di controllo nel codice compilato JIT
  • CVE-2022-46699: Fallimento dell'asserzione a causa di una memorizzazione errata delle proprietà speciali negli IC
  • CVE-2022-46700: Intl.Locale.prototype.hourCycles perde un JSValue vuoto nello script
  • CVE-2025-43214: Corruzione della memoria durante JSToWasmEntry quando si itera sullo stack
  • CVE-2025-43213: Tipizzazione errata dell'operazione NewRegExpUntyped

Gecko/Spidermonkey

  • CVE-2018-12386: Un bug nell'allocazione dei registri di IonMonkey porta a confusioni di tipo
  • CVE-2019-9791: L'inferenza di tipo di IonMonkey è errata per i costruttori inseriti tramite OSR
  • CVE-2019-9792: IonMonkey perde il valore magico JS_OPTIMIZED_OUT nello script
  • CVE-2019-9816: ObjectGroup inaspettato nell'operazione ObjectGroupDispatch
  • CVE-2019-9813: Il codice compilato da IonMonkey non riesce ad aggiornare i tipi di proprietà inferiti, portando a confusioni di tipo
  • CVE-2019-11707: IonMonkey predice erroneamente il tipo di ritorno di Array.prototype.pop, portando a confusioni di tipo
  • CVE-2020-15656: Confusione di tipo per argomenti speciali in IonMonkey
  • CVE-2021-29982: Allocazione errata dei registri (trovato da JIT-Picker)
  • CVE-2021-29984: Il riordino delle istruzioni in combinazione con un GC inaspettato può portare a corruzione della memoria
  • CVE-2022-28285: AliasSet per MLoadTypedArrayElementHole troppo permissivo
  • CVE-2022-31745: Errore nel GC incrementale
  • CVE-2022-42928: Annotazioni KeepAlive mancanti per alcune operazioni BigInt possono portare a corruzione della memoria
  • CVE-2022-45406: Use-after-free di un Realm JavaScript
  • CVE-2023-4577: Corruzione della memoria a causa dell'interazione tra GC e RegEx
  • CVE-2023-5171: GC ha provocato una condizione di use-after-free durante la compilazione
  • CVE-2023-25735: Potenziale use-after-free da disallineamento dei compartment
  • CVE-2023-25751: Corruzione del codice jitted
  • CVE-2023-29535: Corruzione della memoria durante il GC delle weak map
  • CVE-2023-29543: Corruzione della memoria all'interno di Debugger
  • CVE-2023-29544: Corruzione della memoria durante la marcatura parallela
  • CVE-2023-29549: Oggetti allocati in realm errato
  • CVE-2024-0744: Il codice compilato JIT potrebbe aver dereferenziato un puntatore wild
  • CVE-2024-3854: JIT ha ottimizzato erroneamente le istruzioni switch e generato codice con letture fuori dai limiti
  • CVE-2024-3855: JIT ha ottimizzato erroneamente le operazioni MSubstr, portando a letture fuori dai limiti
  • CVE-2024-3857: JIT ha generato codice errato risultando in use-after-free durante la garbage collection
  • CVE-2024-3858: La mutazione di un oggetto JavaScript durante il tracing GC causa il crash del codice jitted
  • CVE-2024-6613: Elenco errato degli stack frame WASM
  • CVE-2024-6614: Elenco errato degli stack frame WASM
  • CVE-2024-7521: Gestione incompleta delle eccezioni WebAssembly
  • CVE-2024-7652: Bug nella specifica di AsyncGeneratorPrototype
  • CVE-2024-8381: Confusione di tipo durante la ricerca di un nome di proprietà in un blocco "with"
  • CVE-2024-9396: Potenziale corruzione della memoria durante la clonazione di determinati oggetti
  • CVE-2025-0240: Disallineamento del compartment durante l'analisi del modulo JSON JavaScript
  • CVE-2025-0241: Corruzione della memoria durante l'uso di JavaScript Text Segmentation
  • CVE-2025-1012: Use-after-free durante la delazificazione concorrente
  • CVE-2025-1934: GC inaspettato durante l'elaborazione del bailout di RegExp

Chromium/v8* Issue 939316: Turbofan potrebbe leggere un puntatore Map fuori dai limiti durante l'ottimizzazione di Reflect.construct

  • Issue 944062: JSCallReducer::ReduceArrayIndexOfIncludes non inserisce i controlli Map
  • CVE-2019-5831: Elaborazione errata delle mappe in V8
  • Issue 944865: Rappresentazione di valori non valida in V8
  • CVE-2019-5841: Bug nell'euristica di inlining
  • CVE-2019-5847: Elementi sigillati/congelati di V8 causano crash
  • CVE-2019-5853: Corruzione della memoria nel controllo della lunghezza delle regexp
  • Issue 992914: La migrazione delle mappe non rispetta i tipi di elemento, causando confusione di tipo
  • CVE-2020-6512: Confusione di tipo in V8
  • CVE-2020-16006: Corruzione della memoria a causa di una collisione di hash gestita in modo improprio in DescriptorArray
  • CVE-2021-37991: Condizione di gara durante la compilazione JIT concorrente
  • Issue 1359937: La deserializzazione dei BigInt potrebbe produrre un valore -0n non valido
  • Issue 1377775: Controllo di tipo errato durante l'inlining di Array.prototype.at in Turbofan

Duktape

  • Issue 2323: Puntatore valstack instabile in putprop
  • Issue 2320: Overflow del puntatore Memcmp nelle funzioni built-in per stringhe

JerryScript

  • CVE-2020-13991: Rilascio errato degli argomenti spread
  • Issue 3784: Corruzione della memoria a causa di un'enumerazione errata delle proprietà
  • CVE-2020-13623: Stack overflow tramite chiavi di proprietà per oggetti Proxy
  • CVE-2020-13649 (1): Corruzione della memoria dovuta alla gestione degli errori in caso di OOM
  • CVE-2020-13649 (2): Corruzione della memoria dovuta alla gestione degli errori in caso di OOM
  • CVE-2020-13622: Corruzione della memoria a causa della gestione errata delle chiavi di proprietà per oggetti Proxy
  • CVE-2020-14163: Corruzione della memoria dovuta a una condizione di gara scatenata dalla garbage collection durante l'aggiunta di coppie chiave/valore
  • Issue 3813: Gestione degli errori errata nella funzione SerializeJSONProperty
  • Issue 3814: Oggetto Proxy inaspettato nell'asserzione ecma_op_function_has_instance
  • Issue 3836: Corruzione della memoria a causa di un'inizializzazione errata di TypedArray
  • Issue 3837: Corruzione della memoria a causa di una gestione errata della memoria in getOwnPropertyDescriptor

Hermes

  • CVE-2020-1912: Corruzione della memoria durante l'esecuzione di funzioni generatrici interne compilate in modo lazy
  • CVE-2020-1914: Corruzione del bytecode durante la gestione dell'istruzione SaveGeneratorLong

Disclaimer

Questo non è un prodotto ufficialmente supportato da Google.