Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
Outils/GitHubGitHub/0vercl0k/wtf
Analyse Dynamique (Sandboxing)Analyse des VulnérabilitésExploitationFuzzingAnalyse de Binaires
GitHub0vercl0k/wtf

wtf

Distribué, fuzzer basé sur des instantanés guidé par la couverture de code pour cibles en mode utilisateur et noyau sur Windows et Linux, avec backends d'émulateur et d'hyperviseur.

Voir le dépôt
1.8k154il y a 15 joursVérifié par Kitploit

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

what the fuzz

Un fuzzer distribué, guidé par la couverture de code, basé sur des instantanés, multiplateforme, conçu pour attaquer des cibles en mode utilisateur et/ou noyau s'exécutant sur Microsoft Windows et Linux en mode utilisateur (expérimental !).

Aperçu

what the fuzz ou wtf est un fuzzer distribué, guidé par la couverture de code, personnalisable, basé sur des instantanés, multiplateforme, conçu pour attaquer des cibles en mode utilisateur et/ou noyau s'exécutant sur Microsoft Windows ou Linux (expérimental, voir linux_mode). L'exécution de la cible peut se faire dans un émulateur avec bochscpu (le plus lent, le plus précis), dans une VM Windows avec les API Windows Hypervisor Platform ou dans une VM Linux avec les API KVM (le plus rapide).

Il a découvert des vulnérabilités de corruption mémoire dans un large éventail de logiciels : IDA Pro, un jeu AAA populaire, le noyau Windows, le client RDP Microsoft, le pilote d'affichage GPU NVIDIA, etc.

Les binaires compilés sont disponibles soit via les artefacts CI, soit dans la section Releases pour Windows et Linux.

Si vous souhaitez en savoir plus sur son histoire ou comment l'utiliser sur une cible réelle, je vous recommande de consulter ces articles pour commencer 🔥

  • Construction d'un nouveau fuzzer par instantané et fuzzing d'IDA
  • Fuzzing des protocoles de jeux UDP modernes avec des fuzzers par instantané par Markus Gaasedelen
  • Fuzzing de RDPEGFX avec "what the fuzz" par Colas Le Guernic, Jérémy Rubert, et Anonymous
  • Un voyage dans le fuzzing de protocoles réseau – Dissection du protocole client IMAP Microsoft par Wayne Chin Yick Low
  • La section Snapshot Fuzzing du Testing Handbook de Trail Of Bits
  • Attaquer les EDRs Partie 4 : Fuzzing du moteur d'analyse et d'émulation de Defender (mpengine.dll) par Manuel Feifel

Utilisation

La meilleure façon d'essayer les fonctionnalités est de travailler avec les modules fuzzer_hevd / fuzzer_tlv_server. Vous pouvez télécharger les archives target-hevd.7z / target-tlv_server.7z et les extraire dans le répertoire targets/. Les archives contiennent les arborescences de répertoires attendues pour chaque cible :

  • inputs est le dossier où sont placés vos cas de test d'entrée,
  • outputs est le dossier où sont sauvegardés les fichiers minset actuels,
  • coverage est le dossier où les fichiers .cov doivent se trouver,
  • crashes est le dossier où les crashes sont sauvegardés,
  • state est le dossier où sont stockés le dump mémoire (mem.dmp), l'état du CPU (regs.json) et le magasin de symboles (symbol-store.json). Le magasin de symboles est un simple fichier JSON utilisé sur les systèmes Linux pour savoir où placer les points d'arrêt, car il n'y a pas de support pour les symboles / dbgeng sur ces plateformes. wtf génère ce fichier à l'exécution chaque fois que vous exécutez votre cible sur Windows.

Ce qui suit suppose que vous avez téléchargé le fichier target-hevd.7z joint à la dernière version, et que vous l'avez extrait dans le répertoire targets de votre clone de wtf. Vous devriez avoir wtf/targets/hevd dans lequel vous trouverez les répertoires inputs / outputs, etc.

Démarrage d'un nœud serveur

Le serveur est essentiellement le cerveau et garde la trace de tout l'état : la couverture de code agrégée, le corpus, il génère et distribue les cas de test au client.

Voici comment vous pourriez lancer un nœud serveur local :```text wtf.exe master --name hevd --max_len=1028 --runs=10000000

root@kitploit:~
L'option `max_len` est utilisée pour limiter la taille du cas de test généré, `runs` est le nombre de cas de test qui seront générés, `address` spécifie où **wtf** doit écouter, `target` est un répertoire contenant l'arborescence de répertoires que nous avons décrite ci-dessus (l'utilisateur peut également choisir de remplacer ces répertoires avec `--input` / `--output` / `--crashes`) et `name` spécifie le nom de votre module de fuzzing afin que le maître puisse invoquer votre fonction génératrice si vous en avez défini une.

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

### Nœuds de fuzzing

Les nœuds clients exécutent un cas de test qui a été généré et distribué par le serveur et communiquent le résultat au serveur (couverture de code, résultat, etc.).

Voici comment démarrer un nœud client qui utilise le backend *bochscpu* :```text
wtf.exe fuzz --name hevd --limit 10000000

La sous-commande fuzz est utilisée avec l'option name pour spécifier quel module de fuzzing doit être utilisé, backend spécifie le backend d'exécution et limit le nombre maximum d'instructions à exécuter par testcase (selon le backend, cette option a une signification différente).

Exécution d'un test-case

Si vous souhaitez exécuter un test-case (ou un dossier rempli de test-cases), vous pouvez utiliser la sous-commande run.

Voici comment exécuter le 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 d'un corpus

Pour minseter un corpus, vous devez utiliser un nœud serveur et autant de nœuds clients que nécessaire, comme pour un job de fuzzing. Vous pouvez simplement définir l'option `runs` à 0.

Voici comment minseter le corpus dans `outputs` vers le répertoire `minset` (cela montre également comment vous pouvez remplacer les répertoires `inputs` et `outputs`) :```
wtf.exe master --name hevd --max_len=1028 --runs=0 --inputs=outputs --outputs=minset

Génération de traces d'exécution

Le principal mécanisme disponible pour introspecter un backend d'exécution est de générer une trace d'exécution. bochscpu est le backend le plus rapide pour le faire, car la sortie du mode VMX est très coûteuse sur les autres backends.

Voici comment générer une trace d'exécution pour le cas de test 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>

Pour symboliser les traces d'exécution, vous devriez utiliser [symbolizer-rs](https://github.com/0vercl0k/symbolizer-rs). Voici comment vous symboliseriez la trace d'exécution `crash-0xfffff764b91c0000-0x0-0xffffbf84fb10e780-0x2-0x0.trace` générée ci-dessus :```
symbolizer-rs.exe --trace crash-0xfffff764b91c0000-0x0-0xffffbf84fb10e780-0x2-0x0.rip.trace

Génération des traces Tenet

Si vous avez besoin de plus de conscience contextuelle, le backend bochscpu vous permet de générer des traces d'exécution qui peuvent être chargées dans l'explorateur de traces Tenet. Dans ce qui suit, je pars d'un crash dans memmove et je remonte pour découvrir d'où vient le pointeur source (mode utilisateur !) :``` 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>

### Génération des traces de couverture de code

Pour générer des traces de couverture de code, vous pouvez simplement utiliser la sous-commande `run` avec l'option `--trace-type=cov`.

Voici comment générer des traces de couverture de code pour tous les fichiers du dossier `minset` et les stocker dans le dossier `coverage-traces` :

```bash
stilf run minset --trace-type=cov -o coverage-traces

wtf.exe run --name hevd --input minset --trace-path=coverage-traces --trace-type=cov

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

Ces traces ne sont pas directement chargeables dans [lighthouse](https://github.com/gaasedelen/lighthouse) car elles ne sont pas symbolisées.

Voici comment symboliser tous les fichiers du dossier `coverage-traces` et écrire les résultats dans `coverage-traces-symbolized` :```
symbolizer-rs.exe --trace coverage-traces -o coverage-traces-symbolized --style modoff

Et enfin, vous pouvez les charger dans lighthouse :

De plus, si la couverture de code individuelle ne vous intéresse pas, le master maintient un fichier coverage.cov qui contient la couverture de code agrégée unique qui a été exercée. Cela permet de vérifier rapidement la couverture de code globale pendant une session de fuzzing.

Comment ça fonctionne ?

wtf exécute les modes utilisateur et noyau via un moteur d'exécution et repose sur l'utilisateur pour insérer des cas de test dans la cible. Contrairement à d'autres outils de fuzzing classiques, wtf ne fait pas l'essentiel du travail ; c'est l'utilisateur qui le fait. L'utilisateur doit bien connaître la cible instrumentée et l'intégration d'une cible est un processus itératif qui prend du temps. Cependant, il offre une grande flexibilité si vous êtes prêt à vous lancer dans le hacking :)

Le flux de travail habituel pour instrumenter une cible est le suivant :

  1. Faites fonctionner votre cible dans une VM Hyper-V sous Windows avec un CPU virtuel et 4 Go de RAM.

  2. Mettez votre cible dans l'état souhaité à l'aide de KD. Par exemple, pour cibler le gestionnaire IOCTL de HEVD, j'ai choisi d'arrêter la cible en mode utilisateur juste avant que le client n'invoque DeviceIoControl. Cela varie selon vos cibles, mais vous voudrez probablement être proche du code que vous souhaitez fuzzer.

    root@kitploit:~
    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)}
    
  3. Utilisez snapshot pour générer le minidump du noyau ainsi que le fichier regs.json contenant l'état du CPU. Je recommande de placer ces fichiers dans un répertoire state sous votre répertoire target (par exemple, ) :

À ce stade, vous devriez commencer à itérer et vérifier que le module de fuzzer fonctionne comme prévu. Les moteurs d'exécution sont une boîte noire, vous devriez donc générer des traces d'exécution pour vous assurer qu'ils passent par les bons chemins et font les bonnes actions. Pendant cette phase, j'utilise principalement le backend bochscpu car il est entièrement déterministe, démarre rapidement, permet de générer des traces d'exécution, la couverture de code est gratuite, etc. Dans l'ensemble, c'est un environnement plus agréable pour développer et prototyper.

Une fois que vous êtes satisfait du module, vous pouvez commencer à envisager de le faire fonctionner avec les backends winhv / kvm si vous avez besoin qu'il s'exécute sous ceux-ci. Une différence majeure entre le backend bochscpu et les autres est que les autres utilisent des points d'arrêt logiciels pour fournir des informations de couverture de code. Par conséquent, vous devrez charger les modules dont vous souhaitez la couverture dans IDA et utiliser le script gen_coveragefile_ida.py pour générer un simple fichier JSON qui sera chargé par wtf. Vous êtes libre de générer ce fichier JSON vous-même avec l'outil de votre choix : il s'agit essentiellement d'une liste d'adresses virtuelles de blocs de base.

Vous pouvez également cibler les applications WoW64 en utilisant la commande !wow64exts.sw de Windbg pour basculer vers le contexte 64 bits juste avant de créer l'instantané (merci @cube0x8 d'avoir partagé cette astuce !) :``` 32.kd:x86> !wow64exts.sw The context is partially valid. Only x86 user-mode context is available. Switched to Host mode

32.kd> !snapshot

root@kitploit:~
## Comment livrer plusieurs paquets à ma cible ?

Les cibles complexes ont généralement des états complexes également et il est probable que vous ayez besoin de livrer plus d'un testcase dans une session pour déclencher des problèmes complexes. [tlv_server.cc](https://github.com/0vercl0k/wtf/blob/HEAD/src/tlv_server/tlv_server.cc) est un exemple d'un tel serveur où l'exercice de la fonction d'analyse avec un seul testcase ne suffira pas à découvrir les bugs.

Pour gérer ce cas, consultez [fuzzer_tlv_server.cc](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_tlv_server.cc) qui montre un exemple de comment résoudre ce problème.

## Comment fournir un mutateur / générateur personnalisé ?

**wtf** est livré avec deux mutateurs génériques populaires : [libfuzzer](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/mutator.h) & [honggfuzz](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/mutator.h). Vous voudrez peut-être fournir le vôtre ou générer des testcases par vous-même également.

Pour ce faire, vous pouvez sous-classer l'interface [Mutator_t](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/mutator.h), et enregistrer la fonction qui instancie votre mutateur lorsque vous définissez votre module 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);

Consultez la classe CustomMutator_t dans le module fuzzer_tlv_server.cc pour un exemple complet.

Backends d'exécution

Dans cette section, je mentionne brièvement diverses différences entre les backends d'exécution.

bochscpu

  • ✅ Couverture de code en mode complet système (couverture des arêtes disponible via --edges),
  • ✅ Demand-paging,
  • ✅ Le délai d'attente est le nombre d'instructions, ce qui est très précis,
  • ✅ Les traces d'exécution complètes sont prises en charge,
  • ✅ Entièrement déterministe,
  • ❌ La vitesse semble bonne pour les exécutions courtes mais pas pour les longues exécutions (~100x plus lent que KVM lorsque je fuzzais IDA).

whv

  • ✔ Couverture de code via points d'arrêt logiciels,
  • ❌ Demand-paging donc le démarrage est lent (car il doit charger le crash-dump complet en mémoire),
  • ✔ Le délai d'attente est implémenté avec une minuterie,
  • ✅ Les traces d'exécution complètes sont prises en charge mais sont lentes (sortir de VMX est coûteux),
  • ✔ Déterministe si l'on gère manuellement la source de non-déterminisme (par exemple, en patchant nt!ExGenRamdom qui utilise rdrand),
  • ✔ La vitesse semble correcte pour les longues exécutions (beaucoup de goulots d'étranglement dans whv cependant ; ~10x plus lent que KVM lorsque je fuzzais IDA).

KVM

  • ✔ Couverture de code via points d'arrêt logiciels,
  • ✅ Le Demand-paging est pris en charge via UFDD,
  • ✔ Le délai d'attente est implémenté avec une minuterie. ✅ Si le matériel prend en charge la virtualisation du PMU, il est utilisé pour générer un PMI après X instructions retirées (MSR_IA32_FIXED_CTR0),
  • ✅ Les traces d'exécution complètes sont prises en charge mais sont lentes (sortir de VMX est coûteux),
  • ✔ Déterministe si l'on gère manuellement la source de non-déterminisme (par exemple, en patchant nt!ExGenRamdom qui utilise rdrand),
  • ✅ Le plus rapide pour les longues exécutions (~500m - 1,5 milliard d'instructions ; ~100x plus rapide que bochscpu, ~10x plus rapide que whv lorsque je fuzzais IDA).

Build

Le CI construit wtf sur Ubuntu en utilisant à la fois clang++ / g++, sur Windows en utilisant Visual Studio de Microsoft et sur OSX en utilisant clang++.

Pour le construire vous-même, vous devez lancer une Invite de commandes développeur Visual Studio et exécuter soit build-release.bat qui utilise le générateur Ninja, soit build-release-msvc.bat pour générer un fichier solution 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

root@kitploit:~
## Auteurs

* Axel '[0vercl0k](https://twitter.com/0vercl0k)' Souchet

## Contributeurs

Remerciements particuliers à :
- [@yrp604](https://github.com/yrp604) pour avoir fourni des contributions précieuses tout au long du projet,
- [@masthoon](https://github.com/masthoon) pour avoir suggéré d'écrire une démo ciblant le mode sécurisé de [HEVD](https://github.com/hacksysteam/HackSysExtremeVulnerableDriver),
- [Markus Gaasedelen](https://github.com/0vercl0k/wtf/pull/12/) pour avoir ajouté le support de Tenet,
- [@y0ny0ns0n](https://github.com/y0ny0ns0n) pour avoir contribué l'exemple de fuzzing multi-entrées (https://github.com/0vercl0k/wtf/pull/67),
- [Colas Le Guernic](https://github.com/clslgrnc) / Jérémy Rubert / Anonyme pour avoir implémenté la couverture de bords pour bochscpu (https://github.com/0vercl0k/wtf/pull/137),
- [@1ndahous3](https://github.com/1ndahous3) pour avoir contribué le module de fuzzer ioctl générique (https://github.com/0vercl0k/wtf/pull/155),
- Jason Crowder / [Kyle Ossinger](https://k0ss.net/) de Cisco ASIG pour le mode Linux (https://github.com/0vercl0k/wtf/pull/192),
- et tous les autres contributeurs 🙏

[ ![contributors-img](https://contrib.rocks/image?repo=0vercl0k/wtf) ](https://github.com/0vercl0k/wtf/graphs/contributors)
Télécharger l’outil
targets/hevd/state
root@kitploit:~
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!
  • Créez un module de fuzzer, écrivez le code qui insère un cas de test dans votre cible et définissez les différentes conditions pour détecter les crashs ou la fin d'un cas de test.

  • Vous pouvez également créer votre propre mutateur/générateur en sous-classant l'interface Mutator_t. Le fichier fuzzer_tlv_server.cc est un bon exemple pour comprendre comment implémenter le vôtre.