wtf v0.3.2 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).
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.jsonfile that contains the CPU state. I recommend to dump those file in a
statedirectory under your
- 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.
- Add 32bit function return simulate by @y0ny0ns0n in #96
- Move the fs hooks from ntdll to nt. by @0vercl0k in #108
- Update the CI for clang15 and codeql-v2 by @0vercl0k in #113
- Improve README and fix #109 by @0vercl0k in #110
- Allow dumps larger than 4GB but warn the user that this is an unconventional configuration by @0vercl0k in #114
- Grab the bugcheck code as part of crash detection and fix rdrand opcode detection by @0vercl0k in #115
Copyright (c) 2021 Axel Souchet