Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
wtf — Распределённый, управляемый покрытием кода, основанный на снимках фаззер для целей в пользовательском режиме и режиме ядра на Windows и Linux, с эмуляторными и гипервизорными бэкендами. | Kitploit
Инструменты/GitHubGitHub/0vercl0k/wtf
Динамический анализ (песочница)Анализ уязвимостейЭксплуатацияФаззингАнализ Бинарных Файлов
GitHub0vercl0k/wtf

wtf

Распределённый, управляемый покрытием кода, основанный на снимках фаззер для целей в пользовательском режиме и режиме ядра на Windows и Linux, с эмуляторными и гипервизорными бэкендами.

Репозиторий
1.8k15415 дней назадПроверено Kitploit

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

what the fuzz

Распределённый, управляемый покрытием кода, кроссплатформенный фаззер на основе снимков, предназначенный для атаки на цели в пользовательском и/или режиме ядра, работающие под управлением Microsoft Windows и Linux (экспериментально!).

Обзор

what the fuzz или wtf — это распределённый, управляемый покрытием кода, настраиваемый, кроссплатформенный фаззер на основе снимков, предназначенный для атаки на цели в пользовательском и/или режиме ядра, работающие под управлением Microsoft Windows или Linux (экспериментально, см. linux_mode). Выполнение цели может осуществляться внутри эмулятора с помощью bochscpu (самый медленный, наиболее точный), внутри виртуальной машины Windows с использованием Windows Hypervisor Platform APIs или внутри виртуальной машины Linux с использованием KVM APIs (самый быстрый).

Он выявил уязвимости повреждения памяти в широком спектре программного обеспечения: IDA Pro, популярная AAA-игра, ядро Windows, клиент Microsoft RDP, драйвер дисплея NVIDIA GPU и др.

Скомпилированные бинарные файлы доступны либо из артефактов CI, либо из раздела Releases как для Windows, так и для Linux.

Если вы хотите узнать больше об истории проекта или о том, как использовать его на реальной цели, рекомендую ознакомиться с этими статьями, чтобы начать 🔥

  • Building a new snapshot fuzzer & fuzzing IDA
  • Fuzzing Modern UDP Game Protocols With Snapshot-based Fuzzers от Markus Gaasedelen
  • Fuzzing RDPEGFX with "what the fuzz" от Colas Le Guernic, Jérémy Rubert и Анонима
  • A Journey to Network Protocol Fuzzing – Dissecting Microsoft IMAP Client Protocol от Wayne Chin Yick Low
  • Раздел Snapshot Fuzzing из Testing Handbook компании Trail Of Bits
  • Attacking EDRs Part 4: Fuzzing Defender's Scanning and Emulation Engine (mpengine.dll) от Manuel Feifel

Использование

Лучший способ опробовать возможности — поработать с модулями fuzzer_hevd / fuzzer_tlv_server. Вы можете скачать архивы target-hevd.7z / target-tlv_server.7z и извлечь их в каталог targets/. Архивы содержат структуру каталогов, ожидаемую для каждой цели:

  • inputs — папка, куда помещаются ваши входные тестовые примеры,
  • outputs — папка, куда сохраняются текущие файлы minset,
  • coverage — папка, в которой ожидаются файлы .cov,
  • crashes — папка, куда сохраняются аварийные завершения,
  • state — папка, где хранятся дамп памяти (mem.dmp), состояние ЦП (regs.json) и хранилище символов (symbol-store.json). Хранилище символов — это простой файл JSON, используемый в системах Linux для указания мест установки точек останова, поскольку на этих платформах нет поддержки символов / dbgeng. wtf генерирует этот файл во время выполнения каждый раз, когда вы запускаете цель на Windows.

Далее предполагается, что вы скачали файл target-hevd.7z, прикреплённый к последнему релизу, и извлекли его в каталог targets вашего клона wtf. У вас должен появиться путь wtf/targets/hevd, в котором находятся каталоги inputs, outputs и т.д.

Запуск серверного узла

Сервер, по сути, является мозгом и отслеживает всё состояние: агрегированное покрытие кода, корпус, генерирует и распространяет тестовые примеры среди клиентов.

Вот как вы можете запустить локальный серверный узел:```text wtf.exe master --name hevd --max_len=1028 --runs=10000000

root@kitploit:~
Опция `max_len` используется для ограничения размера генерируемого тестового примера, `runs` — количество генерируемых тестовых примеров, `address` указывает, где **wtf** должен прослушивать, `target` — это директория с деревом каталогов, которое мы описали выше (пользователь также может переопределить эти директории с помощью `--input` / `--output` / `--crashes`), а `name` задает имя вашего модуля фаззинга, чтобы мастер мог вызвать вашу функцию-генератор, если вы ее определили.

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

### Узлы фаззинга

Клиентские узлы запускают тестовый пример, сгенерированный и распределенный сервером, и передают результат обратно серверу (покрытие кода, результат и т.д.).

Вот как вы запустите клиентский узел, использующий бэкенд *bochscpu*:```text
wtf.exe fuzz --name hevd --limit 10000000

Подкоманда fuzz используется с опцией name, чтобы указать, какой модуль фаззера нужно использовать; backend задаёт бэкенд выполнения, а limit — максимальное количество инструкций для выполнения на один тестовый пример (в зависимости от бэкенда значение этой опции различается).

Запуск тестового примера

Если вы хотите запустить тестовый пример (или папку, заполненную тестовыми примерами), вы можете использовать подкоманду run.

Вот как вы могли бы бы запустить тестовый пример crash-0xfffff764b91c0000-0x0-0xffffbf84fb10e780-0x2-0x0: $HOME/FUZZAN/fuzzer.py $HOME/FUZZAN/seeds/example $HOME/FUZZAN/workdir/ -b frida -t 60000 -m 10000 -p 1000 -c -v $HOME/FUZZAN/workdir/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>

### Minseting корпуса

Для minset корпуса необходимо использовать серверный узел и столько клиентских узлов, сколько нужно, как при фаззинге. Вы можете просто установить `runs` optins в 0.

Вот как вы можете minset корпус из `outputs` в директорию `minset` (также показано, как переопределять директории `inputs` и `outputs`):```
wtf.exe master --name hevd --max_len=1028 --runs=0 --inputs=outputs --outputs=minset

Генерация трасс выполнения

Основной механизм, доступный для интроспекции в бэкенде выполнения, — это генерация трассы выполнения. bochscpu — это самый быстрый бэкенд для этого, поскольку выход из режима VMX очень затратен для других бэкендов.

Вот как вы можете сгенерировать трассу выполнения для тестового случая 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>

Для символизации трасс выполнения следует использовать [symbolizer-rs](https://github.com/0vercl0k/symbolizer-rs). Вот как можно символизировать трассу выполнения `crash-0xfffff764b91c0000-0x0-0xffffbf84fb10e780-0x2-0x0.trace`, сгенерированную выше:```
symbolizer-rs.exe --trace crash-0xfffff764b91c0000-0x0-0xffffbf84fb10e780-0x2-0x0.rip.trace

Генерация трасс Tenet

Если вам требуется более широкая контекстная осведомленность, бэкенд bochscpu позволяет генерировать трассы выполнения, которые можно загрузить в Tenet — проводник трасс. В примере ниже я начинаю с сбоя в memmove и возвращаюсь назад, чтобы выяснить, откуда берется исходный указатель (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>

### Генерация трасс покрытия кода

Чтобы сгенерировать трассы покрытия кода, вы можете просто использовать подкоманду `run` с опцией `--trace-type=cov`.

Вот как можно сгенерировать трассы покрытия кода для всех файлов внутри папки `minset` и сохранить их в папку `coverage-traces`:```
wtf.exe run --name hevd --input minset --trace-path=coverage-traces --trace-type=cov

Эти трассировки невозможно напрямую загрузить в lighthouse, так как они не символизованы.

Вот как можно символизовать все файлы внутри папки coverage-traces и записать результаты в 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>

И наконец, вы можете загрузить их в [lighthouse](https://github.com/gaasedelen/lighthouse):

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

Также, если вас не интересует индивидуальное покрытие кода, главный процесс поддерживает файл `coverage.cov`, содержащий уникальное агрегированное покрытие кода, которое было отработано. Это позволяет быстро проверять глобальное покрытие кода во время работы фаззера.

## Как это работает?

**wtf** работает в пользовательском и режиме ядра через *execution backend* и полагается на пользователя для вставки тестовых примеров в цель. В отличие от других классических инструментов фаззинга, **wtf** не выполняет большую часть тяжелой работы — это делает пользователь. Пользователь должен очень хорошо знать целевую программу, и подключение цели — это итеративный процесс, который займет время. Однако он предлагает большую гибкость, если вы готовы заняться хакингом :)

Обычный рабочий процесс для подключения цели выглядит следующим образом:

1. Запустите вашу цель в виртуальной машине Hyper-V с Windows, одним виртуальным процессором и 4 ГБ ОЗУ.
1. Приведите цель в нужное состояние с помощью [KD](https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/). Например, для атаки на обработчик IOCTL драйвера [HEVD](https://github.com/hacksysteam/HackSysExtremeVulnerableDriver) я остановил цель в пользовательском режиме непосредственно перед вызовом клиентом [DeviceIoControl](https://docs.microsoft.com/en-us/windows/win32/api/ioapiset/nf-ioapiset-deviceiocontrol). Это будет зависеть от ваших целей, но, вероятно, вы захотите остановиться как можно ближе к коду, который хотите фаззить.

    ```
    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. Используйте [snapshot](https://github.com/0vercl0k/snapshot) для создания дампа ядра при сбое и файла `regs.json`, содержащего состояние ЦП. Рекомендую сохранять эти файлы в каталоге `state` внутри вашего каталога `target` (например, `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. Создайте [модуль фаззера](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_hevd.cc), напишите код, который [вставляет тестовый пример](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_hevd.cc#L20) в вашу цель, и определите [различные](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_hevd.cc#L81) [условия](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_hevd.cc#L104) [для обнаружения сбоев](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_hevd.cc#L115) или [окончания тестового примера](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_hevd.cc#L69).

1. Вы также можете создать свой собственный мутатор/генератор, унаследовавшись от интерфейса [Mutator_t](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/mutator.h). Файл [fuzzer_tlv_server.cc](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_tlv_server.cc) — хороший пример, чтобы понять, как можно реализовать свой собственный.

На этом этапе вы должны начать итеративно проверять, что модуль фаззера работает как ожидается. Исполнительные бэкенды — это черный ящик, поэтому вам следует генерировать трассы выполнения, чтобы убедиться, что код проходит по правильным путям и делает правильные вещи. На этом этапе я в основном использую бэкенд [bochscpu](https://github.com/yrp604/bochscpu), так как он полностью детерминирован, быстро запускается, позволяет генерировать трассы выполнения, покрытие кода получается автоматически и т.д. В целом, это более удобная среда для разработки и прототипирования.

Когда вы будете удовлетворены модулем, можно начать настраивать его работу с бэкендами [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), если вам нужно запускать его под ними. Одно из основных отличий бэкенда *bochscpu* от других заключается в том, что другие используют программные точки останова для получения информации о покрытии кода. В результате вам потребуется загрузить модули, для которых нужно покрытие, в [IDA](https://hex-rays.com/IDA-pro/) и использовать скрипт [gen_coveragefile_ida.py](https://github.com/0vercl0k/wtf/blob/HEAD/scripts/gen_coveragefile_ida.py) для создания простого JSON-файла, который загружается wtf. Вы можете сгенерировать этот JSON-файл самостоятельно с помощью любого другого инструмента: по сути, это список виртуальных адресов базовых блоков.

Вы также можете нацеливаться на приложения [WoW64](https://docs.microsoft.com/en-us/windows/win32/winprog64/wow64-implementation-details), используя команду `!wow64exts.sw` в Windbg для переключения в 64-битный контекст непосредственно перед созданием снимка (спасибо [@cube0x8](https://twitter.com/cube0x8) за этот трюк!):```
32.kd:x86> !wow64exts.sw
The context is partially valid. Only x86 user-mode context is available.
Switched to Host mode

32.kd> !snapshot

Как доставлять несколько пакетов к моей цели?

Сложные цели обычно имеют сложное состояние, и, скорее всего, вам потребуется доставить более одного тесткейса в сессии, чтобы вызвать сложные проблемы. tlv_server.cc — пример такого сервера, где выполнение функции разбора только с одним тесткейсом не позволит обнаружить ошибки.

Чтобы справиться с этой задачей, посмотрите fuzzer_tlv_server.cc, который показывает пример решения этой проблемы.

Как предоставить собственный мутатор/генератор?

wtf включает два популярных общих мутатора: libfuzzer и honggfuzz. Возможно, вы захотите предоставить свой собственный или генерировать тесткейсы самостоятельно.

Для этого вы можете создать подкласс интерфейса Mutator_t и зарегистрировать функцию, которая создает экземпляр вашего мутатора, при определении вашего модуля фаззинга:```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:~
Посмотрите на класс [CustomMutator_t](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_tlv_server.cc) в модуле [fuzzer_tlv_server.cc](https://github.com/0vercl0k/wtf/blob/HEAD/src/wtf/fuzzer_tlv_server.cc) для полного примера.

## Бэкенды выполнения

В этом разделе я кратко упомяну различные различия между бэкендами выполнения.

### bochscpu
- ✅ Полное покрытие кода всей системы (покрытие граней доступно через `--edges`),
- ✅ Страничная подкачка по требованию,
- ✅ Таймаут — это количество инструкций, что очень точно,
- ✅ Полные трассы выполнения поддерживаются,
- ✅ Полностью детерминировано,
- ❌Скорость кажется хорошей для коротких выполнений, но не для длинных (~в 100 раз медленнее, чем KVM, когда я фаззил IDA).

### whv
- ✔ Покрытие кода через программные точки останова,
- ❌ Страничная подкачка по требованию, поэтому запуск медленный (так как нужно загрузить полный дамп краша в память),
- ✔ Таймаут реализован с помощью таймера,
- ✅ Полные трассы выполнения поддерживаются, но они медленные (выход из VMX затратен),
- ✔ Детерминировано при ручной обработке источника недетерминизма (например, патч `nt!ExGenRamdom`, использующего `rdrand`),
- ✔ Скорость кажется приемлемой для длительных выполнений (хотя в whv много узких мест; ~в 10 раз медленнее, чем kvm, когда я фаззил IDA).

### KVM
- ✔ Покрытие кода через программные точки останова,
- ✅ Страничная подкачка по требованию поддерживается через UFDD,
- ✔ Таймаут реализован с помощью таймера. ✅ Если оборудование поддерживает виртуализацию PMU, она используется для генерации [PMI](https://forum.osdev.org/viewtopic.php?f=1&t=27040) после X завершённых инструкций (`MSR_IA32_FIXED_CTR0`),
- ✅ Полные трассы выполнения поддерживаются, но они медленные (выход из VMX затратен),
- ✔ Детерминировано при ручной обработке источника недетерминизма (например, патч `nt!ExGenRamdom`, использующего `rdrand`),
- ✅ Самый быстрый для длительных выполнений (~500 млн - 1.5 млрд инструкций; ~в 100 раз быстрее, чем *bochscpu*, ~в 10 раз быстрее, чем *whv*, когда я фаззил IDA).

## Сборка

Система [CI](https://github.com/0vercl0k/wtf/actions/workflows/wtf.yml) собирает **wtf** на Ubuntu с использованием как [clang++](https://clang.llvm.org/) / [g++](https://gcc.gnu.org/gcc-11/), на Windows с использованием [Visual Studio](https://visualstudio.microsoft.com/vs/community/) от Microsoft и на OSX с использованием [clang++](https://clang.llvm.org/).

Чтобы собрать его самостоятельно, нужно запустить *Командную строку разработчика Visual Studio* и либо запустить [build-release.bat](https://github.com/0vercl0k/wtf/blob/HEAD/src/build/build-release.bat), который использует генератор [Ninja](https://ninja-build.org/), либо [build-release-msvc.bat](https://github.com/0vercl0k/wtf/blob/HEAD/src/build/build-release-msvc.bat) для создания файла решения 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

Авторы

  • Axel '0vercl0k' Souchet

Участники

Особая благодарность:

  • @yrp604 за ценные идеи на протяжении всего проекта,
  • @masthoon за предложение написать демо для HEVD в защищённом режиме,
  • Markus Gaasedelen за добавление поддержки Tenet,
  • @y0ny0ns0n за вклад в пример фаззинга с множественными входами,
  • Colas Le Guernic / Jérémy Rubert / Anonymous за реализацию покрытия границ для bochscpu,
  • @1ndahous3 за вклад в модуль фаззинга ioctl общего назначения,
  • Jason Crowder / Kyle Ossinger из Cisco ASIG за режим Linux,
  • и всех остальных участников 🙏

contributors-img

Скачать инструмент