wtf v0.5.1 releases: cross-platform snapshot-based fuzzer designed for attacking user/ kernel-mode targets
what the fuzz
what the fuzz or wtf is a distributed, code-coverage guided, customizable, cross-platform snapshot-based fuzzer designed for attacking user and or kernel-mode targets running on Microsoft Windows. Execution of the target can be done inside an emulator with bochscpu (slowest, most precise), inside a Windows VM with the Windows Hypervisor Platform APIs, or inside a Linux VM with KVM APIs (fastest).
It uncovered memory corruption vulnerabilities in a wide range of softwares: IDA Pro, a popular AAA game, the Windows kernel, HEVD secure mode, etc.
Compiled binaries are available from the CI artifacts for both Windows & Linux or from the Release section.
Special thanks to @yrp604 for providing valuable inputs throughout the project and @masthoon for suggesting to write a demo targeting HEVD secure mode.
How it works
wtf runs user & kernel-mode through an execution backend and relies on the user to insert test-cases in the target. Unlike other classical fuzzer tools, wtf doesn’t do much of the heavy lifting; the user does. The user needs to know the harnessed target very well and onboarding a target is an iterative process that will take time. It has a lot of flexibility to offer if you are ready to get hacking though 🙂
The usual workflow to harness a target is as follows:
- Get your target running into a Hyper-V VM running Windows with one virtual CPU and 4GB of RAM,
- Put your target into the desired state using KD. For example, to target HEVD‘s IOCTL handler, I chose to stop the target in user-mode right before the client invokes DeviceIoControl. This will vary depending on your targets but you probably want it to be close to the code you want to fuzz.
- Use bdump.js to generate the kernel crash-dump as well as the
regs.json
file that contains the CPU state. I recommend to dump those file in astate
directory under yourtarget
directory (targets/hevd/state
for example): - Create a fuzzer module, write the code that inserts a test-case into your target and define the various conditions to detect crashes or the end of a test-case.
At this point, you should start to iterate and verify that the fuzzer module works as expected. The execution backends are a blackbox so you should generate execution traces to make sure it goes through the right paths, does the right things. During this phase I mainly use the bochscpu backend as it is fully deterministic, starts fast, generating execution traces is possible, code-coverage comes for free, etc. Overall, it’s a nicer environment to develop and prototype in.
Once you are satisfied with the module, you can start to look at making it work with the winhv / kvm backends if you need it to run under those. One major difference between the bochscpu backend & the others, is that the others use software breakpoints to provide code-coverage information. As a result, you’ll need to load the modules you want coverage for under IDA and use the gen_coveragefile_ida.py script to generate a simple JSON file that gets loaded by wtf. You are free to generate this JSON file yourself using whatever tool you would like: it basically is a list of basic-blocks virtual addresses.
Changelog v0.5.1
- Explicitly pass the size of the requested arguments by @1ndahous3 in #188
- Update
kdmp-parser
to v0.7.1 by @0vercl0k in #190
Use
Copyright (c) 2021 Axel Souchet