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
wtf — Fuzzer distribuído orientado por cobertura de código baseado em snapshots para alvos em modo de usuário e modo kernel no Windows e Linux, com backends de emulador e hipervisor. | Kitploit
Ferramentas/GitHubGitHub/0vercl0k/wtf
Análise Dinâmica (Sandboxing)Análise de VulnerabilidadesExploraçãoFuzzingAnálise de Binários
GitHub0vercl0k/wtf

wtf

Fuzzer distribuído orientado por cobertura de código baseado em snapshots para alvos em modo de usuário e modo kernel no Windows e Linux, com backends de emulador e hipervisor.

Ver Repositório
1.8k154há 15 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

what the fuzz

Um fuzzer distribuído, guiado por cobertura de código, multiplataforma e baseado em snapshots, projetado para atacar alvos em modo de usuário e/ou kernel executando no Microsoft Windows e no modo usuário do Linux (experimental!).

Visão Geral

what the fuzz ou wtf é um fuzzer distribuído, guiado por cobertura de código, customizável, multiplataforma e baseado em snapshots, projetado para atacar alvos em modo de usuário e/ou kernel executando no Microsoft Windows ou Linux (experimental, veja linux_mode). A execução do alvo pode ser feita dentro de um emulador com bochscpu (mais lento, mais preciso), dentro de uma VM Windows com as APIs do Windows Hypervisor Platform ou dentro de uma VM Linux com as APIs KVM (mais rápido).

Ele descobriu vulnerabilidades de corrupção de memória em uma ampla gama de softwares: IDA Pro, um jogo AAA popular, o kernel do Windows, o cliente Microsoft RDP, o driver de display NVIDIA GPU, etc.

Binários compilados estão disponíveis nos artefatos do CI ou na seção de Releases tanto para Windows quanto para Linux.

Se você quiser ler mais sobre sua história ou como usá-lo em um alvo real, recomendo dar uma olhada nestas postagens para começar 🔥

  • Construindo um novo fuzzer de snapshot e fuzzeando IDA
  • Fuzzeando protocolos modernos de jogos UDP com fuzzers baseados em snapshot por Markus Gaasedelen
  • Fuzzeando RDPEGFX com "what the fuzz" por Colas Le Guernic, Jérémy Rubert e Anônimo
  • Uma jornada para fuzzing de protocolo de rede – Dissecando o protocolo IMAP do Microsoft por Wayne Chin Yick Low
  • A seção de Fuzzing de Snapshot do Manual de Testes da Trail Of Bits
  • Atacando EDRs Parte 4: Fuzzeando o mecanismo de varredura e emulação do Defender (mpengine.dll) por Manuel Feifel

Uso

A melhor maneira de experimentar os recursos é trabalhar com os módulos fuzzer_hevd / fuzzer_tlv_server. Você pode baixar os arquivos target-hevd.7z / target-tlv_server.7z e extraí-los no diretório targets/. Os arquivos contêm as árvores de diretórios esperadas para cada alvo:

  • inputs é a pasta onde seus casos de teste de entrada vão,
  • outputs é a pasta onde os arquivos minset atuais são salvos,
  • coverage é a pasta onde os arquivos .cov devem estar,
  • crashes é onde as falhas são salvas,
  • state é onde o dump de memória (mem.dmp), bem como o estado da CPU (regs.json) e o armazenamento de símbolos são armazenados (symbol-store.json). O armazenamento de símbolos é um arquivo JSON simples usado em sistemas Linux para saber onde colocar pontos de interrupção, já que não há suporte para símbolos/dbgeng nessas plataformas. wtf gera este arquivo em tempo de execução sempre que você executa seu alvo no Windows.

O que se segue assume que você baixou o arquivo target-hevd.7z anexado à versão mais recente e o extraiu no diretório targets do seu clone de wtf. Você deve ter wtf/targets/hevd onde encontrará os diretórios inputs / outputs, etc.

Iniciando um nó servidor

O servidor é basicamente o cérebro e mantém o controle de todo o estado: a cobertura de código agregada, o corpus, gera e distribui os casos de teste para o cliente.

É assim que você pode optar por iniciar um nó servidor local:```text wtf.exe master --name hevd --max_len=1028 --runs=10000000

root@kitploit:~
A opção `max_len` é usada para limitar o tamanho do caso de teste gerado, `runs` é o número de casos de teste que serão gerados, `address` especifica onde o **wtf** precisa estar ouvindo, `target` é um diretório com a árvore de diretórios que descrevemos acima (o usuário também pode optar por substituir esses diretórios com `--input` / `--output` / `--crashes`) e `name` especifica o nome do seu  módulo de fuzzing para que o mestre possa invocar sua função geradora, se você tiver definido uma.

<p align='center'>
<img src="https://assets.kitploit.com/production/public/readmes/4699/4a03fc75eed3ed5a92f7f10def697dbf220ae36b0701f05b37759eb432fc0fd9.webp">
</p>

### Nós de fuzzing

Os nós clientes executam um caso de teste que foi gerado e distribuído pelo servidor e comunicam o resultado de volta ao servidor (cobertura de código, resultado, etc.).

É assim que você iniciaria um nó cliente que usa o backend *bochscpu*:```text
wtf.exe fuzz --name hevd --limit 10000000

O subcomando fuzz é usado com a opção name para especificar qual módulo fuzzer precisa ser usado, backend especifica o backend de execução e limit o número máximo de instruções a executar por caso de teste (dependendo do backend, esta opção tem significado diferente).

Executando um caso de teste

Se você quiser executar um caso de teste (ou uma pasta cheia de casos de teste), você pode usar o subcomando run.

É assim que você executaria o caso de teste crash-0xfffff764b91c0000-0x0-0xffffbf84fb10e780-0x2-0x0:``` wtf.exe run --name hevd --limit 10000000 --input crashes\crash-0xfffff764b91c0000-0x0-0xffffbf84fb10e780-0x2-0x0

root@kitploit:~
<p align='center'>
<img src="https://assets.kitploit.com/production/public/readmes/4699/49b3ca8582d6314724e5615c687472499d5f8f41d04c9543c0a6a070c51f56f8.webp">
</p>

### Minimizando um corpus

Para minimizar um corpus, você precisa usar um nó servidor e quantos nós clientes forem necessários, como faria para um trabalho de fuzzing. Você pode simplesmente definir a opção `runs` para 0.

É assim que você minimizaria o corpus em `outputs` para o diretório `minset` (também destaca como você pode substituir os diretórios `inputs` e `outputs`):```
wtf.exe master --name hevd --max_len=1028 --runs=0 --inputs=outputs --outputs=minset

Gerando traços de execução

O principal mecanismo disponível para introspecção em um backend de execução é gerar um traço de execução. bochscpu é o backend mais rápido para fazer isso, pois sair do modo VMX é muito caro nos outros backends.

É assim que você geraria um traço de execução para o caso de teste crash-0xfffff764b91c0000-0x0-0xffffbf84fb10e780-0x2-0x0:``` wtf.exe run --name hevd --limit 10000000 --input crashes\crash-0xfffff764b91c0000-0x0-0xffffbf84fb10e780-0x2-0x0 --trace-type=rip

root@kitploit:~
<p align='center'>
<img src="https://assets.kitploit.com/production/public/readmes/4699/340b4b251e378eaf21c6f5ffdd4f013bd2cef89f23a604cffd0ebf897d27c71f.webp">
</p>

Para simbolizar os traços de execução, você deve usar o [symbolizer-rs](https://github.com/0vercl0k/symbolizer-rs). É assim que você simbolizaria o traço de execução `crash-0xfffff764b91c0000-0x0-0xffffbf84fb10e780-0x2-0x0.trace` gerado acima:```
symbolizer-rs.exe --trace crash-0xfffff764b91c0000-0x0-0xffffbf84fb10e780-0x2-0x0.rip.trace

Gerando traços Tenet

Caso precise de mais consciência contextual, o backend bochscpu permite gerar traços de execução que podem ser carregados no explorador de traços Tenet. Abaixo, parto de uma falha em memmove e volto para descobrir de onde vem o ponteiro de origem (modo de usuário!):``` wtf.exe run --name hevd --limit 10000000 --input crashes\crash-0xfffff764b91c0000-0x0-0xffffbf84fb10e780-0x2-0x0 --trace-type=tenet

root@kitploit:~
<p align='center'>
<img src="https://assets.kitploit.com/production/public/readmes/4699/34df2f5ca8f378db664d3f01bcbefdd43409e300d256d50e3f4f630eb06cc7be.webp">
</p>

### Gerando traces de cobertura de código

Para gerar traces de cobertura de código, você pode simplesmente usar o subcomando `run` com a opção `--trace-type=cov`.

É assim que você geraria traces de cobertura de código para todos os arquivos dentro da pasta `minset` e os armazenaria na pasta `coverage-traces`:```
wtf.exe run --name hevd --input minset --trace-path=coverage-traces --trace-type=cov

Esses rastros não são diretamente carregáveis no lighthouse porque não são simbolizados.

É assim que você simbolizaria todos os arquivos dentro da pasta coverage-traces e escreveria os resultados em coverage-traces-symbolized:``` symbolizer-rs.exe --trace coverage-traces -o coverage-traces-symbolized --style modoff

root@kitploit:~
<p align='center'>
<img src="https://assets.kitploit.com/production/public/readmes/4699/8a3c3ca18571abef16a9f87f736fe4d52ac102f41095eab4db32533cb5b198b4.webp">
</p>

E, por fim, você pode carregá-los no [lighthouse](https://github.com/gaasedelen/lighthouse):

<p align='center'>
<img src="https://assets.kitploit.com/production/public/readmes/4699/35d9c25c3d26abf5761fec9e7848ba09d090c7aab32322a740732d82e85964e8.webp">
</p>

Além disso, se você não se importa com a cobertura de código individual, o branch master mantém um arquivo `coverage.cov` que contém a cobertura de código agregada única que foi exercitada. Isso facilita verificar rapidamente a cobertura global durante um job de fuzzing. 

## Como funciona?

**wtf** executa os modos usuário e kernel através de um *backend de execução* e depende do usuário para inserir casos de teste no alvo. Ao contrário de outras ferramentas clássicas de fuzzing, **wtf** não faz grande parte do trabalho pesado; o usuário o faz. O usuário precisa conhecer muito bem o alvo e a adaptação de um alvo é um processo iterativo que levará tempo. No entanto, oferece muita flexibilidade se você estiver pronto para hackear :)

O fluxo de trabalho usual para adaptar um alvo é o seguinte:

1. Faça seu alvo rodar em uma VM Hyper-V com Windows, com uma CPU virtual e 4 GB de RAM.
1. Coloque seu alvo no estado desejado usando [KD](https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/). Por exemplo, para mirar o manipulador de IOCTL do [HEVD](https://github.com/hacksysteam/HackSysExtremeVulnerableDriver), optei por parar o alvo em modo de usuário bem antes de o cliente invocar [DeviceIoControl](https://docs.microsoft.com/en-us/windows/win32/api/ioapiset/nf-ioapiset-deviceiocontrol). Isso variará dependendo dos seus alvos, mas provavelmente você quer que ele esteja próximo ao código que deseja fuzzeá-lo.

    ```
    kd> r
    rax=000000dfd98ff3d0 rbx=0000000000000088 rcx=0000000000000088
    rdx=00000000deadbeef rsi=0000000000000000 rdi=0000000000000000
    rip=00007ff6f5bb111e rsp=000000dfd98ff380 rbp=0000000000000000
    r8=000000dfd98ff3d0  r9=0000000000000400 r10=000002263e823055
    r11=00007ff6f5bcb54d r12=0000000000000000 r13=0000000000000000
    r14=0000000000000000 r15=0000000000000000
    iopl=0         nv up ei pl nz na po nc
    cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206
    hevd_client!main+0xae:
    00007ff6`f5bb111e ff15dc1e0100    call    qword ptr [hevd_client!_imp_DeviceIoControl (00007ff6`f5bc3000)] ds:002b:00007ff6`f5bc3000={KERNEL32!DeviceIoControlImplementation (00007ff8`3e2e6360)}
    ```

1. Use [snapshot](https://github.com/0vercl0k/snapshot) para gerar o crash-dump do kernel, bem como o arquivo `regs.json` que contém o estado da CPU. Recomendo salvar esses arquivos em um diretório `state` dentro do diretório do seu alvo (`targets/hevd/state`, por exemplo):

    ```
    kd> .load c:\work\codes\snapshot\target\release\snapshot.dll

    kd> !snapshot -h
    [snapshot] Usage: snapshot [OPTIONS] [STATE_PATH]

    Arguments:
      [STATE_PATH]  The path to save the snapshot to

    Options:
      -k, --kind <KIND>  The kind of snapshot to take [default: full] [possible values: active-kernel, full]
      -h, --help         Print help

    kd> !snapshot c:\work\codes\wtf\targets\hevd\state
    [snapshot] Dumping the CPU state into c:\work\codes\wtf\targets\hevd\state\regs.json..
    [snapshot] Dumping the memory state into c:\work\codes\wtf\targets\hevd\state\mem.dmp..
    Creating c:\\work\\codes\\wtf\\targets\\hevd\\state\\mem.dmp - Full memory range dump
    0% written.
    5% written. 1 min 50 sec remaining.
    10% written. 1 min 17 sec remaining.
    15% written. 1 min 30 sec remaining.
    [...]
    Wrote 4.0 GB in 1 min 32 sec.
    The average transfer rate was 44.5 MB/s.
    Dump successfully written
    [snapshot] Done!
    ```

1. Crie um [módulo de fuzzer](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_hevd.cc) e escreva o código que [insere um caso de teste](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_hevd.cc#L20) no seu alvo e defina [as](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_hevd.cc#L81) [várias](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_hevd.cc#L104) [condições](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_hevd.cc#L115) para [detectar crashes](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_hevd.cc#L115) ou [o fim de um caso de teste](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_hevd.cc#L69).

1. Você também pode criar seu próprio mutator / generator herdando da interface [Mutator_t](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/mutator.h). O [fuzzer_tlv_server.cc](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_tlv_server.cc) é um bom exemplo para entender como implementar o seu.

Neste ponto, você deve começar a iterar e verificar se o módulo de fuzzer funciona conforme o esperado. Os backends de execução são uma caixa-preta, portanto você deve gerar traces de execução para garantir que ele percorra os caminhos corretos e faça as coisas certas. Durante essa fase, utilizo principalmente o backend [bochscpu](https://github.com/yrp604/bochscpu), pois é totalmente determinístico, inicia rapidamente, é possível gerar traces de execução, a cobertura de código vem de graça, etc. No geral, é um ambiente melhor para desenvolver e prototipar.

Depois de satisfeito com o módulo, você pode começar a buscar fazê-lo funcionar com os backends [winhv](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/whv_backend.h) / [kvm](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/kvm_backend.h) se precisar que ele execute sob eles. Uma grande diferença entre o backend *bochscpu* e os outros é que os outros usam breakpoints de software para fornecer informações de cobertura de código. Como resultado, você precisará carregar os módulos para os quais deseja cobertura no [IDA](https://hex-rays.com/IDA-pro/) e usar o script [gen_coveragefile_ida.py](https://github.com/0vercl0k/wtf/blob/HEAD/scripts/gen_coveragefile_ida.py) para gerar um simples arquivo JSON que é carregado pelo wtf. Você é livre para gerar esse arquivo JSON usando qualquer ferramenta que desejar: basicamente é uma lista de endereços virtuais de blocos básicos.

Você também pode mirar aplicações [WoW64](https://docs.microsoft.com/en-us/windows/win32/winprog64/wow64-implementation-details) usando o comando `!wow64exts.sw` do Windbg para alternar para o contexto de 64 bits imediatamente antes de criar o snapshot (obrigado [@cube0x8](https://twitter.com/cube0x8) por compartilhar esse truque!):```
32.kd:x86> !wow64exts.sw
The context is partially valid. Only x86 user-mode context is available.
Switched to Host mode

32.kd> !snapshot

Como entregar múltiplos pacotes ao meu alvo?

Alvos complexos geralmente também carregam estados complexos e é provável que você precise entregar mais de um caso de teste em uma sessão para desencadear problemas complexos. tlv_server.cc é um exemplo de tal servidor onde exercitar a função de análise com apenas um caso de teste não será suficiente para descobrir os bugs.

Para lidar com este caso, confira fuzzer_tlv_server.cc que mostra um exemplo de como resolver este problema.

Como fornecer um mutador/gerador personalizado?

wtf vem com dois mutadores genéricos populares: libfuzzer e honggfuzz. Você pode querer fornecer o seu próprio ou gerar casos de teste por conta própria também.

Para fazer isso, você pode criar uma subclasse da interface Mutator_t e registrar a função que instancia seu mutador ao definir seu módulo de fuzzing:```c++ class CustomMutator_t : public Mutator_t { public: static std::unique_ptr<Mutator_t> Create(std::mt19937_64 &Rng, const size_t TestcaseMaxSize) { return std::make_unique<CustomMutator_t>(Rng, TestcaseMaxSize); } // ... };

Target_t target("target", Init, InsertTestcase, Restore, CustomMutator_t::Create);

root@kitploit:~
Veja a classe [CustomMutator_t](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_tlv_server.cc) no módulo [fuzzer_tlv_server.cc](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_tlv_server.cc) para um exemplo completo.

## Backends de execução

Nesta seção, menciono brevemente várias diferenças entre os backends de execução.

### bochscpu
- ✅ Cobertura de código de sistema completo (cobertura de aresta disponível via `--edges`),
- ✅ Paginação sob demanda,
- ✅ Timeout é o número de instruções, o que é muito preciso,
- ✅ Traços de execução completos são suportados,
- ✅ Totalmente determinístico,
- ❌A velocidade parece ser boa para execuções curtas, mas não para execuções longas (~100x mais lento que KVM quando estava fuzzeando IDA).

### whv
- ✔ Cobertura de código via breakpoints de software,
- ❌ Paginação sob demanda, então a inicialização é lenta (pois precisa carregar o crash-dump completo na memória),
- ✔ Timeout é implementado com um timer,
- ✅ Traços de execução completos são suportados, mas são lentos (sair do VMX é custoso),
- ✔ Determinístico se tratar manualmente a fonte de não determinismo (por exemplo, corrigindo `nt!ExGenRamdom` que usa `rdrand`),
- ✔ A velocidade parece ser ok para execuções longas (muitos gargalos no whv, no entanto; ~10x mais lento que kvm quando estava fuzzeando IDA).

### KVM
- ✔ Cobertura de código via breakpoints de software,
- ✅ Paginação sob demanda é suportada via UFDD,
- ✔ Timeout é implementado com um timer. ✅ Se o hardware suporta virtualização de PMU, ele é usado para gerar um [PMI](https://forum.osdev.org/viewtopic.php?f=1&t=27040) após X instruções retiradas (`MSR_IA32_FIXED_CTR0`),
- ✅ Traços de execução completos são suportados, mas são lentos (sair do VMX é custoso),
- ✔ Determinístico se tratar manualmente a fonte de não determinismo (por exemplo, corrigindo `nt!ExGenRamdom` que usa `rdrand`),
- ✅ Mais rápido para execuções longas (~500 milhões - 1,5 bilhão de instruções; ~100x mais rápido que *bochscpu*, ~10x mais rápido que *whv* quando estava fuzzeando IDA).

## Compilação

O [CI](https://github.com/0vercl0k/wtf/actions/workflows/wtf.yml) compila o **wtf** no Ubuntu usando tanto [clang++](https://clang.llvm.org/) quanto [g++](https://gcc.gnu.org/gcc-11/), no Windows usando o [Visual Studio](https://visualstudio.microsoft.com/vs/community/) da Microsoft e no OSX usando [clang++](https://clang.llvm.org/).

Para compilar você mesmo, precisa iniciar um *Visual Studio Developer Command Prompt* e executar [build-release.bat](https://github.com/0vercl0k/wtf/blob/HEAD/src/build/build-release.bat) que usa o gerador [Ninja](https://ninja-build.org/) ou [build-release-msvc.bat](https://github.com/0vercl0k/wtf/blob/HEAD/src/build/build-release-msvc.bat) para gerar um arquivo de solução do Visual Studio:```
(base) wtf\src\build>build-release.bat
[...]
[2/2] Linking CXX executable wtf.exe

(base) wtf\src\build_msvc>..\build\build-release-msvc.bat
[...]
  Finished generating code
  wtf.vcxproj -> wtf\src\build_msvc\RelWithDebInfo\wtf.exe
  Building Custom Rule wtf/src/CMakeLists.txt

Autores

  • Axel '0vercl0k' Souchet

Contribuidores

Agradecimentos especiais a:

  • @yrp604 por fornecer contribuições valiosas ao longo do projeto,
  • @masthoon por sugerir escrever um demo direcionado ao modo seguro do HEVD,
  • Markus Gaasedelen por adicionar suporte ao Tenet,
  • @y0ny0ns0n por contribuir com o exemplo de fuzzing multi-input,
  • Colas Le Guernic / Jérémy Rubert / Anônimo por implementar cobertura de arestas para bochscpu,
  • @1ndahous3 por contribuir com o módulo genérico de fuzzer ioctl,
  • Jason Crowder / Kyle Ossinger da Cisco ASIG pelo modo Linux,
  • e a todos os outros contribuidores 🙏

contributors-img

Baixar ferramenta