You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+5-9Lines changed: 5 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -21,7 +21,7 @@ Naturally, this is conditional on the same operation run twice returning the sam
21
21
22
22
## TL;DR: usage
23
23
24
-
1. Clone this repository, run `make`; this will build libdiffuzz.so
24
+
1. Clone this repository, run `cargo build --release`; this will build libdiffuzz.so and put it in `target/release`
25
25
1. Make your code run the same operation twice in the same process and compare outputs.
26
26
1. Run your code like this: `LD_PRELOAD=/path/to/libdiffuzz.so /path/to/your/binary`. If you're fuzzing with [AFL](http://lcamtuf.coredump.cx/afl/), use `AFL_PRELOAD=/path/to/libdiffuzz.so afl-fuzz ...` instead. If you're not fuzzing with AFL - you should!
27
27
1. Brag that you've used differential fuzzing to find vulnerabilities in real code
@@ -32,7 +32,7 @@ If your code does not contain `unsafe` blocks, you don't need to do a thing! You
32
32
33
33
However, if you have read from [the black book](https://doc.rust-lang.org/nomicon/) and invoked the Old Ones...
34
34
35
-
1. Clone this repository, run `make`; this will build libdiffuzz.so
35
+
1. Clone this repository, run `cargo build --release`; this will build libdiffuzz.so and put it in `target/release`
36
36
1. Make sure [this code](https://gist.github.com/Shnatsel/0c024a51b64c6e0b6c6e66f991904816) doesn't reliably crash when run on its own, but does crash when you run it like this: `LD_PRELOAD=/path/to/libdiffuzz.so target/release/membleed`
37
37
1. If you haven't done regular fuzzing yet - do set up fuzzing with AFL. [It's not that hard.](https://fuzz.rs/book/afl/setup.html)
38
38
1. In your fuzz target run the same operation twice and `assert!` that they produce the same result. See [example fuzz target for lodepng-rust](https://github.com/Shnatsel/lodepng-afl-fuzz-differential) for reference. [A more complicated example](https://github.com/Shnatsel/claxon-differential-fuzzing) is also available.
@@ -49,20 +49,16 @@ static GLOBAL: System = System;
49
49
50
50
If your target binary lets you feed it the same input several times - stellar! Simply preload libdiffuzz-numbering into a binary, feed it the same input twice and compare the outputs.
51
51
52
-
However, if your binary only accepts one input and then terminates, you will have to change the `u16 alloc_clobber_counter = 0;` in libdiffuzz-numbering to something unique to each process, such as milliseconds from system time, replace `alloc_clobber_counter++` in memset call with `alloc_clobber_counter`, then run the entire process twice and compare the outputs from the two runs. If they differ - congratulations, you've found a memory disclosure vulnerability!
52
+
However, if your binary only accepts one input and then terminates, you will have to set the environment variable `LIBDIFFUZZ_NONDETERMINISTIC`.
53
53
54
-
Oh - if the output is inherently non-deterministic, you're out of luck.
54
+
Unfortunately, if the output is inherently non-deterministic, you're out of luck. To make it deterministic, you could try limiting it to one thread and overriding any other source of randomness.
55
55
56
56
## Limitations and future work
57
57
58
58
Stack-based uninitialized reads are not detected.
59
59
60
60
Unlike memory sanitizer, this thing will not make your program crash as soon as a read from uninitialized memory occurs. Instead, it lets you detect that it has occurred after the fact and only if the contents of uninitialized memory leak into the output. I.e. this will help you notice security vulnerabilities, but will not really aid in debugging.
61
61
62
-
It currently does not reliably detect reads from uninitialized memory in multi-threaded programs. Pull requests switching the global counter to atomic type are [welcome](https://github.com/Shnatsel/libdiffuzz/issues/2). For now you can work around this by applying the same hack as for black-box binaries.
63
-
64
-
This may miss single-byte uninitialized reads because the counter is `u16`; if you need to detect those, change it to `u8`, but be warned that it will be a bit more likely to miss uninitialized reads that way (one in 256 versus one in 65536).
65
-
66
62
## Trophy case
67
63
68
64
List of previously unknown (i.e. zero-day) vulnerabilities found using this tool, to show that this whole idea is not completely bonkers:
@@ -71,6 +67,6 @@ List of previously unknown (i.e. zero-day) vulnerabilities found using this tool
71
67
72
68
## See also
73
69
74
-
[libdislocator](https://github.com/mirrorer/afl/tree/master/libdislocator), poor man's [Address Sanitizer](https://clang.llvm.org/docs/AddressSanitizer.html) that also works with black-box binaries. libdiffuzz is based on libdislocator code.
70
+
[libdislocator](https://github.com/mirrorer/afl/tree/master/libdislocator), poor man's [Address Sanitizer](https://clang.llvm.org/docs/AddressSanitizer.html) that also works with black-box binaries. libdiffuzz is loosely based on libdislocator code.
75
71
76
72
For background on how this project came about, see [How I've found vulnerability in a popular Rust crate (and you can too)](https://medium.com/@shnatsel/how-ive-found-vulnerability-in-a-popular-rust-crate-and-you-can-too-3db081a67fb).
0 commit comments