Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
wtf — Fuzzer distribuido, guiado por cobertura de código y basado en instantáneas para objetivos en modo usuario y kernel en Windows y Linux, con backends de emulador e hipervisor. | Kitploit
Herramientas/GitHubGitHub/0vercl0k/wtf
Análisis Dinámico (Sandboxing)Análisis de VulnerabilidadesExplotaciónFuzzingAnálisis de Binarios
GitHub0vercl0k/wtf

wtf

Fuzzer distribuido, guiado por cobertura de código y basado en instantáneas para objetivos en modo usuario y kernel en Windows y Linux, con backends de emulador e hipervisor.

Ver Repositorio
1.8k154hace 14 díasRevisado por Kitploit

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

what the fuzz

Un fuzzer distribuido, guiado por cobertura de código, basado en instantáneas y multiplataforma, diseñado para atacar objetivos en modo usuario y/o núcleo que se ejecuten en Microsoft Windows y modo usuario de Linux (¡experimental!).

Descripción general

what the fuzz o wtf es un fuzzer distribuido, guiado por cobertura de código, personalizable, basado en instantáneas y multiplataforma, diseñado para atacar objetivos en modo usuario y/o núcleo que se ejecuten en Microsoft Windows o Linux (experimental, consulte linux_mode). La ejecución del objetivo se puede realizar dentro de un emulador con bochscpu (el más lento, el más preciso), dentro de una máquina virtual de Windows con las APIs de la Plataforma de Hipervisor de Windows o dentro de una máquina virtual de Linux con las APIs de KVM (la más rápida).

Ha descubierto vulnerabilidades de corrupción de memoria en una amplia gama de software: IDA Pro, un popular juego AAA, el kernel de Windows, el cliente RDP de Microsoft, el controlador de pantalla GPU de NVIDIA, etc.

Los binarios compilados están disponibles tanto desde los artefactos de CI como desde la sección de Lanzamientos para Windows y Linux.

Si desea leer más sobre su historia o cómo usarlo en un objetivo real, recomiendo echar un vistazo a estas publicaciones para comenzar 🔥

  • Construyendo un nuevo fuzzer de instantáneas y fuzzing de IDA
  • Fuzzing de protocolos modernos de juegos UDP con fuzzers basados en instantáneas por Markus Gaasedelen
  • Fuzzing de RDPEGFX con "what the fuzz" por Colas Le Guernic, Jérémy Rubert y Anonymous
  • Un viaje al fuzzing de protocolos de red – Diseccionando el protocolo de cliente IMAP de Microsoft por Wayne Chin Yick Low
  • La sección de Fuzzing de instantáneas del Manual de pruebas de Trail of Bits
  • Atacando EDRs Parte 4: Fuzzing del motor de escaneo y emulación de Defender (mpengine.dll) por Manuel Feifel

Uso

La mejor manera de probar las características es trabajar con los módulos fuzzer_hevd / fuzzer_tlv_server. Puede descargar los archivos target-hevd.7z / target-tlv_server.7z y extraerlos en el directorio targets/. Los archivos contienen los árboles de directorios esperados para cada objetivo:

  • inputs es la carpeta donde se colocan los casos de prueba de entrada,
  • outputs es la carpeta donde se guardan los archivos del minset actual,
  • coverage es la carpeta donde se espera que estén los archivos .cov,
  • crashes es donde se guardan los fallos,
  • state es donde se almacenan el volcado de memoria (mem.dmp), el estado de la CPU (regs.json) y el almacén de símbolos (symbol-store.json). El almacén de símbolos es un simple archivo JSON que se utiliza en sistemas Linux para saber dónde colocar puntos de interrupción, ya que no hay soporte para símbolos / dbgeng en esas plataformas. wtf genera este archivo en tiempo de ejecución cada vez que se ejecuta el objetivo en Windows.

Lo que sigue asume que ha descargado el archivo target-hevd.7z adjunto a la última versión y lo ha extraído en el directorio targets de su clon de wtf. Debería tener wtf/targets/hevd en el que encontrará los directorios inputs / outputs, etc.

Iniciando un nodo servidor

El servidor es básicamente el cerebro y realiza un seguimiento de todo el estado: la cobertura de código agregada, el corpus, genera y distribuye los casos de prueba al cliente.

Así es como podría elegir lanzar un nodo servidor local:```text wtf.exe master --name hevd --max_len=1028 --runs=10000000

root@kitploit:~
La opción `max_len` se utiliza para limitar el tamaño del caso de prueba generado, `runs` es el número de casos de prueba que generará, `address` especifica dónde debe escuchar **wtf**, `target` es un directorio con el árbol de directorio que describimos anteriormente (el usuario también puede optar por sobrescribir esos directorios con `--input` / `--output` / `--crashes`) y `name` especifica el nombre de tu módulo de fuzzing para que el maestro pueda invocar tu función generadora si has definido una.

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

### Nodos de fuzzing

Los nodos cliente ejecutan un caso de prueba que ha sido generado y distribuido por el servidor y comunican el resultado de vuelta al servidor (cobertura de código, resultado, etc.).

Así es como iniciarías un nodo cliente que utiliza el backend *bochscpu*:

wtf client --address localhost:26001 --corpus /tmp/corpus --crashes /tmp/crashes

root@kitploit:~
wtf.exe fuzz --name hevd --limit 10000000
```
El subcomando `fuzz` se utiliza con la opción `name` para especificar qué módulo de fuzzing debe usarse, `backend` especifica el backend de ejecución y `limit` el número máximo de instrucciones a ejecutar por caso de prueba (dependiendo del backend, esta opción tiene un significado diferente).

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

### Ejecutar un caso de prueba

Si desea ejecutar un caso de prueba (o una carpeta llena de casos de prueba), puede usar el subcomando `run`.

Así es como se ejecutaría el caso de prueba `crash-0xfffff764b91c0000-0x0-0xffffbf84fb10e780-0x2-0x0`:

```bash
$AFL_BASE/afl-fuzz -S secondary_instance -i /path/to/seeds -o output_dir ./program

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>

### Minseting a corpus

Para minset un corpus, necesitas usar un nodo servidor y tantos nodos cliente como necesites, igual que harías para un trabajo de fuzzing. Puedes simplemente establecer las opciones `runs` a 0.

Así es como minsetarías el corpus en `outputs` dentro del directorio `minset` (también destaca cómo puedes sobrescribir los directorios `inputs` y `outputs`):```
wtf.exe master --name hevd --max_len=1028 --runs=0 --inputs=outputs --outputs=minset

Generación de trazas de ejecución

El mecanismo principal disponible para inspeccionar en un backend de ejecución es generar una traza de ejecución. bochscpu es el backend más rápido para hacerlo, porque salir del modo VMX es muy costoso en los otros backends.

Así es como se generaría una traza de ejecución para el caso de prueba 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 los rastros de ejecución deberías usar [symbolizer-rs](https://github.com/0vercl0k/symbolizer-rs). Así es como simbolizarías el rastro de ejecución `crash-0xfffff764b91c0000-0x0-0xffffbf84fb10e780-0x2-0x0.trace` generado anteriormente:```
symbolizer-rs.exe --trace crash-0xfffff764b91c0000-0x0-0xffffbf84fb10e780-0x2-0x0.rip.trace

Generando trazas de Tenet

Si necesitas más conciencia contextual, el backend bochscpu te permite generar trazas de ejecución que se pueden cargar en el explorador de trazas Tenet. A continuación, comienzo desde un fallo en memmove y retrocedo para descubrir de dónde proviene el puntero de origen (¡modo usuario!):``` 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>

### Generación de trazas de cobertura de código

Para generar trazas de cobertura de código, puedes usar simplemente el subcomando `run` con la opción `--trace-type=cov`.

Así es como generarías trazas de cobertura de código para todos los archivos dentro de la carpeta `minset` y las almacenarías en la carpeta `coverage-traces`:```
wtf.exe run --name hevd --input minset --trace-path=coverage-traces --trace-type=cov

Esos traces no se pueden cargar directamente en lighthouse porque no están simbolizados.

Así es como simbolizarías todos los archivos dentro de la carpeta coverage-traces y escribirías los resultados en 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>

Y finalmente, puedes cargarlos en [lighthouse](https://github.com/gaasedelen/lighthouse):

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

Además, si no te importa la cobertura de código individual, el *master* mantiene un archivo `coverage.cov` que contiene la cobertura de código agregada única que se ha ejercitado. Facilita verificar rápidamente la cobertura de código global durante un trabajo de fuzzing.

## ¿Cómo funciona?

**wtf** ejecuta modo usuario y modo kernel a través de un *backend de ejecución* y depende del usuario para insertar casos de prueba en el objetivo. A diferencia de otras herramientas clásicas de fuzzing, **wtf** no hace gran parte del trabajo pesado; el usuario lo hace. El usuario necesita conocer muy bien el objetivo instrumentado y la incorporación de un objetivo es un proceso iterativo que llevará tiempo. Sin embargo, ofrece mucha flexibilidad si estás listo para ponerte manos a la obra :)

El flujo de trabajo habitual para instrumentar un objetivo es el siguiente:

1. Haz que tu objetivo funcione en una máquina virtual Hyper-V con Windows, una CPU virtual y 4 GB de RAM.
1. Pon tu objetivo en el estado deseado usando [KD](https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/). Por ejemplo, para apuntar al manejador de IOCTL de [HEVD](https://github.com/hacksysteam/HackSysExtremeVulnerableDriver), elegí detener el objetivo en modo usuario justo antes de que el cliente invoque [DeviceIoControl](https://docs.microsoft.com/en-us/windows/win32/api/ioapiset/nf-ioapiset-deviceiocontrol). Esto variará según tu objetivo, pero probablemente quieras que esté cerca del código que deseas fuzzear.

    ```
    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) para generar el volcado de memoria del kernel y el archivo `regs.json` que contiene el estado de la CPU. Recomiendo guardar esos archivos en un directorio `state` dentro de tu directorio `target` (por ejemplo, `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 [módulo de fuzzing](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_hevd.cc), escribe el código que [inserta un caso de prueba](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_hevd.cc#L20) en tu objetivo y define [las](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_hevd.cc#L81) [diversas](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_hevd.cc#L104) [condiciones](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) o [el final de un caso de prueba](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_hevd.cc#L69).

1. También puedes crear tu propio mutador/generador subclasificando la interfaz [Mutator_t](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/mutator.h). El [fuzzer_tlv_server.cc](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_tlv_server.cc) es un buen ejemplo para entender cómo implementar el tuyo propio.

En este punto deberías empezar a iterar y verificar que el módulo de fuzzing funciona como se espera. Los backends de ejecución son una caja negra, por lo que deberías generar trazas de ejecución para asegurarte de que pasa por las rutas correctas y hace lo correcto. Durante esta fase, uso principalmente el backend [bochscpu](https://github.com/yrp604/bochscpu) ya que es completamente determinista, se inicia rápido, es posible generar trazas de ejecución, la cobertura de código viene de forma gratuita, etc. En general, es un entorno más agradable para desarrollar y prototipar.

Una vez que estés satisfecho con el módulo, puedes empezar a ver cómo hacerlo funcionar con los 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) si necesitas que se ejecute bajo ellos. Una diferencia importante entre el backend *bochscpu* y los otros es que los otros usan *breakpoints* de software para proporcionar información de cobertura de código. Como resultado, necesitarás cargar los módulos para los que deseas cobertura en [IDA](https://hex-rays.com/IDA-pro/) y usar el script [gen_coveragefile_ida.py](https://github.com/0vercl0k/wtf/blob/HEAD/scripts/gen_coveragefile_ida.py) para generar un archivo JSON simple que será cargado por wtf. Eres libre de generar este archivo JSON tú mismo usando cualquier herramienta que desees: básicamente es una lista de direcciones virtuales de bloques básicos.

También puedes apuntar a aplicaciones [WoW64](https://docs.microsoft.com/en-us/windows/win32/winprog64/wow64-implementation-details) usando el comando `!wow64exts.sw` de Windbg para cambiar al contexto de 64 bits justo antes de crear la instantánea (¡gracias a [@cube0x8](https://twitter.com/cube0x8) por compartir este truco!):```
32.kd:x86> !wow64exts.sw
The context is partially valid. Only x86 user-mode context is available.
Switched to Host mode

32.kd> !snapshot

¿Cómo entregar múltiples paquetes a mi objetivo?

Los objetivos complejos suelen tener también estados complejos, y es probable que necesites entregar más de un caso de prueba en una sesión para desencadenar problemas complejos. El archivo tlv_server.cc es un ejemplo de un servidor de este tipo, donde ejercitar la función de análisis con un solo caso de prueba no será suficiente para descubrir los errores.

Para manejar este caso, consulta fuzzer_tlv_server.cc que muestra un ejemplo de cómo resolver este problema.

¿Cómo proporcionar un mutador/generador personalizado?

wtf incluye dos mutadores genéricos populares: libfuzzer & honggfuzz. Es posible que quieras proporcionar el tuyo propio o generar casos de prueba por tu cuenta.

Para hacerlo, puedes subclasificar la interfaz Mutator_t y registrar la función que instancia tu mutador cuando definas tu 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:~
Consulte la clase [CustomMutator_t](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_tlv_server.cc) en el módulo [fuzzer_tlv_server.cc](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_tlv_server.cc) para un ejemplo completo.

## Backends de ejecución

En esta sección menciono brevemente varias diferencias entre los backends de ejecución.

### bochscpu
- ✅ Cobertura de código de sistema completo (cobertura de aristas disponible mediante `--edges`),
- ✅ Paginación bajo demanda,
- ✅ El tiempo de espera es el número de instrucciones, lo cual es muy preciso,
- ✅ Se admiten trazas completas de ejecución,
- ✅ Completamente determinista,
- ❌Speed parece buena para ejecuciones cortas pero no para largas (~100x más lento que KVM cuando fuzzeaba IDA).

### whv
- ✔ Cobertura de código mediante puntos de interrupción de software,
- ❌ Paginación bajo demanda, por lo que el inicio es lento (ya que necesita cargar el volcado de memoria completo en la memoria),
- ✔ El tiempo de espera se implementa con un temporizador,
- ✅ Se admiten trazas completas de ejecución pero son lentas (salir de VMX es costoso),
- ✔ Determinista si se maneja manualmente la fuente de no determinismo (por ejemplo, parcheando `nt!ExGenRamdom` que usa `rdrand`),
- ✔ La velocidad parece estar bien para ejecuciones largas (aunque hay muchos cuellos de botella en whv; ~10x más lento que kvm cuando fuzzeaba IDA).

### KVM
- ✔ Cobertura de código mediante puntos de interrupción de software,
- ✅ La paginación bajo demanda es compatible mediante UFDD,
- ✔ El tiempo de espera se implementa con un temporizador. ✅ Si el hardware soporta virtualización PMU, se utiliza para generar un [PMI](https://forum.osdev.org/viewtopic.php?f=1&t=27040) después de X instrucciones retiradas (`MSR_IA32_FIXED_CTR0`),
- ✅ Se admiten trazas completas de ejecución pero son lentas (salir de VMX es costoso),
- ✔ Determinista si se maneja manualmente la fuente de no determinismo (por ejemplo, parcheando `nt!ExGenRamdom` que usa `rdrand`),
- ✅ El más rápido para ejecuciones largas (~500m - 1.5 mil millones de instrucciones; ~100x más rápido que *bochscpu*, ~10x más rápido que *whv* cuando fuzzeaba IDA).

## Build

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

Para compilarlo usted mismo, necesita iniciar un *Símbolo del sistema para desarrolladores de Visual Studio* y ejecutar ya sea [build-release.bat](https://github.com/0vercl0k/wtf/blob/HEAD/src/build/build-release.bat) que usa el generador [Ninja](https://ninja-build.org/) o [build-release-msvc.bat](https://github.com/0vercl0k/wtf/blob/HEAD/src/build/build-release-msvc.bat) para generar un archivo de solución de 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

Agradecimientos especiales a:

  • @yrp604 por proporcionar valiosas aportaciones a lo largo del proyecto,
  • @masthoon por sugerir escribir una demo orientada al modo seguro de HEVD,
  • Markus Gaasedelen por añadir soporte para Tenet,
  • @y0ny0ns0n por contribuir con el ejemplo de fuzzing multi-entrada,
  • Colas Le Guernic / Jérémy Rubert / Anonymous por implementar la cobertura de bordes para bochscpu,
  • @1ndahous3 por contribuir con el módulo de fuzzing genérico de ioctl,
  • Jason Crowder / Kyle Ossinger de Cisco ASIG por el modo Linux,
  • y todos los demás colaboradores 🙏

contributors-img

Descargar herramienta