AFLplusplus / LibAFL

Advanced Fuzzing Library - Slot your Fuzzer together in Rust! Scales across cores and machines. For Windows, Android, MacOS, Linux, no_std, ...
Other
2.05k stars 322 forks source link

Need examples for instrumenting and fuzzing Rust program #1904

Open KaminariOS opened 9 months ago

KaminariOS commented 9 months ago

Is your feature request related to a problem? Please describe. I know that I can use libcc to instrument a C program but I am not sure how to instrument a Rust program and get the coverage data.

Describe the solution you'd like A simple example of coverage-guided Rust program fuzzing

addisoncrump commented 8 months ago

Hey, if this isn't done in the next week, feel free to ping me -- this is something I've been meaning to do for a while.

KaminariOS commented 8 months ago

I have something working already. This is in my config.toml for the harness:

rustflags = "-Cpasses=sancov-module -Cllvm-args=-sanitizer-coverage-level=4 -Cllvm-args=-sanitizer-coverage-inline-8bit-counters -Cllvm-args=-sanitizer-coverage-pc-table -Cinstrument-coverage -Zsanitizer=address -Clink-arg=-Wl,--allow-multiple-definition"

And I have a build.rs to link the fuzzer as a staticlib.

It is kinda weird: harness main calls fuzzer afl_main calls harness LLVMFuzzerTestOneInput

addisoncrump commented 8 months ago

Yeah, there are more elegant ways to do this which definitely justifies having an example.

KaminariOS commented 8 months ago

@addisoncrump Hey, how is it going with the example?

addisoncrump commented 8 months ago

Hey, haven't gotten to it yet. Thanks for the reminder.

AzimMuradov commented 4 months ago

@addisoncrump Add a rust instrumentation example, please :)

0xalpharush commented 1 month ago

I tried the approach in this book and it builds/runs but the coverage instrumentation doesn't appear to be working. It'd be nice to have some tool like afl-hitmap to check

Next, I tried the approach I found searching through the discord of creating a fuzzer based on libfuzzer_png, building a static library, trying to link the fuzzer and target, and using libfuzzer-sys' custom runtime env variable override. I can't reproduce it now because I am getting undefined references to symbol _libafl_main errors now but I was running into this issue with static linking rust libraries and having conflicting standard libarary symbols (https://github.com/rust-lang/rust/issues/44322). I think the libafl_libfuzzer_runtime's build.rs file shows how to work around this but I've yet to succeed pulling off the linker magic necessary.

It'd be really nice to package this up in a template or something like cargo-fuzz bc it's hard to take advantage of things like LibAFL's nautilus for pure Rust targets.

KaminariOS commented 1 month ago

@0xalpharush You can check my hacky example: https://github.com/KaminariOS/tree-fuzzer

0xalpharush commented 1 month ago

Thanks! Does this require cargo-fuzz to run or what is the proper way? I ran ./tree-fuzzer-json-splicer/fuzz/run.sh after modifying the Cargo.toml to build a binary for main.rs:

[[bin]]
name = "fuzzer"
path = "src/main.rs"

This does not seem to execute anything:

$ cargo r --bin fuzzer
   Compiling serde v1.0.197
   Compiling serde_json v1.0.115
   Compiling ryu v1.0.17
   Compiling test_serde v0.0.0 (/Users/x/tree-fuzzer/crates/tree-fuzzer-json-splicer/fuzz)
   Compiling itoa v1.0.11
   Compiling tree-fuzzer v0.1.0 (/Users/x/tree-fuzzer/crates/tree-fuzzer)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.92s
     Running `target/debug/fuzzer`
fuzzer(66974,0x1edfe7240) malloc: nano zone abandoned due to inability to reserve vm space.
Workdir: "/Users/x/tree-fuzzer/crates/tree-fuzzer-json-splicer/fuzz"
Restart mgr
Monitor: [Broker      #0]  (GLOBAL) run time: 0h-0m-30s, clients: 0, corpus: 0, objectives: 0, executions: 0, exec/sec: 0.000 (Aggregated):
Monitor:                   (CLIENT) corpus: 0, objectives: 0, executions: 0, exec/sec: 0.000
Monitor: [Broker      #0]  (GLOBAL) run time: 0h-1m-0s, clients: 1, corpus: 0, objectives: 0, executions: 0, exec/sec: 0.000 (Aggregated):
Monitor:                   (CLIENT) corpus: 0, objectives: 0, executions: 0, exec/sec: 0.000
KaminariOS commented 1 month ago

You need to download seeds by yourself. The fuzzer is working but without any seeds.