0vercl0k / wtf

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 and Linux user-mode (experimental!).
MIT License
1.47k stars 132 forks source link

The corpus is empty, exiting #189

Closed Flerov closed 11 months ago

Flerov commented 12 months ago

Hey, I hope to get some insight into what I'm doing wrong. I am new to fuzzing and not much familiar with wtf, bochscpu. From what I have hopefully understood corrrectly: bochscpu as a backend provides full-coverage so no .cov files need to be generated.

When I issue wtf.exe fuzz --backend=bochscpu --name rltk --limit 10000000 I get the output

Setting @fptw to 0xff'ff.
Initializing the debugger instance.. (this takes a bit of time)
Setting debug register status to zero.
Setting debug register status to zero.
Dialing to tcp://localhost:31337/..
Could not receive size (-1)
Receive failed
#1 cov: 0 exec/s: 0.0 lastcov: 3.0s crash: 0 timeout: 1 cr3: 0 uptime: 3.0s

And the server exits. Where Cov is 0 which is odd to me. I really appreciate any help :)

I am fuzzing my own driver's code. In my driver_target.c in the InsertTestcase function I can successfully obtain the Rax-Register and from there traverse to my DataBuffer. Where then I perform a VirtWriteDirty. The function returns succesfully.

In case you need to see some code of my fuzzer module let me know. I hope I have provided enough information to get help. Cheers

0vercl0k commented 12 months ago

Hey!

I am currently on vacation so haven't had time to look closely at your issue. But based on what you are describing your testcase seems to not execute a single instruction (as you can see in 'cov: 0') but triggers a timeout interestingly. So something is wrong.

I'd recommend trying to grab a RIP trace to get a bit more understanding of what your testcase is doing. I would also recommend trying to remove code in your InsertTestcase function and see if you are able to execute any code

Cheers

On Sun, Nov 19, 2023 at 12:57 AM zyphex @.***> wrote:

Hey, I hope to get some insight into what I'm doing wrong. I am new to fuzzing and not much familiar with wtf, bochscpu. From what I have hopefully understood corrrectly: bochscpu as a backend provides full-coverage so no .cov files need to be generated.

When I issue wtf.exe fuzz --backend=bochscpu --name rltk --limit 10000000 I get the output

Setting @fptw to 0xff'ff. Initializing the debugger instance.. (this takes a bit of time) Setting debug register status to zero. Setting debug register status to zero. Dialing to tcp://localhost:31337/.. Could not receive size (-1) Receive failed

1 cov: 0 exec/s: 0.0 lastcov: 3.0s crash: 0 timeout: 1 cr3: 0 uptime: 3.0s

And the server exits. Where Cov is 0 which is odd to me. I really appreciate any help :)

I am fuzzing my own driver's code. In my driver_target.c in the InsertTestcase function I can successfully obtain the Rax-Register and from there traverse to my DataBuffer. Where then I perform a VirtWriteDirty. The function returns succesfully.

In case you need to see some code of my fuzzer module let me know. I hope I have provided enough information to get help. Cheers

— Reply to this email directly, view it on GitHub https://github.com/0vercl0k/wtf/issues/189, or unsubscribe https://github.com/notifications/unsubscribe-auth/AALIOROVCZCPC22XOLEGMWDYFFDNTAVCNFSM6AAAAAA7RJVUGWVHI2DSMVQWIX3LMV43ASLTON2WKOZSGAYDANRSGUYDCNQ . You are receiving this because you are subscribed to this thread.Message ID: @.***>

Big-Champ commented 11 months ago

I also seem to be having this exact issue. For a bit of background, I'm using WHV for the backend and took a snapshot using bdump.js in WinDBG preview on a HyperV VM with 4G ram and 1 core. Earlier I was having an issue where my memory dumps weren't being read in, but after further investigation I discovered it was due to this issue: https://github.com/0vercl0k/wtf/issues/101 and I resolved it by adding code from https://github.com/hugsy/kdmp-parser/tree/new_type_support

The output and server exiting described by Flerov is exactly what I am experiencing. I did a virtual read of RIP at Init and InsertTestCase within my harness and they both returned the correct bytes. I should also mention that both of those functions are stripped down to the bare minimum, with Init only setting the end breakpoint and InsertTestCase not actually modifying the state of the program.

Any help would be greatly appreciated.

0vercl0k commented 11 months ago

In order for wtf to measure code-coverage with WHV you need to generate a metadata file that contains the addresses of every basic block - one-shot breakpoints will be set at those addresses to measure coverage. If you don't do this, then the engine has no way to know what is executed. This means all your inputs will generate no coverage data so wtf bails out as it means something is wrong.

Let me know if this helps.

Cheers

On Sat, Nov 25, 2023 at 5:03 AM Big-Champ @.***> wrote:

I also seem to be having this exact issue. For a bit of background, I'm using WHV for the backend and took a snapshot using bdump.js in WinDBG preview on a HyperV VM with 4G ram and 1 core. Earlier I was having an issue where my memory dumps weren't being read in, but after further investigation I discovered it was due to this issue: #101 https://github.com/0vercl0k/wtf/issues/101 and I resolved it by adding code from https://github.com/hugsy/kdmp-parser/tree/new_type_support

The output and server exiting describes exactly what I am experiencing. I did a virtual read of RIP at Init and InsertTestCase within my harness and they both returned the correct bytes. I should also mention that both of those functions are stripped down to the bare minimum, with Init only setting the end breakpoint and InsertTestCase not actually modifying the state of the program.

Any help would be greatly appreciated.

— Reply to this email directly, view it on GitHub https://github.com/0vercl0k/wtf/issues/189#issuecomment-1826207139, or unsubscribe https://github.com/notifications/unsubscribe-auth/AALIORJPASO3NXJMUV44RTDYGFUYBAVCNFSM6AAAAAA7RJVUGWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQMRWGIYDOMJTHE . You are receiving this because you commented.Message ID: @.***>

Big-Champ commented 11 months ago

Hmmm I see. After copying the HEVD.cov file into my target directory I can see it's trying to apply coverage breakpoints now, so that is most likely the issue. I've tried to run gen_coveragefile_ida.py by loading it as a script in IDA but it's throwing an error at line 6392 "AttributeError: 'NoneType' object has no attribute 'Characteristics'". I couldn't really find any documentation for this script so I'm not sure if my setup is incorrect.

I'm running IDA Pro 7.5 with python3

0vercl0k commented 11 months ago

The expected way to run this script is to open HEVD.sys (for example) in IDA and then run the script via the File / run menu. I also can't remember if I tested it out on the 7.5 version (which is getting old).

Cheers

Big-Champ commented 11 months ago

Ok, that's the method I've been using to run it (while also having the correct IDB open). I know pretty much nothing about ida python API. Any pointers on what my issue may be? Exact stacktrace + error is:

error: Traceback (most recent call last): File "", line 6416, in File "", line 6392, in main AttributeError: 'NoneType' object has no attribute 'Characteristics'

0vercl0k commented 11 months ago

Hmmm, it seems like https://github.com/0vercl0k/wtf/blob/main/scripts/gen_coveragefile_ida.py#L6391 returns None? The loop basically goes through every functions that IDA found, and then try to find PE section in which it belongs and it isn't finding any which I don't think I've run into.

Are you looking at some kind of special executable? Is this a user-mode application or kernel-mode?

You can also try to replace:

            discardable = (sect.Characteristics & SECTION_CHARACTERISTICS['IMAGE_SCN_MEM_DISCARDABLE']) != 0

by:

            discardable = (sect is not None) and (sect.Characteristics & SECTION_CHARACTERISTICS['IMAGE_SCN_MEM_DISCARDABLE']) != 0

And see if it does the trick!

Cheers

Big-Champ commented 11 months ago

This worked! Coverage breakpoints were added successfully

Unrelated to this issue, is it possible to load coverage to a module that isn't loaded in the dump file used for the state? For example, say you breakpoint on a user-mode process and you know it will send an IOCTL that will later send input to a second user-mode process. If you wanted to track the coverage for both user-mode processes, how would you do this? I've noticed that loading coverage will fail if it can't find the base. I'm guessing this is because when you scope into a process using .Process it won't contain modules of other processes

0vercl0k commented 11 months ago

You're correct - generally speaking wtf you won't let you cross the process boundary. In theory, you could probably make it work assuming all the physical memory is available in the dump. In practice, if the cr3 register is changed / if the current thread is getting context-switched out, the execution is artificially terminated if I remember correctly.

Cheers

On Mon, Nov 27, 2023 at 3:59 PM Big-Champ @.***> wrote:

This worked! Coverage breakpoints were added successfully

Unrelated to this issue, is it possible to load coverage to a module that isn't loaded in the dump file used for the state? For example, say you breakpoint on a user-mode process and you know it will send an IOCTL that will later send input to a second user-mode process. If you wanted to track the coverage for both user-mode processes, how would you do this? I've noticed that loading coverage will fail if it can't find the base. I'm guessing this is because when you scope into a process using .Process it won't contain modules of other processes

— Reply to this email directly, view it on GitHub https://github.com/0vercl0k/wtf/issues/189#issuecomment-1828001007, or unsubscribe https://github.com/notifications/unsubscribe-auth/AALIORNM5TD4D24AD6VCYBDYGSTE3AVCNFSM6AAAAAA7RJVUGWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQMRYGAYDCMBQG4 . You are receiving this because you commented.Message ID: @.***>

0vercl0k commented 11 months ago

Closing this thread as it seems the issues were addressed and there hasn't been any new activity :)

Cheers