fix custom mutators and add real test cases

This commit is contained in:
van Hauser
2020-05-12 16:32:40 +02:00
parent 7b40d7b942
commit 6177954773
6 changed files with 107 additions and 24 deletions

View File

@ -6,6 +6,9 @@ See [docs/custom_mutators.md](../docs/custom_mutators.md) for more information
Note that if you compile with python3.7 you must use python3 scripts, and if Note that if you compile with python3.7 you must use python3 scripts, and if
you use python2.7 to compile python2 scripts! you use python2.7 to compile python2 scripts!
simple_example.c - most simplest example. generates a random sized buffer
filled with 'A'
example.c - this is a simple example written in C and should be compiled to a example.c - this is a simple example written in C and should be compiled to a
shared library. Use make to compile it and produce libexamplemutator.so shared library. Use make to compile it and produce libexamplemutator.so

View File

@ -21,6 +21,7 @@ COMMANDS = [
b"GET", b"GET",
b"PUT", b"PUT",
b"DEL", b"DEL",
b"AAAAAAAAAAAAAAAAA",
] ]

View File

@ -0,0 +1,74 @@
// This simple example just creates random buffer <= 100 filled with 'A'
// needs -I /path/to/AFLplusplus/include
#include "custom_mutator_helpers.h"
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#ifndef _FIXED_CHAR
#define 0x41
#endif
typedef struct my_mutator {
afl_t *afl;
// Reused buffers:
BUF_VAR(u8, fuzz);
} my_mutator_t;
my_mutator_t *afl_custom_init(afl_t *afl, unsigned int seed) {
srand(seed);
my_mutator_t *data = calloc(1, sizeof(my_mutator_t));
if (!data) {
perror("afl_custom_init alloc");
return NULL;
}
data->afl = afl;
return data;
}
size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
u8 **out_buf, uint8_t *add_buf,
size_t add_buf_size, // add_buf can be NULL
size_t max_size) {
int size = (rand() % 100) + 1;
if (size > max_size) size = max_size;
u8 *mutated_out = maybe_grow(BUF_PARAMS(data, fuzz), size);
if (!mutated_out) {
*out_buf = NULL;
perror("custom mutator allocation (maybe_grow)");
return 0; /* afl-fuzz will very likely error out after this. */
}
memset(mutated_out, _FIXED_CHAR, size);
*out_buf = mutated_out;
return size;
}
/**
* Deinitialize everything
*
* @param data The data ptr from afl_custom_init
*/
void afl_custom_deinit(my_mutator_t *data) {
free(data->fuzz_buf);
free(data);
}

View File

@ -117,7 +117,7 @@ void destroy_custom_mutators(afl_state_t *afl) {
LIST_FOREACH_CLEAR(&afl->custom_mutator_list, struct custom_mutator, { LIST_FOREACH_CLEAR(&afl->custom_mutator_list, struct custom_mutator, {
if (!el->data) { FATAL("Deintializing NULL mutator"); } if (!el->data) { FATAL("Deintializing NULL mutator"); }
el->afl_custom_deinit(el->data); if (el->afl_custom_deinit) el->afl_custom_deinit(el->data);
if (el->dh) dlclose(el->dh); if (el->dh) dlclose(el->dh);
if (el->pre_save_buf) { if (el->pre_save_buf) {
@ -166,32 +166,37 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) {
} }
/* "afl_custom_deinit", optional for backward compatibility */
mutator->afl_custom_deinit = dlsym(dh, "afl_custom_deinit");
if (!mutator->afl_custom_deinit) WARNF("Symbol 'afl_custom_init' not found.");
/* "afl_custom_pre_save", optional */ /* "afl_custom_pre_save", optional */
mutator->afl_custom_pre_save = dlsym(dh, "afl_custom_pre_save"); mutator->afl_custom_pre_save = dlsym(dh, "afl_custom_pre_save");
if (!mutator->afl_custom_pre_save) if (!mutator->afl_custom_pre_save)
WARNF("Symbol 'afl_custom_pre_save' not found."); ACTF("optional symbol 'afl_custom_pre_save' not found.");
u8 notrim = 0; u8 notrim = 0;
/* "afl_custom_init_trim", optional */ /* "afl_custom_init_trim", optional */
mutator->afl_custom_init_trim = dlsym(dh, "afl_custom_init_trim"); mutator->afl_custom_init_trim = dlsym(dh, "afl_custom_init_trim");
if (!mutator->afl_custom_init_trim) if (!mutator->afl_custom_init_trim)
WARNF("Symbol 'afl_custom_init_trim' not found."); ACTF("optional symbol 'afl_custom_init_trim' not found.");
/* "afl_custom_trim", optional */ /* "afl_custom_trim", optional */
mutator->afl_custom_trim = dlsym(dh, "afl_custom_trim"); mutator->afl_custom_trim = dlsym(dh, "afl_custom_trim");
if (!mutator->afl_custom_trim) WARNF("Symbol 'afl_custom_trim' not found."); if (!mutator->afl_custom_trim)
ACTF("optional symbol 'afl_custom_trim' not found.");
/* "afl_custom_post_trim", optional */ /* "afl_custom_post_trim", optional */
mutator->afl_custom_post_trim = dlsym(dh, "afl_custom_post_trim"); mutator->afl_custom_post_trim = dlsym(dh, "afl_custom_post_trim");
if (!mutator->afl_custom_post_trim) if (!mutator->afl_custom_post_trim)
WARNF("Symbol 'afl_custom_post_trim' not found."); ACTF("optional symbol 'afl_custom_post_trim' not found.");
if (notrim) { if (notrim) {
mutator->afl_custom_init_trim = NULL; mutator->afl_custom_init_trim = NULL;
mutator->afl_custom_trim = NULL; mutator->afl_custom_trim = NULL;
mutator->afl_custom_post_trim = NULL; mutator->afl_custom_post_trim = NULL;
WARNF( ACTF(
"Custom mutator does not implement all three trim APIs, standard " "Custom mutator does not implement all three trim APIs, standard "
"trimming will be used."); "trimming will be used.");
@ -200,23 +205,23 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) {
/* "afl_custom_havoc_mutation", optional */ /* "afl_custom_havoc_mutation", optional */
mutator->afl_custom_havoc_mutation = dlsym(dh, "afl_custom_havoc_mutation"); mutator->afl_custom_havoc_mutation = dlsym(dh, "afl_custom_havoc_mutation");
if (!mutator->afl_custom_havoc_mutation) if (!mutator->afl_custom_havoc_mutation)
WARNF("Symbol 'afl_custom_havoc_mutation' not found."); ACTF("optional symbol 'afl_custom_havoc_mutation' not found.");
/* "afl_custom_havoc_mutation", optional */ /* "afl_custom_havoc_mutation", optional */
mutator->afl_custom_havoc_mutation_probability = mutator->afl_custom_havoc_mutation_probability =
dlsym(dh, "afl_custom_havoc_mutation_probability"); dlsym(dh, "afl_custom_havoc_mutation_probability");
if (!mutator->afl_custom_havoc_mutation_probability) if (!mutator->afl_custom_havoc_mutation_probability)
WARNF("Symbol 'afl_custom_havoc_mutation_probability' not found."); ACTF("optional symbol 'afl_custom_havoc_mutation_probability' not found.");
/* "afl_custom_queue_get", optional */ /* "afl_custom_queue_get", optional */
mutator->afl_custom_queue_get = dlsym(dh, "afl_custom_queue_get"); mutator->afl_custom_queue_get = dlsym(dh, "afl_custom_queue_get");
if (!mutator->afl_custom_queue_get) if (!mutator->afl_custom_queue_get)
WARNF("Symbol 'afl_custom_queue_get' not found."); ACTF("optional symbol 'afl_custom_queue_get' not found.");
/* "afl_custom_queue_new_entry", optional */ /* "afl_custom_queue_new_entry", optional */
mutator->afl_custom_queue_new_entry = dlsym(dh, "afl_custom_queue_new_entry"); mutator->afl_custom_queue_new_entry = dlsym(dh, "afl_custom_queue_new_entry");
if (!mutator->afl_custom_queue_new_entry) if (!mutator->afl_custom_queue_new_entry)
WARNF("Symbol 'afl_custom_queue_new_entry' not found"); ACTF("optional symbol 'afl_custom_queue_new_entry' not found");
OKF("Custom mutator '%s' installed successfully.", fn); OKF("Custom mutator '%s' installed successfully.", fn);

View File

@ -12,11 +12,10 @@
int main(int argc, char **argv) { int main(int argc, char **argv) {
int a = 0; int a = 0;
char s[16]; char s[100];
memset(s, 0, 16); read(0, s, 100);
read(0, s, 0xa0);
if (s[17] != '\x00') { abort(); } if (s[7] == 'B') { abort(); }
return 0; return 0;

View File

@ -970,16 +970,17 @@ test "1" = "`../afl-fuzz | grep -i 'without python' >/dev/null; echo $?`" && {
} }
} }
# Compile the custom mutator # Compile the custom mutator
make -C ../examples/custom_mutators libexamplemutator.so > /dev/null 2>&1 cc -D_FIXED_CHAR=0x41 -g -fPIC -shared -I../include ../examples/custom_mutators/simple_example.c -o libexamplemutator.so > /dev/null 2>&1
test -e test-custom-mutator -a -e ${CUSTOM_MUTATOR_PATH}/libexamplemutator.so && { cc -D_FIXED_CHAR=0x42 -g -fPIC -shared -I../include ../examples/custom_mutators/simple_example.c -o libexamplemutator2.so > /dev/null 2>&1
test -e test-custom-mutator -a -e ./libexamplemutator.so && {
# Create input directory # Create input directory
mkdir -p in mkdir -p in
echo "00000" > in/in echo "00000" > in/in
# Run afl-fuzz w/ the C mutator # Run afl-fuzz w/ the C mutator
$ECHO "$GREY[*] running afl-fuzz for the C mutator, this will take approx 10 seconds" $ECHO "$GREY[*] running afl-fuzz for the C mutator, this will take approx 5 seconds"
{ {
AFL_CUSTOM_MUTATOR_LIBRARY=${CUSTOM_MUTATOR_PATH}/libexamplemutator.so ../afl-fuzz -V10 -m ${MEM_LIMIT} -i in -o out -- ./test-custom-mutator >>errors 2>&1 AFL_CUSTOM_MUTATOR_LIBRARY=./libexamplemutator.so AFL_CUSTOM_MUTATOR_ONLY=1 ../afl-fuzz -V1 -m ${MEM_LIMIT} -i in -o out -- ./test-custom-mutator >>errors 2>&1
} >>errors 2>&1 } >>errors 2>&1
# Check results # Check results
@ -996,10 +997,10 @@ test "1" = "`../afl-fuzz | grep -i 'without python' >/dev/null; echo $?`" && {
# Clean # Clean
rm -rf out errors rm -rf out errors
#Run afl-fuzz w/ multiple C mutators # Run afl-fuzz w/ multiple C mutators
$ECHO "$GREY[*] running afl-fuzz with multiple custom C mutators, this will take approx 20 seconds" $ECHO "$GREY[*] running afl-fuzz with multiple custom C mutators, this will take approx 5 seconds"
{ {
AFL_CUSTOM_MUTATOR_LIBRARY="${CUSTOM_MUTATOR_PATH}/libexamplemutator.so;${CUSTOM_MUTATOR_PATH}/libexamplemutator.so" ../afl-fuzz -V20 -m ${MEM_LIMIT} -i in -o out -- ./test-multiple-mutators >>errors 2>&1 AFL_CUSTOM_MUTATOR_LIBRARY="./libexamplemutator.so;./libexamplemutator2.so" AFL_CUSTOM_MUTATOR_ONLY=1 ../afl-fuzz -V1 -m ${MEM_LIMIT} -i in -o out -- ./test-multiple-mutators >>errors 2>&1
} >>errors 2>&1 } >>errors 2>&1
test -n "$( ls out/crashes/id:000000* 2>/dev/null )" && { # TODO: update here test -n "$( ls out/crashes/id:000000* 2>/dev/null )" && { # TODO: update here
@ -1016,11 +1017,11 @@ test "1" = "`../afl-fuzz | grep -i 'without python' >/dev/null; echo $?`" && {
rm -rf out errors rm -rf out errors
# Run afl-fuzz w/ the Python mutator # Run afl-fuzz w/ the Python mutator
$ECHO "$GREY[*] running afl-fuzz for the Python mutator, this will take approx 10 seconds" $ECHO "$GREY[*] running afl-fuzz for the Python mutator, this will take approx 5 seconds"
{ {
export PYTHONPATH=${CUSTOM_MUTATOR_PATH} export PYTHONPATH=${CUSTOM_MUTATOR_PATH}
export AFL_PYTHON_MODULE=example export AFL_PYTHON_MODULE=example
../afl-fuzz -V10 -m ${MEM_LIMIT} -i in -o out -- ./test-custom-mutator >>errors 2>&1 AFL_CUSTOM_MUTATOR_ONLY=1 ../afl-fuzz -V5 -m ${MEM_LIMIT} -i in -o out -- ./test-custom-mutator >>errors 2>&1
unset PYTHONPATH unset PYTHONPATH
unset AFL_PYTHON_MODULE unset AFL_PYTHON_MODULE
} >>errors 2>&1 } >>errors 2>&1
@ -1039,7 +1040,7 @@ test "1" = "`../afl-fuzz | grep -i 'without python' >/dev/null; echo $?`" && {
# Clean # Clean
rm -rf in out errors rm -rf in out errors
rm -rf ${CUSTOM_MUTATOR_PATH}/__pycache__/ rm -rf ${CUSTOM_MUTATOR_PATH}/__pycache__/
rm -f test-multiple-mutators rm -f test-multiple-mutators test-custom-mutator libexamplemutator.so libexamplemutator2.so
} || { } || {
ls . ls .
ls ${CUSTOM_MUTATOR_PATH} ls ${CUSTOM_MUTATOR_PATH}