-E option and docu update

This commit is contained in:
van Hauser 2019-07-12 18:17:32 +02:00
parent c067ef0216
commit eddfddccb2
3 changed files with 139 additions and 5 deletions

View File

@ -88,6 +88,8 @@ u64 total_puppet_find = 0;
u64 temp_puppet_find = 0;
u64 most_time_key = 0;
u64 most_time_puppet = 0;
u64 most_execs_key = 0;
u64 most_execs = 0;
u64 old_hit_count = 0;
int SPLICE_CYCLES_puppet;
int limit_time_sig = 0;
@ -11344,18 +11346,21 @@ static void usage(u8* argv0) {
" -n - fuzz without instrumentation (dumb mode)\n"
" -x dir - optional fuzzer dictionary (see README)\n\n"
"Testing settings:\n"
" -s seed - use a fixed seed for the RNG\n"
" -V seconds - fuzz for a maximum total time of seconds then terminate\n"
" -E execs - fuzz for a maximum number of total executions then terminate\n\n"
"Other stuff:\n"
" -T text - text banner to show on the screen\n"
" -M / -S id - distributed mode (see parallel_fuzzing.txt)\n"
" -C - crash exploration mode (the peruvian rabbit thing)\n"
" -V seconds - fuzz for a maximum total time of seconds then terminate\n"
" -s seed - use a fixed seed for the rng - important to testing\n"
" -e ext - File extension for the temporarily generated test case\n\n"
#ifdef USE_PYTHON
"Compiled with Python 2.7 module support, see docs/python_mutators.txt\n"
#endif
"For additional tips, please consult %s/README.\n\n",
"For additional tips, please consult %s/README\n\n",
argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path);
@ -12050,7 +12055,7 @@ int main(int argc, char** argv) {
gettimeofday(&tv, &tz);
init_seed = tv.tv_sec ^ tv.tv_usec ^ getpid();
while ((opt = getopt(argc, argv, "+i:o:f:m:t:T:dnCB:S:M:x:Qe:p:s:V:L:")) > 0)
while ((opt = getopt(argc, argv, "+i:o:f:m:t:T:dnCB:S:M:x:Qe:p:s:V:E:L:")) > 0)
switch (opt) {
@ -12251,13 +12256,20 @@ int main(int argc, char** argv) {
break;
case 'V': {
case 'V': {
most_time_key = 1;
if (sscanf(optarg, "%llu", &most_time_puppet) < 1 || optarg[0] == '-')
FATAL("Bad syntax used for -V");
}
break;
case 'E': {
most_execs_key = 1;
if (sscanf(optarg, "%llu", &most_execs) < 1 || optarg[0] == '-')
FATAL("Bad syntax used for -E");
}
break;
case 'L': { /* MOpt mode */
if (limit_time_sig) FATAL("Multiple -L options not supported");
@ -12583,6 +12595,10 @@ int main(int argc, char** argv) {
if (most_time_puppet * 1000 < cur_ms_lv - start_time)
break;
}
if (most_execs_key == 1) {
if (most_execs >= total_execs)
break;
}
}
if (queue_cur) show_stats();

View File

@ -20,6 +20,7 @@ Version ++2.52d (tbd):
- added MOpt (github.com/puppet-meteor/MOpt-AFL) mode
- added never zero counters for afl-gcc and optional (because of an
optimization issue in llvm < 9) for llvm_mode (AFL_LLVM_NEVER_ZERO=1)
- added a new doc about binary only fuzzing: docs/binaryonly_fuzzing.txt
- more cpu power for afl-system-config
- added forkserver patch to afl-tmin, makes it much faster (originally from
github.com/nccgroup/TriforceAFL)
@ -30,6 +31,8 @@ Version ++2.52d (tbd):
see docs/python_mutators.txt (originally by choller@mozilla)
- added AFL_CAL_FAST for slow applications and AFL_DEBUG_CHILD_OUTPUT for
debugging
- added -V time and -E execs option to better comparison runs, runs afl-fuzz
for a specific time/executions.
- added a -s seed switch to allow afl run with a fixed initial
seed that is not updated. this is good for performance and path discovery
tests as the random numbers are deterministic then

115
docs/binaryonly_fuzzing.txt Normal file
View File

@ -0,0 +1,115 @@
Fuzzing binary-only programs with afl++
=======================================
afl++, libfuzzer and others are great if you have the source code, and
it allows for very fast and coverage guided fuzzing.
However, if there is only the binary program and not source code available,
then standard afl++ (dumb mode) is not effective.
The following is a description of how these can be fuzzed with afl++
!!!!!
DTLR: try DYNINST with afl-dyninst. If it produces too many crashes then
use afl -Q qemu_mode.
!!!!!
QEMU
----
Qemu is the "native" solution to the program.
It is available in the ./qemu_mode/ directory and once compiled it can
be accessed by the afl-fuzz -Q command line option.
The speed decrease is at about 50%
It the easiest to use alternative and even works for cross-platform binaries.
As it is included in afl++ this needs no URL.
DYNINST
-------
Dyninst is a binary instrumentation framework similar to Pintool and Dynamorio
(see far below). Howver whereas Pintool and Dynamorio work at runtime, dyninst
instruments the target at load time, and then let it run.
This is great for some things, e.g. fuzzing, and not so effective for others,
e.g. malware analysis.
So what we can do with dyninst is taking every basic block, and put afl's
instrumention code in there - and then save the binary.
Afterwards we can just fuzz the newly saved target binary with afl-fuzz.
Sounds great? It is. The issue though - this is a non-trivial problem to
insert instructions, which changes addresses in the process space and that
everything still works afterwards. Hence more often than not binaries
crash when they are run.
The speed decrease is about 25-35%
So if dyninst works, its the best option available. Otherwise it just doesn't
work well.
https://github.com/vanhauser-thc/afl-dyninst
INTEL-PT
--------
The big issue with Intel's PT is the small buffer size and the complex
encoding of the debug information collected through PT.
This makes the decoding very CPU intensive, hence slow and using up twice
the CPU resources. So to fairly compare Intel PT based afl fuzzers with
native afl or afl qemu we need to calculate in the higher CPU resources used.
As a result, the overall speed decrease is about 85-90%
there are two afl intel-pt implementations:
1. https://github.com/junxzm1990/afl-pt
=> this needs Ubuntu 14.04.05 without any updates and the 4.4 kernel.
2. https://github.com/hunter-ht-2018/ptfuzzer
=> this needs a 4.14 or 4.15 kernel. the "nopti" kernel boot option must
be used
CORESIGHT
---------
Coresight is the ARM answer to Intel's PT.
There is no implementation so far which handle coresight and getting
it working on an ARM Linux is very difficult due custom kernel building
on embedded systems is difficult. And finding one that has coresight in
the ARM chip is difficult too.
My guess is that it is slower than Qemu, but faster than Intel PT.
If anyone finds any coresight implemention for afl please ping me:
vh@thc.org
PIN & DYNAMORIO
---------------
Pintool and Dynamorio are dynamic instrumentation engines, and they can be
used for getting basic block information at runtime.
Pintool is only available for Intel x32/x64 on Linux, Mac OS and Windows
whereas Dynamorio is additionally available for ARM and AARCH64.
Dynamorio is also 10x faster than Pintool.
The big issue with Dynamorio (and therefore Pintool too) is speed.
Dynamorio has a speed decrease of 98-99%
Pintool has a speed decrease of 99.5%
Hence Dynamorio is the option to go for if everything fails, and Pintool
only if Dynamorio fails too.
Dynamorio solutions:
https://github.com/vanhauser-thc/afl-dynamorio
https://github.com/mxmssh/drAFL
https://github.com/googleprojectzero/winafl/ <= very good but windows only
Pintool solutions:
https://github.com/vanhauser-thc/afl-pin
https://github.com/mothran/aflpin
https://github.com/spinpx/afl_pin_mode <= only old Pintool version supported
That's it!
News, corrections, updates?
Email vh@thc.org