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
wtf — Fuzzer distribuito, basato su snapshot e guidato dalla copertura del codice per target in modalità utente e kernel su Windows e Linux, con backend emulatore e hypervisor. | Kitploit
Strumenti/GitHubGitHub/0vercl0k/wtf
Analisi Dinamica (Sandboxing)Analisi delle VulnerabilitàExploitFuzzingAnalisi di Binari
GitHub0vercl0k/wtf

wtf

Fuzzer distribuito, basato su snapshot e guidato dalla copertura del codice per target in modalità utente e kernel su Windows e Linux, con backend emulatore e hypervisor.

Vedi Repository
1.8k15415 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

what the fuzz

Un fuzzer distribuito, guidato dalla copertura del codice, cross-platform, basato su snapshot, progettato per attaccare target in modalità utente e/o kernel in esecuzione su Microsoft Windows e Linux in modalità utente (sperimentale!).

Panoramica

what the fuzz o wtf è un fuzzer distribuito, guidato dalla copertura del codice, personalizzabile, cross-platform, basato su snapshot, progettato per attaccare target in modalità utente e/o kernel in esecuzione su Microsoft Windows o Linux (sperimentale, vedere linux_mode). L'esecuzione del target può essere effettuata all'interno di un emulatore con bochscpu (più lento, più preciso), all'interno di una VM Windows con le API Windows Hypervisor Platform o all'interno di una VM Linux con le API KVM (più veloce).

Ha scoperto vulnerabilità di corruzione della memoria in un'ampia gamma di software: IDA Pro, un popolare gioco AAA, il kernel Windows, il client RDP Microsoft, il driver per display GPU NVIDIA, ecc.

I binari compilati sono disponibili sia dagli artefatti CI che dalla sezione Releases sia per Windows che per Linux.

Se desideri saperne di più sulla sua storia o su come usarlo su un target reale, ti consiglio di dare un'occhiata a questi post per iniziare 🔥

  • Costruire un nuovo snapshot fuzzer e fuzzare IDA
  • Fuzzing di protocolli di gioco UDP moderni con snapshot fuzzer di Markus Gaasedelen
  • Fuzzing di RDPEGFX con "what the fuzz" di Colas Le Guernic, Jérémy Rubert e Anonimo
  • Un viaggio nel fuzzing di protocolli di rete – Dissezionare il protocollo client IMAP di Microsoft di Wayne Chin Yick Low
  • La sezione Snapshot Fuzzing del Manuale di Testing di Trail of Bits
  • Attaccare gli EDR Parte 4: Fuzzare il motore di scansione ed emulazione di Defender (mpengine.dll) di Manuel Feifel

Utilizzo

Il modo migliore per provare le funzionalità è lavorare con i moduli fuzzer_hevd / fuzzer_tlv_server. Puoi scaricare gli archivi target-hevd.7z / target-tlv_server.7z ed estrarli nella directory targets/. Gli archivi contengono le strutture di directory previste per ogni target:

  • inputs è la cartella dove inserire i tuoi casi di test di input,
  • outputs è la cartella dove vengono salvati i file minset correnti,
  • coverage è la cartella dove ci si aspetta che siano i file .cov,
  • crashes è dove vengono salvati i crash,
  • state è dove vengono archiviati il dump della memoria (mem.dmp), lo stato della CPU (regs.json) e lo store dei simboli (symbol-store.json). Lo store dei simboli è un semplice file JSON che viene utilizzato sui sistemi Linux per sapere dove posizionare i breakpoint poiché non c'è supporto per simboli / dbgeng su quelle piattaforme. wtf genera questo file in esecuzione ogni volta che esegui il target su Windows.

Quanto segue presuppone che tu abbia scaricato il file target-hevd.7z allegato all'ultima release e lo abbia estratto nella directory targets del tuo clone di wtf. Dovresti avere wtf/targets/hevd in cui trovi le directory inputs / outputs, ecc.

Avviare un nodo server

Il server è fondamentalmente il cervello e tiene traccia di tutto lo stato: la copertura del codice aggregata, il corpus, genera e distribuisce i casi di test al client.

Ecco come potresti scegliere di avviare un nodo server locale:```text wtf.exe master --name hevd --max_len=1028 --runs=10000000

root@kitploit:~
L'opzione `max_len` è usata per limitare la dimensione del test-case generato, `runs` è il numero di test-case che verranno generati, `address` specifica dove **wtf** deve restare in ascolto, `target` è una directory con l'albero delle directory descritto sopra (l'utente può anche scegliere di sovrascrivere quelle directory con `--input` / `--output` / `--crashes`) e `name` specifica il  nome del tuo modulo di fuzzing in modo che il master possa invocare la tua funzione generatrice se ne hai definita una.

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

### Nodi di fuzzing

I nodi client eseguono un test-case che è stato generato e distribuito dal server e comunicano il risultato al server (copertura del codice, risultato, ecc.).

Ecco come si avvia un nodo client che utilizza il backend *bochscpu*:```text
wtf.exe fuzz --name hevd --limit 10000000

Il sottocomando fuzz viene utilizzato con l'opzione name per specificare quale modulo fuzzer deve essere utilizzato, backend specifica il backend di esecuzione e limit il numero massimo di istruzioni da eseguire per test case (a seconda del backend, questa opzione ha un significato diverso).

Esecuzione di un test-case

Se desideri eseguire un test-case (o una cartella piena di test-case), puoi utilizzare il sottocomando run.

Ecco come eseguiresti il test-case 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>

### Minset di un corpus

Per eseguire il minset di un corpus, è necessario utilizzare un nodo server e tanti nodi client quanti necessari, come si farebbe per un lavoro di fuzzing. Puoi semplicemente impostare l'opzione `runs` a 0.

Ecco come eseguire il minset del corpus in `outputs` nella directory `minset` (mostra anche come sovrascrivere le directory `inputs` e `outputs`):```
wtf.exe master --name hevd --max_len=1028 --runs=0 --inputs=outputs --outputs=minset

Generazione di tracce di esecuzione

Il meccanismo principale disponibile per ispezionare in un backend di esecuzione è generare una traccia di esecuzione. bochscpu è il backend più veloce per farlo, perché uscire dalla modalità VMX è molto costoso negli altri backend.

Ecco come genereresti una traccia di esecuzione per il test-case 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>

Per simbolizzare le tracce di esecuzione dovresti usare [symbolizer-rs](https://github.com/0vercl0k/symbolizer-rs). Ecco come simbolizzeresti la traccia di esecuzione `crash-0xfffff764b91c0000-0x0-0xffffbf84fb10e780-0x2-0x0.trace` generata sopra:```
symbolizer-rs.exe --trace crash-0xfffff764b91c0000-0x0-0xffffbf84fb10e780-0x2-0x0.rip.trace

Generazione di tracce Tenet

Se hai bisogno di maggiore consapevolezza contestuale, il backend bochscpu ti permette di generare tracce di esecuzione che possono essere caricate nell'esploratore di tracce Tenet. Qui sotto, parto da un crash in memmove e torno indietro per scoprire da dove proviene il puntatore sorgente (user-mode!):``` 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>

### Generazione di tracce di copertura del codice

Per generare tracce di copertura del codice puoi semplicemente usare il sottocomando `run` con l'opzione `--trace-type=cov`.

Ecco come generare tracce di copertura del codice per tutti i file all'interno della cartella `minset` e salvarle nella cartella `coverage-traces`:```
wtf.exe run --name hevd --input minset --trace-path=coverage-traces --trace-type=cov

Queste tracce non sono direttamente caricabili in lighthouse perché non sono simbolizzate.

Ecco come simbolizzare tutti i file all'interno della cartella coverage-traces e scrivere i risultati in 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 infine, puoi caricare questi file in [lighthouse](https://github.com/gaasedelen/lighthouse):

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

Inoltre, se non ti interessa la copertura del codice individuale, il master mantiene un file `coverage.cov` che contiene la copertura aggregata unica del codice che è stata esercitata. Semplifica la verifica rapida della copertura globale durante un lavoro di fuzzing.

## Come funziona?

**wtf** esegue la modalità utente e kernel attraverso un *execution backend* e si affida all'utente per inserire i casi di test nel target. A differenza di altri strumenti di fuzzing classici, **wtf** non fa gran parte del lavoro pesante; lo fa l'utente. L'utente deve conoscere molto bene il target e l'onboarding di un target è un processo iterativo che richiede tempo. Offre comunque molta flessibilità se sei pronto a metterti all'opera :)

Il flusso di lavoro usuale per preparare un target è il seguente:

1. Esegui il tuo target in una VM Hyper-V con Windows, con una CPU virtuale e 4GB di RAM.
1. Porta il tuo target nello stato desiderato usando [KD](https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/). Ad esempio, per targettare il gestore IOCTL di [HEVD](https://github.com/hacksysteam/HackSysExtremeVulnerableDriver), ho scelto di fermare il target in modalità utente appena prima che il client invochi [DeviceIoControl](https://docs.microsoft.com/en-us/windows/win32/api/ioapiset/nf-ioapiset-deviceiocontrol). Questo varia a seconda dei target, ma probabilmente vorrai essere vicino al codice che vuoi fuzzare.

    ```
    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. Usa [snapshot](https://github.com/0vercl0k/snapshot) per generare il dump di crash del kernel e il file `regs.json` che contiene lo stato della CPU. Raccomando di salvare questi file in una directory `state` sotto la tua directory `target` (ad esempio `targets/hevd/state`):

    ```
    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. Crea un [modulo fuzzer](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_hevd.cc), scrivi il codice che [inserisce un caso di test](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_hevd.cc#L20) nel target e definisci [le](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_hevd.cc#L81) [varie](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_hevd.cc#L104) [condizioni](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_hevd.cc#L115) per [rilevare crash](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_hevd.cc#L115) o [la fine di un caso di test](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_hevd.cc#L69).

1. Puoi anche creare il tuo mutatore/generatore sottoclassando l'interfaccia [Mutator_t](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/mutator.h). Il [fuzzer_tlv_server.cc](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_tlv_server.cc) è un buon esempio per capire come implementare il tuo.

A questo punto dovresti iniziare a iterare e verificare che il modulo fuzzer funzioni come previsto. I back-end di esecuzione sono una scatola nera, quindi dovresti generare tracce di esecuzione per assicurarti che percorra i percorsi giusti e faccia le cose giuste. Durante questa fase uso principalmente il backend [bochscpu](https://github.com/yrp604/bochscpu) perché è completamente deterministico, si avvia velocemente, è possibile generare tracce di esecuzione, la copertura del codice è gratuita, ecc. Nel complesso, è un ambiente più piacevole per sviluppare e prototipare.

Una volta che sei soddisfatto del modulo, puoi iniziare a considerare di farlo funzionare con i backend [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 hai bisogno che funzioni sotto di essi. Una differenza importante tra il backend *bochscpu* e gli altri è che gli altri usano breakpoint software per fornire informazioni sulla copertura del codice. Di conseguenza, dovrai caricare i moduli per cui vuoi la copertura in [IDA](https://hex-rays.com/IDA-pro/) e usare lo script [gen_coveragefile_ida.py](https://github.com/0vercl0k/wtf/blob/HEAD/scripts/gen_coveragefile_ida.py) per generare un semplice file JSON che viene caricato da wtf. Sei libero di generare tu stesso questo file JSON con qualsiasi strumento: è fondamentalmente un elenco di indirizzi virtuali di blocchi di base.

Puoi anche targettare applicazioni [WoW64](https://docs.microsoft.com/en-us/windows/win32/winprog64/wow64-implementation-details) usando il comando `!wow64exts.sw` di Windbg per passare al contesto a 64-bit appena prima di creare lo snapshot (grazie a [@cube0x8](https://twitter.com/cube0x8) per aver condiviso questo trucco!):```
32.kd:x86> !wow64exts.sw
The context is partially valid. Only x86 user-mode context is available.
Switched to Host mode

32.kd> !snapshot

Come inviare più pacchetti al mio target?

I target complessi solitamente hanno anche stati complessi ed è probabile che tu debba inviare più di un testcase in una sessione per innescare problemi complessi. tlv_server.cc è un esempio di un server di questo tipo in cui esercitare la funzione di parsing con un solo testcase non è sufficiente per scoprire i bug.

Per gestire questo caso, dai un'occhiata a fuzzer_tlv_server.cc che mostra un esempio di come risolvere questo problema.

Come fornire un mutator / generatore personalizzato?

wtf viene fornito con due popolari mutator generici: libfuzzer e honggfuzz. Potresti voler fornire il tuo o generare testcase autonomamente.

Per farlo, puoi creare una sottoclasse dell'interfaccia Mutator_t e registrare la funzione che istanzia il tuo mutator quando definisci il tuo modulo di 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:~
Dai un'occhiata alla classe [CustomMutator_t](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_tlv_server.cc) nel modulo [fuzzer_tlv_server.cc](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_tlv_server.cc) per un esempio completo.

## Execution backends

In questa sezione menziono brevemente varie differenze tra i backend di esecuzione.

### bochscpu
- ✅ Copertura completa del codice di sistema (copertura degli edge disponibile tramite `--edges`),
- ✅ Demand-paging,
- ✅ Timeout è il numero di istruzioni, molto preciso,
- ✅ Tracciamento completo delle esecuzioni supportato,
- ✅ Completamente deterministico,
- ❌ Velocità sembra buona per esecuzioni brevi ma non per esecuzioni lunghe (~100x più lento di KVM quando fuzzavo IDA).

### whv
- ✔ Copertura del codice tramite breakpoint software,
- ❌ Demand-paging, quindi l'avvio è lento (poiché deve caricare l'intero crash-dump in memoria),
- ✔ Timeout implementato con un timer,
- ✅ Tracciamento completo delle esecuzioni supportato ma lento (l'uscita da VMX è costosa),
- ✔ Deterministico se si gestisce manualmente la fonte di non deterministico (ad esempio, patchando `nt!ExGenRamdom` che usa `rdrand`),
- ✔ Velocità sembra ok per esecuzioni lunghe (molti colli di bottiglia in whv comunque; ~10x più lento di kvm quando fuzzavo IDA).

### KVM
- ✔ Copertura del codice tramite breakpoint software,
- ✅ Demand-paging supportato tramite UFDD,
- ✔ Timeout implementato con un timer. ✅ Se l'hardware supporta la virtualizzazione PMU, viene utilizzato per generare un [PMI](https://forum.osdev.org/viewtopic.php?f=1&t=27040) dopo X istruzioni ritirate (`MSR_IA32_FIXED_CTR0`),
- ✅ Tracciamento completo delle esecuzioni supportato ma lento (l'uscita da VMX è costosa),
- ✔ Deterministico se si gestisce manualmente la fonte di non deterministico (ad esempio, patchando `nt!ExGenRamdom` che usa `rdrand`),
- ✅ Più veloce per esecuzioni lunghe (~500m - 1.5 miliardi di istruzioni; ~100x più veloce di *bochscpu*, ~10x più veloce di *whv* quando fuzzavo IDA).

## Build

La [CI](https://github.com/0vercl0k/wtf/actions/workflows/wtf.yml) compila **wtf** su Ubuntu usando sia [clang++](https://clang.llvm.org/) che [g++](https://gcc.gnu.org/gcc-11/), su Windows usando [Visual Studio](https://visualstudio.microsoft.com/vs/community/) di Microsoft e su OSX usando [clang++](https://clang.llvm.org/).

Per compilarlo da solo devi avviare un *Visual Studio Developper Command Prompt* ed eseguire [build-release.bat](https://github.com/0vercl0k/wtf/blob/HEAD/src/build/build-release.bat) che usa il generatore [Ninja](https://ninja-build.org/) oppure [build-release-msvc.bat](https://github.com/0vercl0k/wtf/blob/HEAD/src/build/build-release-msvc.bat) per generare un file di soluzione di 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

Autori

  • Axel '0vercl0k' Souchet

Contributori

Un ringraziamento speciale a:

  • @yrp604 per aver fornito preziosi suggerimenti durante tutto il progetto,
  • @masthoon per aver suggerito di scrivere una demo che mirasse alla modalità sicura di HEVD,
  • Markus Gaasedelen per aver aggiunto il supporto a Tenet,
  • @y0ny0ns0n per aver contribuito con l'esempio di fuzzing multi-input,
  • Colas Le Guernic / Jérémy Rubert / Anonimo per aver implementato la copertura degli archi per bochscpu,
  • @1ndahous3 per aver contribuito con il modulo generico di fuzzing per ioctl,
  • Jason Crowder / Kyle Ossinger di Cisco ASIG per la modalità Linux,
  • e tutti gli altri contributori 🙏

contributors-img

Scarica lo strumento