Merge pull request #462 from AFLplusplus/dev

Dev
This commit is contained in:
van Hauser
2020-07-21 13:17:29 +02:00
committed by GitHub
10 changed files with 100 additions and 19 deletions

14
.gitignore vendored
View File

@ -5,6 +5,11 @@
*.so
*.pyc
*.dSYM
as
ld
in
out
core*
afl-analyze
afl-as
afl-clang
@ -43,13 +48,10 @@ afl-system-config.8
afl-tmin.8
afl-whatsup.8
qemu_mode/libcompcov/compcovtest
as
ld
qemu_mode/qemu-*
unicorn_mode/samples/*/\.test-*
unicorn_mode/samples/*/output/
unicorn_mode/unicornafl
core\.*
test/unittests/unit_maybe_alloc
test/unittests/unit_preallocable
test/unittests/unit_list
@ -57,5 +59,7 @@ test/unittests/unit_rand
test/unittests/unit_hash
examples/afl_network_proxy/afl-network-server
examples/afl_network_proxy/afl-network-client
in
out
examples/afl_frida/afl-frida
examples/afl_frida/libtestinstr.so
examples/afl_frida/frida-gum-example.c
examples/afl_frida/frida-gum.h

View File

@ -357,9 +357,10 @@ Here are some good writeups to show how to effectively use AFL++:
* [https://securitylab.github.com/research/fuzzing-sockets-FTP](https://securitylab.github.com/research/fuzzing-sockets-FTP)
If you are interested in fuzzing structured data (where you define what the
structure is), these two links have you covered:
* [https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/tree/master/4_libprotobuf_aflpp_custom_mutator](https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/tree/master/4_libprotobuf_aflpp_custom_mutator)
* [https://github.com/thebabush/afl-libprotobuf-mutator](https://github.com/thebabush/afl-libprotobuf-mutator)
structure is), these links have you covered:
* Superion for afl++: [https://github.com/adrian-rt/superion-mutator](https://github.com/adrian-rt/superion-mutator)
* libprotobuf raw: [https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/tree/master/4_libprotobuf_aflpp_custom_mutator](https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/tree/master/4_libprotobuf_aflpp_custom_mutator)
* libprotobuf for old afl++ API: [https://github.com/thebabush/afl-libprotobuf-mutator](https://github.com/thebabush/afl-libprotobuf-mutator)
If you find other good ones, please send them to us :-)

View File

@ -1,7 +1,8 @@
# TODO list for AFL++
## Roadmap 2.66+
## Roadmap 2.67+
- allow to sync against honggfuzz and libfuzzer
- AFL_MAP_SIZE for qemu_mode and unicorn_mode
- namespace for targets? e.g. network
- learn from honggfuzz (mutations, maybe ptrace?)

View File

@ -10,3 +10,22 @@ Use with e.g.
and add `AFL_CUSTOM_MUTATOR_ONLY=1` if you only want to use the custom mutator.
Multiple custom mutators can be used by separating their paths with `:` in the environment variable.
# Other custom mutators
## Superion port
Adrian Tiron ported the Superion grammar fuzzer to afl++, it is WIP and
requires cmake (among other things):
[https://github.com/adrian-rt/superion-mutator](https://github.com/adrian-rt/superion-mutator)
## Protobuf
There are two WIP protobuf projects, that require work to be working though:
transforms protobuf raw:
https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/tree/master/4_libprotobuf_aflpp_custom_mutator
has a transform function you need to fill for your protobuf format, however
needs to be ported to the updated afl++ custom mutator API (not much work):
https://github.com/thebabush/afl-libprotobuf-mutator

View File

@ -36,7 +36,7 @@ size_t afl_custom_fuzz(void *data, uint8_t *buf, size_t buf_size, u8 **out_buf,
size_t afl_custom_post_process(void *data, uint8_t *buf, size_t buf_size, uint8_t **out_buf);
int32_t afl_custom_init_trim(void *data, uint8_t *buf, size_t buf_size);
size_t afl_custom_trim(void *data, uint8_t **out_buf);
int32_t afl_custom_post_trim(void *data, int success) {
int32_t afl_custom_post_trim(void *data, int success);
size_t afl_custom_havoc_mutation(void *data, u8 *buf, size_t buf_size, u8 **out_buf, size_t max_size);
uint8_t afl_custom_havoc_mutation_probability(void *data);
uint8_t afl_custom_queue_get(void *data, const uint8_t *filename);

View File

@ -31,4 +31,4 @@ However the stability is low. Reason is currently unknown.
# Background
This code ist copied for a larger part from https://github.com/meme/hotwax
This code is copied for a larger part from https://github.com/meme/hotwax

View File

@ -125,10 +125,9 @@ NOTE: some targets also need to set the linker, try both `afl-clang-lto` and
## AUTODICTIONARY feature
Setting `AFL_LLVM_LTO_AUTODICTIONARY` will generate a dictionary in the
target binary based on string compare and memory compare functions.
afl-fuzz will automatically get these transmitted when starting to fuzz.
This improves coverage on a lot of targets.
While compiling, automatically a dictionary based on string comparisons is
generated put into the target binary. This dictionary is transfered to afl-fuzz
on start. This improves coverage statistically by 5-10% :)
## Fixed memory map
@ -147,6 +146,8 @@ Some targets are difficult because the configure script does unusual stuff that
is unexpected for afl. See the next chapter `Potential issues` how to solve
these.
### Example: ffmpeg
An example of a hard to solve target is ffmpeg. Here is how to successfully
instrument it:
@ -186,6 +187,31 @@ instrument it:
4. Then type make, wait for a long time and you are done :)
### Example: WebKit jsc
Building jsc is difficult as the build script has bugs.
1. checkout Webkit:
```
svn checkout https://svn.webkit.org/repository/webkit/trunk WebKit
cd WebKit
```
2. Fix the build environment:
```
mkdir -p WebKitBuild/Release
cd WebKitBuild/Release
ln -s ../../../../../usr/bin/llvm-ar-11 llvm-ar-11
ln -s ../../../../../usr/bin/llvm-ranlib-11 llvm-ranlib-11
cd ../..
```
3. Build :)
```
Tools/Scripts/build-jsc --jsc-only --cli --cmakeargs="-DCMAKE_AR='llvm-ar-11' -DCMAKE_RANLIB='llvm-ranlib-11' -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -DCMAKE_CC_FLAGS='-O3 -lrt' -DCMAKE_CXX_FLAGS='-O3 -lrt' -DIMPORTED_LOCATION='/lib/x86_64-linux-gnu/' -DCMAKE_CC=afl-clang-lto -DCMAKE_CXX=afl-clang-lto++ -DENABLE_STATIC_JSC=ON"
```
## Potential issues
### compiling libraries fails

View File

@ -768,9 +768,19 @@ int main(int argc, char **argv, char **envp) {
#if LLVM_VERSION_MAJOR <= 6
instrument_mode = INSTRUMENT_AFL;
#else
if (getenv("AFL_LLVM_INSTRUMENT_FILE") || getenv("AFL_LLVM_WHITELIST"))
if (getenv("AFL_LLVM_INSTRUMENT_FILE") || getenv("AFL_LLVM_WHITELIST")) {
instrument_mode = INSTRUMENT_AFL;
else
WARNF(
"switching to classic instrumentation because "
"AFL_LLVM_INSTRUMENT_FILE does not work with PCGUARD. Use "
"-fsanitize-coverage-allowlist=allowlist.txt if you want to use "
"PCGUARD. See "
"https://clang.llvm.org/docs/"
"SanitizerCoverage.html#partially-disabling-instrumentation");
} else
instrument_mode = INSTRUMENT_PCGUARD;
#endif
@ -818,9 +828,12 @@ int main(int argc, char **argv, char **envp) {
if (instrument_mode == INSTRUMENT_PCGUARD &&
(getenv("AFL_LLVM_INSTRUMENT_FILE") || getenv("AFL_LLVM_WHITELIST")))
WARNF(
FATAL(
"Instrumentation type PCGUARD does not support "
"AFL_LLVM_INSTRUMENT_FILE!");
"AFL_LLVM_INSTRUMENT_FILE! Use "
"-fsanitize-coverage-allowlist=allowlist.txt instead, see "
"https://clang.llvm.org/docs/"
"SanitizerCoverage.html#partially-disabling-instrumentation");
if (argc < 2 || strcmp(argv[1], "-h") == 0) {

View File

@ -286,6 +286,15 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf,
"Trimmed data returned by custom mutator is larger than original "
"data");
} else if (unlikely(retlen == 0)) {
/* Do not run the empty test case on the target. To keep the custom
trimming function running, we simply treat the empty test case as an
unsuccessful trimming and skip it, instead of aborting the trimming. */
++afl->trim_execs;
goto unsuccessful_trimming;
}
write_to_testcase(afl, retbuf, retlen);
@ -325,6 +334,8 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf,
} else {
unsuccessful_trimming:
/* Tell the custom mutator that the trimming was unsuccessful */
afl->stage_cur = mutator->afl_custom_post_trim(mutator->data, 0);
if (unlikely(afl->stage_cur < 0)) {

View File

@ -1048,6 +1048,12 @@ int main(int argc, char **argv_orig, char **envp) {
}
#ifdef RAND_TEST_VALUES
u32 counter;
for (counter = 0; counter < 100000; counter++)
printf("DEBUG: rand %06d is %u\n", counter, rand_below(afl, 65536));
#endif
setup_custom_mutators(afl);
setup_cmdline_file(afl, argv + optind);