Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
fuzzilli — Um Fuzzer de Motor JavaScript | Kitploit
Ferramentas/GitHubGitHub/googleprojectzero/fuzzilli
Análise de VulnerabilidadesFuzzingAnálise de BináriosPapers e PesquisaAprendizado e Educação
GitHubgoogleprojectzero/fuzzilli

fuzzilli

Um Fuzzer de Motor JavaScript

Ver Repositório
2.3k3661há 7 diasRevisado pelo Kitploit

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

Fuzzilli

Um fuzzer guiado por cobertura para interpretadores de linguagens dinâmicas, baseado em uma linguagem intermediária personalizada ("FuzzIL") que pode ser mutada e traduzida para JavaScript.

Uso

Os passos básicos para usar este fuzzer são:

  1. Baixe o código-fonte de um dos mecanismos JavaScript suportados. Consulte o diretório Targets/ para a lista de mecanismos JavaScript suportados.
  2. Aplique os patches correspondentes do diretório do alvo. Consulte também o README.md nesse diretório.
  3. Compile o mecanismo com instrumentação de cobertura (requer clang >= 4.0) conforme descrito no README.
  4. Compile o fuzzer: swift build [-c release].
  5. Execute o fuzzer: swift run [-c release] FuzzilliCli --profile=<profile> [other cli options] /path/to/jsshell. Veja também swift run FuzzilliCli --help.

Construir e executar o Fuzzilli e os mecanismos JavaScript suportados dentro do Docker e no Google Compute Engine também é suportado.

Hacking

Confira main.swift para ver um exemplo de uso da biblioteca Fuzzilli e brincar com as várias opções de configuração. Em seguida, dê uma olhada em Fuzzer.swift para a lógica de fuzzing de alto nível. A partir daí, mergulhe em qualquer parte que pareça interessante.

Patches, adições e outras contribuições a este projeto são muito bem-vindas! No entanto, verifique rapidamente as notas para contribuidores. O Fuzzilli segue aproximadamente o guia de estilo de código do Google para Swift.

Seria muito apreciado se você pudesse enviar uma breve nota (possivelmente incluindo um número CVE) para [email protected] ou abrir um pull request para qualquer vulnerabilidade encontrada com a ajuda deste projeto, para que possa ser incluída na seção mostruário de bugs. Fora isso, você pode, claro, reivindicar qualquer recompensa por bug, créditos CVE, etc. pelas vulnerabilidades :)

Conceito

Ao fazer fuzzing para bugs no núcleo do interpretador, por exemplo em compiladores JIT, a correção semântica dos programas gerados torna-se uma preocupação. Isso contrasta com a maioria dos outros cenários, por exemplo, fuzzing de APIs de tempo de execução, onde a correção semântica pode ser facilmente contornada envolvendo o código gerado em construções try-catch. Existem diferentes possibilidades para atingir uma taxa aceitável de amostras semanticamente corretas, uma delas sendo uma abordagem mutacional na qual todas as amostras no corpus também são semanticamente válidas. Nesse caso, cada mutação tem apenas uma pequena chance de transformar uma amostra válida em uma inválida.

Para implementar um fuzzer JavaScript baseado em mutação, mutações no código JavaScript precisam ser definidas. Em vez de mutar a AST ou outros elementos sintáticos de um programa, uma linguagem intermediária (IL) personalizada é definida, na qual mutações no fluxo de controle e dados de um programa podem ser realizadas mais diretamente. Esta IL é posteriormente traduzida para JavaScript para execução. A linguagem intermediária parece aproximadamente como a seguir:

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]

Que pode, por exemplo, ser traduzido trivialmente para o seguinte código 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);

Ou para o seguinte código JavaScript, embutindo expressões intermediárias:

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

O FuzzIL tem várias propriedades:

  • Um programa FuzzIL é simplesmente uma lista de instruções.
  • Uma instrução FuzzIL é uma operação juntamente com variáveis de entrada e saída e potencialmente um ou mais parâmetros (entre aspas simples na notação acima).
  • As entradas para instruções são sempre variáveis, não há valores imediatos.
  • Cada saída de uma instrução é uma nova variável, e as variáveis existentes só podem ser reatribuídas por meio de operações dedicadas, como a instrução Reassign.
  • Cada variável é definida antes de ser usada.

Uma série de mutações pode então ser realizada nesses programas:

  • InputMutator: substitui variáveis de entrada das instruções por outras diferentes para mutar o fluxo de dados do programa.
  • CodeGenMutator: gera código e o insere em algum lugar no programa mutado. O código é gerado executando um gerador de código ou copiando algumas instruções de outro programa no corpus (splicing).
  • CombineMutator: insere um programa do corpus em uma posição aleatória no programa mutado.
  • OperationMutator: muta os parâmetros das operações, por exemplo, substituindo uma constante inteira por outra diferente.
  • e mais...

Uma discussão muito mais aprofundada de como o Fuzzilli funciona pode ser encontrada aqui.

Implementação

O fuzzer é implementado em Swift, com algumas partes (por exemplo, medições de cobertura, interações de socket, etc.) implementadas em C.

Arquitetura

Uma instância do fuzzer (implementada em Fuzzer.swift) é composta pelos seguintes componentes centrais:

  • MutationFuzzer: produz novos programas a partir de programas existentes aplicando mutações. Em seguida, executa as amostras produzidas e as avalia.
  • ScriptRunner: executa programas da linguagem alvo.
  • Corpus: armazena amostras interessantes e as fornece ao fuzzer central.
  • Environment: tem conhecimento do ambiente de tempo de execução, por exemplo, os builtins disponíveis, nomes de propriedades e métodos.
  • Minimizer: minimiza programas que causam crash e programas interessantes.
  • Evaluator: avalia se uma amostra é interessante de acordo com alguma métrica, por exemplo, cobertura de código.
  • Lifter: traduz um programa FuzzIL para a linguagem alvo (JavaScript).

Além disso, uma série de módulos estão opcionalmente disponíveis:

  • Statistics: coleta várias informações estatísticas.
  • NetworkSync: sincroniza várias instâncias pela rede.
  • ThreadSync: sincroniza várias instâncias dentro do mesmo processo.
  • Storage: armazena programas que causam crash em disco.

O fuzzer é orientado a eventos, com a maioria das interações entre diferentes classes ocorrendo por meio de eventos. Eventos são despachados, por exemplo, como resultado de um crash ou de um programa interessante ser encontrado, um novo programa ser executado, uma mensagem de log ser gerada, e assim por diante. Veja Events.swift para a lista completa de eventos. O mecanismo de eventos efetivamente desacopla os vários componentes do fuzzer e facilita a implementação de módulos adicionais.

Um programa FuzzIL pode ser construído usando uma instância de ProgramBuilder. Um ProgramBuilder fornece métodos para criar e anexar novas instruções, anexar instruções de outro programa, recuperar variáveis existentes, consultar o contexto de execução na posição atual (por exemplo, se está dentro de um loop), e mais.

Execução

O Fuzzilli usa um modo de execução personalizado chamado REPRL (read-eval-print-reset-loop). Para isso, o mecanismo alvo é modificado para aceitar uma entrada de script por pipes e/ou memória compartilhada, executá-la, depois redefinir seu estado interno e aguardar o próximo script. Isso remove a sobrecarga da criação de processos e, em grande parte, da inicialização do mecanismo.

Escalabilidade

Há uma instância de Fuzzer por processo alvo. Isso permite a execução síncrona de programas e, portanto, simplifica a implementação de vários algoritmos, como mutações consecutivas e minimização. Além disso, evita a necessidade de implementar acesso thread-safe ao estado interno, por exemplo, ao corpus. Cada instância do fuzzer tem sua própria DispatchQueue, correspondendo conceitualmente a uma única thread. Como regra geral, toda interação com uma instância do Fuzzer deve ocorrer na fila de despacho dessa instância. Isso garante thread-safety, pois a fila é serial. Para mais detalhes, veja a documentação.

Para escalar, as instâncias do fuzzer podem formar uma hierarquia de árvore, caso em que relatam novas amostras interessantes e crashes encontrados ao seu nó pai. Por sua vez, um nó pai sincroniza seu corpus com seus nós filhos. A comunicação entre nós na árvore pode ocorrer de diferentes formas, cada uma implementada como um módulo:

  • Comunicação entre threads: sincroniza instâncias no mesmo processo enfileirando tarefas na DispatchQueue do outro fuzzer.
  • Comunicação entre máquinas: sincroniza instâncias por um protocolo simples baseado em TCP.

Este design permite que o fuzzer escale para muitos núcleos em uma única máquina, bem como para muitas máquinas diferentes. Como um nó pai pode rapidamente ficar sobrecarregado se muitas instâncias enviarem programas para ele, é possível configurar múltiplos níveis de instâncias, por exemplo, uma instância raiz, 16 nós intermediários conectados à raiz e 256 "folhas" conectadas aos nós intermediários. Consulte o diretório Cloud/ para mais informações sobre fuzzing distribuído.

Recursos

Recursos adicionais sobre este fuzzer:

  • Uma apresentação sobre o Fuzzilli dada na Offensive Con 2019.
  • A tese de mestrado para a qual a implementação inicial foi feita.
  • Um post de blog da Sensepost sobre o uso do Fuzzilli para encontrar um bug no V8.
  • Um post de blog da Doyensec sobre fuzzing do mecanismo JerryScript com o Fuzzilli.
  • Um artigo do Simpósio NDSS 2023 sobre o Fuzzilli e como ele se compara a outros fuzzers.

Mostruário de Bugs

A seguir está uma lista de alguns bugs encontrados com a ajuda do Fuzzilli. Apenas bugs com impacto de segurança que estavam presentes em pelo menos uma versão Beta do software afetado devem ser incluídos nesta lista. Como o Fuzzilli é frequentemente usado para testes de fuzzing contínuos durante o desenvolvimento, muitos problemas encontrados por ele não estão incluídos nesta lista, pois geralmente são encontrados antes do código vulnerável atingir uma versão Beta. Uma lista de todos os problemas recentemente encontrados pelo Fuzzilli no V8 pode, no entanto, ser encontrada aqui.

Agradecimentos especiais a todos os usuários do Fuzzilli que relataram bugs encontrados por ele!

WebKit/JavaScriptCore

  • Issue 185328: DFG Compiler uses incorrect output register for NumberIsInteger operation
  • CVE-2018-4299: performProxyCall leaks internal object to script
  • CVE-2018-4359: compileMathIC produces incorrect machine code
  • CVE-2019-8518: OOB access in FTL JIT due to LICM moving array access before the bounds check
  • CVE-2019-8558: CodeBlock UaF due to dangling Watchpoints
  • CVE-2019-8611: AIR optimization incorrectly removes assignment to register
  • CVE-2019-8623: Loop-invariant code motion (LICM) in DFG JIT leaves stack variable uninitialized
  • CVE-2019-8622: DFG's doesGC() is incorrect about the HasIndexedProperty operation's behaviour on StringObjects
  • CVE-2019-8671: DFG: Loop-invariant code motion (LICM) leaves object property access unguarded
  • CVE-2019-8672: JSValue use-after-free in ValueProfiles
  • CVE-2019-8678: JSC fails to run haveABadTime() when some prototypes are modified, leading to type confusions
  • CVE-2019-8685: JSPropertyNameEnumerator uses wrong structure IDs
  • CVE-2019-8765: GetterSetter type confusion during DFG compilation
  • CVE-2019-8820: Type confusion during bailout when reconstructing arguments objects
  • CVE-2019-8844: ObjectAllocationSinkingPhase shouldn't insert hints for allocations which are no longer valid

Gecko/Spidermonkey

  • CVE-2018-12386: IonMonkey register allocation bug leads to type confusions
  • CVE-2019-9791: IonMonkey's type inference is incorrect for constructors entered via OSR
  • CVE-2019-9792: IonMonkey leaks JS_OPTIMIZED_OUT magic value to script
  • CVE-2019-9816: unexpected ObjectGroup in ObjectGroupDispatch operation
  • CVE-2019-9813: IonMonkey compiled code fails to update inferred property types, leading to type confusions
  • CVE-2019-11707: IonMonkey incorrectly predicts return type of Array.prototype.pop, leading to type confusions
  • CVE-2020-15656: Type confusion for special arguments in IonMonkey
  • CVE-2021-29982: Incorrect register allocation (found by JIT-Picker)
  • CVE-2021-29984: Instruction reordering in combination with an unexpected GC may lead to memory corruption
  • CVE-2022-28285: AliasSet for MLoadTypedArrayElementHole to permissive
  • CVE-2022-31745: Error in incremental GC
  • CVE-2022-42928: Missing KeepAlive annotations for some BigInt operations may lead to memory corruption
  • CVE-2022-45406: Use-after-free of a JavaScript Realm
  • CVE-2023-4577: Memory corruption due to interaction of GC and RegEx
  • CVE-2023-5171: GC resulted in a use-after-free condition during compilation

Chromium/v8* Issue 939316: Turbofan pode ler um ponteiro de Map fora dos limites ao otimizar Reflect.construct

  • Issue 944062: JSCallReducer::ReduceArrayIndexOfIncludes falha ao inserir verificações de Map
  • CVE-2019-5831: Processamento incorreto de Map no V8
  • Issue 944865: Representação de valor inválida no V8
  • CVE-2019-5841: Erro na heurística de inlining
  • CVE-2019-5847: Elementos selados/congelados do V8 causam crash
  • CVE-2019-5853: Corrupção de memória na verificação de comprimento de regexp
  • Issue 992914: Migração de Map não respeita tipos de elemento, levando a confusão de tipos
  • CVE-2020-6512: Confusão de tipos no V8
  • CVE-2020-16006: Corrupção de memória devido a colisão de hash tratada incorretamente em DescriptorArray
  • CVE-2021-37991: Condição de corrida durante compilação JIT concorrente
  • Issue 1359937: Desserialização de BigInts pode resultar em valor -0n inválido
  • Issue 1377775: Verificação de tipo incorreta ao fazer inlining de Array.prototype.at no Turbofan

Duktape

  • Issue 2323: Ponteiro valstack instável em putprop
  • Issue 2320: Estouro de ponteiro no memcmp em string builtin

JerryScript

  • CVE-2020-13991: Liberação incorreta de argumentos spread
  • Issue 3784: Corrupção de memória devido a enumeração incorreta de propriedades
  • CVE-2020-13623: Estouro de pilha através de chaves de propriedade para objetos Proxy
  • CVE-2020-13649 (1): Corrupção de memória devido a tratamento de erros em caso de OOM
  • CVE-2020-13649 (2): Corrupção de memória devido a tratamento de erros em caso de OOM
  • CVE-2020-13622: Corrupção de memória devido a tratamento incorreto de chaves de propriedade para objetos Proxy
  • CVE-2020-14163: Corrupção de memória devido a condição de corrida desencadeada pela coleta de lixo ao adicionar pares chave/valor
  • Issue 3813: Tratamento de erros incorreto na função SerializeJSONProperty
  • Issue 3814: Objeto Proxy inesperado na asserção ecma_op_function_has_instance
  • Issue 3836: Corrupção de memória devido a inicialização incorreta de TypedArray
  • Issue 3837: Corrupção de memória devido a tratamento incorreto de memória em getOwnPropertyDescriptor

Hermes

  • CVE-2020-1912: Corrupção de memória ao executar funções geradoras internas compiladas de forma preguiçosa
  • CVE-2020-1914: Corrupção de bytecode ao processar a instrução SaveGeneratorLong

Aviso legal

Este não é um produto oficialmente suportado pelo Google.

Baixar ferramenta
  • CVE-2020-3901: GetterSetter type confusion in FTL JIT code (due to not always safe LICM)
  • CVE-2021-30851: Missing lock during concurrent HashTable lookup
  • CVE-2021-30818: Type confusion when reconstructing arguments on DFG OSR Exit
  • CVE-2022-46696: Assertion failure due to missing exception check in JIT-compiled code
  • CVE-2022-46699: Assertion failure due to incorrect caching of special properties in ICs
  • CVE-2022-46700: Intl.Locale.prototype.hourCycles leaks empty JSValue to script
  • CVE-2025-43214: Memory corruption during JSToWasmEntry when iterating over the stack
  • CVE-2025-43213: Invalid typing of NewRegExpUntyped operation
  • CVE-2023-25735: Potential use-after-free from compartment mismatch
  • CVE-2023-25751: Corruption of jitted code
  • CVE-2023-29535: Memory corruption during GC of weak maps
  • CVE-2023-29543: Memory corruption within Debugger
  • CVE-2023-29544: Memory corruption during parallel marking
  • CVE-2023-29549: Objects allocated in incorrect realm
  • CVE-2024-0744: JIT compiled code could have dereferenced a wild pointer value
  • CVE-2024-3854: JIT incorrectly optimized switch statements and generated code with out-of-bounds-reads
  • CVE-2024-3855: JIT incorrectly optimized MSubstr operations, which led to out-of-bounds reads
  • CVE-2024-3857: JIT generated incorrect code resulting in use-after-free during garbage collection
  • CVE-2024-3858: Mutating a JavaScript object while GC tracing crashes the jitted code
  • CVE-2024-6613: Incorrect listing of WASM stack frames
  • CVE-2024-6614: Incorrect listing of WASM stack frames
  • CVE-2024-7521: Incomplete WebAssembly exception handing
  • CVE-2024-7652: Bug in the AsyncGeneratorPrototype Specification
  • CVE-2024-8381: Type confusion when looking up a property name in a "with" block
  • CVE-2024-9396: Potential memory corruption may occur when cloning certain objects
  • CVE-2025-0240: Compartment mismatch when parsing JavaScript JSON module
  • CVE-2025-0241: Memory corruption when using JavaScript Text Segmentation
  • CVE-2025-1012: Use-after-free during concurrent delazification
  • CVE-2025-1934: Unexpected GC during RegExp bailout processing