From c058ce37bbd578be91b8c5d26161ecb281568725 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 1 Nov 2022 14:05:31 +0100 Subject: remove python2 reference --- docs/custom_mutators.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/custom_mutators.md') diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md index 6b72430a..ffd3cce8 100644 --- a/docs/custom_mutators.md +++ b/docs/custom_mutators.md @@ -269,10 +269,10 @@ sudo apt install python-dev ``` Then, AFL++ can be compiled with Python support. The AFL++ Makefile detects -Python 2 and 3 through `python-config` if it is in the PATH and compiles -`afl-fuzz` with the feature if available. +Python3 through `python-config`/`python3-config` if it is in the PATH and +compiles `afl-fuzz` with the feature if available. -Note: for some distributions, you might also need the package `python[23]-apt`. +Note: for some distributions, you might also need the package `python[3]-apt`. In case your setup is different, set the necessary variables like this: `PYTHON_INCLUDE=/path/to/python/include LDFLAGS=-L/path/to/python/lib make`. -- cgit 1.4.1 From c5f8869778b237f89cc4c12c1961a9ef559179b8 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 11 Nov 2022 10:46:45 +0100 Subject: afl_custom_fuzz_send added --- docs/Changelog.md | 8 ++++++-- docs/custom_mutators.md | 10 ++++++++++ include/afl-fuzz.h | 13 +++++++++++++ src/afl-fuzz-mutators.c | 8 ++++++++ src/afl-fuzz-python.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/afl-fuzz-run.c | 42 +++++++++++++++++++++++++++++++++++++----- utils/afl_proxy/README.md | 5 +++++ 7 files changed, 124 insertions(+), 7 deletions(-) (limited to 'docs/custom_mutators.md') diff --git a/docs/Changelog.md b/docs/Changelog.md index 38e2e6bc..b975fa76 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -4,8 +4,12 @@ release of the tool. See README.md for the general instruction manual. ### Version ++4.05a (dev) - - your PR? :) - + - afl-fuzz: + - added afl_custom_fuzz_send custom mutator feature. Now your can + send fuzz data to the target as you need, e.g. via IPC. + - afl-showmap/afl-cmin + - -t none now translates to -t 120000 (120 seconds) + - unicorn_mode updated ### Version ++4.04c (release) - fix gramatron and grammar_mutator build scripts diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md index ffd3cce8..ecc004e2 100644 --- a/docs/custom_mutators.md +++ b/docs/custom_mutators.md @@ -57,6 +57,7 @@ int afl_custom_post_trim(void *data, unsigned char success); size_t afl_custom_havoc_mutation(void *data, unsigned char *buf, size_t buf_size, unsigned char **out_buf, size_t max_size); unsigned char afl_custom_havoc_mutation_probability(void *data); unsigned char afl_custom_queue_get(void *data, const unsigned char *filename); +void (*afl_custom_fuzz_send)(void *data, const u8 *buf, size_t buf_size); u8 afl_custom_queue_new_entry(void *data, const unsigned char *filename_new_queue, const unsigned int *filename_orig_queue); const char* afl_custom_introspection(my_mutator_t *data); void afl_custom_deinit(void *data); @@ -98,6 +99,9 @@ def havoc_mutation_probability(): def queue_get(filename): return True +def fuzz_send(buf): + pass + def queue_new_entry(filename_new_queue, filename_orig_queue): return False @@ -168,6 +172,12 @@ def deinit(): # optional for Python to the target, e.g. if it is too short, too corrupted, etc. If so, return a NULL buffer and zero length (or a 0 length string in Python). +- `fuzz_send` (optional): + + This method can be used if you want to send data to the target yourself, + e.g. via IPC. This replaces some usage of utils/afl_proxy but requires + that you start the target with afl-fuzz. + - `queue_new_entry` (optional): This methods is called after adding a new test case to the queue. If the diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index c8ca8e9b..a63b7493 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -968,6 +968,19 @@ struct custom_mutator { */ u8 (*afl_custom_queue_get)(void *data, const u8 *filename); + /** + * This method can be used if you want to send data to the target yourself, + * e.g. via IPC. This replaces some usage of utils/afl_proxy but requires + * that you start the target with afl-fuzz. + * + * (Optional) + * + * @param data pointer returned in afl_custom_init by this custom mutator + * @param buf Buffer containing the test case + * @param buf_size Size of the test case + */ + void (*afl_custom_fuzz_send)(void *data, const u8 *buf, size_t buf_size); + /** * Allow for additional analysis (e.g. calling a different tool that does a * different kind of coverage and saves this for the custom mutator). diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index b9daebfa..f3d0bc96 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -314,6 +314,14 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { } + /* "afl_custom_fuzz_send", optional */ + mutator->afl_custom_fuzz_send = dlsym(dh, "afl_custom_fuzz_send"); + if (!mutator->afl_custom_fuzz_send) { + + ACTF("optional symbol 'afl_custom_fuzz_send' not found."); + + } + /* "afl_custom_queue_new_entry", optional */ mutator->afl_custom_queue_new_entry = dlsym(dh, "afl_custom_queue_new_entry"); if (!mutator->afl_custom_queue_new_entry) { diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index a43d80bb..54b05978 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -246,6 +246,8 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) { PyObject_GetAttrString(py_module, "havoc_mutation_probability"); py_functions[PY_FUNC_QUEUE_GET] = PyObject_GetAttrString(py_module, "queue_get"); + py_functions[PY_FUNC_FUZZ_SEND] = + PyObject_GetAttrString(py_module, "fuzz_send"); py_functions[PY_FUNC_QUEUE_NEW_ENTRY] = PyObject_GetAttrString(py_module, "queue_new_entry"); py_functions[PY_FUNC_INTROSPECTION] = @@ -466,6 +468,12 @@ struct custom_mutator *load_custom_mutator_py(afl_state_t *afl, } + if (py_functions[PY_FUNC_FUZZ_SEND]) { + + mutator->afl_custom_fuzz_send = fuzz_send_py; + + } + if (py_functions[PY_FUNC_QUEUE_NEW_ENTRY]) { mutator->afl_custom_queue_new_entry = queue_new_entry_py; @@ -893,6 +901,43 @@ u8 queue_get_py(void *py_mutator, const u8 *filename) { } +void fuzz_send_py(void *py_mutator, const u8 *buf, size_t buf_size) { + + PyObject *py_args, *py_value; + + py_args = PyTuple_New(1); + py_value = PyByteArray_FromStringAndSize(buf, buf_size); + if (!py_value) { + + Py_DECREF(py_args); + FATAL("Failed to convert arguments"); + + } + + PyTuple_SetItem(py_args, 0, py_value); + + py_value = PyObject_CallObject( + ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_FUZZ_SEND], py_args); + Py_DECREF(py_args); + + if (py_value != NULL) { + + #if PY_MAJOR_VERSION >= 3 + u32 retcnt = (u32)PyLong_AsLong(py_value); + #else + u32 retcnt = PyInt_AsLong(py_value); + #endif + Py_DECREF(py_value); + + } else { + + PyErr_Print(); + FATAL("Call failed"); + + } + +} + u8 queue_new_entry_py(void *py_mutator, const u8 *filename_new_queue, const u8 *filename_orig_queue) { diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index ee4a3298..a680228d 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -133,9 +133,25 @@ write_to_testcase(afl_state_t *afl, void **mem, u32 len, u32 fix) { if (new_mem != *mem) { *mem = new_mem; } - /* everything as planned. use the potentially new data. */ - afl_fsrv_write_to_testcase(&afl->fsrv, *mem, new_size); - len = new_size; + if (unlikely(afl->custom_mutators_count)) { + + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { + + if (el->afl_custom_fuzz_send) { + + el->afl_custom_fuzz_send(el->data, *mem, new_size); + + } + + }); + + } else { + + /* everything as planned. use the potentially new data. */ + afl_fsrv_write_to_testcase(&afl->fsrv, *mem, new_size); + len = new_size; + + } } else { @@ -149,8 +165,24 @@ write_to_testcase(afl_state_t *afl, void **mem, u32 len, u32 fix) { } - /* boring uncustom. */ - afl_fsrv_write_to_testcase(&afl->fsrv, *mem, len); + if (unlikely(afl->custom_mutators_count)) { + + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { + + if (el->afl_custom_fuzz_send) { + + el->afl_custom_fuzz_send(el->data, *mem, len); + + } + + }); + + } else { + + /* boring uncustom. */ + afl_fsrv_write_to_testcase(&afl->fsrv, *mem, len); + + } } diff --git a/utils/afl_proxy/README.md b/utils/afl_proxy/README.md index 3c768a19..7965659d 100644 --- a/utils/afl_proxy/README.md +++ b/utils/afl_proxy/README.md @@ -7,3 +7,8 @@ You only need to change the while() loop of the main() to send the data of buf[] with length len to the target and write the coverage information to __afl_area_ptr[__afl_map_size] +UPDATE: you can also use [custom mutators](../../docs/custom_mutators.md) with +afl_custom_fuzz_send to send data to a target, which is much more efficient! +But you can only use this feature if you start the target via afl-fuzz and +a forkserver is active (e.g. via -Q qemu_mode or source compiled). + -- cgit 1.4.1 From 4a7cd53f64abf4eac311621220afc927574fdcea Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 14 Nov 2022 21:26:17 +0100 Subject: custom_send example --- custom_mutators/examples/custom_send.c | 56 ++++++++++++++++++++++++++++++++ docs/custom_mutators.md | 1 + src/afl-fuzz-mutators.c | 58 +++++++++++++++++++++++++++++++++- 3 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 custom_mutators/examples/custom_send.c (limited to 'docs/custom_mutators.md') diff --git a/custom_mutators/examples/custom_send.c b/custom_mutators/examples/custom_send.c new file mode 100644 index 00000000..ffea927e --- /dev/null +++ b/custom_mutators/examples/custom_send.c @@ -0,0 +1,56 @@ +// cc -O3 -fPIC -shared -g -o custom_send.so -I../../include custom_send.c +// cd ../.. +// afl-cc -o test-instr test-instr.c +// afl-fuzz -i in -o out -- ./test-instr -f /tmp/foo + +#include "custom_mutator_helpers.h" + +#include +#include +#include +#include +#include + +typedef struct my_mutator { + + afl_t *afl; + +} my_mutator_t; + +my_mutator_t *afl_custom_init(afl_t *afl, unsigned int 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; + +} + +void afl_custom_fuzz_send(my_mutator_t *data, uint8_t *buf, size_t buf_size) { + + int fd = open("/tmp/foo", O_CREAT | O_NOFOLLOW | O_TRUNC | O_RDWR, 0644); + + if (fd >= 0) { + + (void)write(fd, buf, buf_size); + close(fd); + + } + + return; + +} + +void afl_custom_deinit(my_mutator_t *data) { + + free(data); + +} + diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md index ecc004e2..4ffeda7a 100644 --- a/docs/custom_mutators.md +++ b/docs/custom_mutators.md @@ -177,6 +177,7 @@ def deinit(): # optional for Python This method can be used if you want to send data to the target yourself, e.g. via IPC. This replaces some usage of utils/afl_proxy but requires that you start the target with afl-fuzz. + Example: [custom_mutators/examples/custom_send.c](custom_mutators/examples/custom_send.c) - `queue_new_entry` (optional): diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index f3d0bc96..ef30b993 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -211,8 +211,16 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { WARNF("Symbol 'afl_custom_mutator' not found."); + } else { + + OKF("Found 'afl_custom_mutator'."); + } + } else { + + OKF("Found 'afl_custom_mutator'."); + } /* "afl_custom_introspection", optional */ @@ -222,6 +230,10 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { ACTF("optional symbol 'afl_custom_introspection' not found."); + } else { + + OKF("Found 'afl_custom_introspection'."); + } #endif @@ -232,6 +244,10 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { ACTF("optional symbol 'afl_custom_fuzz_count' not found."); + } else { + + OKF("Found 'afl_custom_fuzz_count'."); + } /* "afl_custom_deinit", optional for backward compatibility */ @@ -248,6 +264,10 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { ACTF("optional symbol 'afl_custom_post_process' not found."); + } else { + + OKF("Found 'afl_custom_post_process'."); + } u8 notrim = 0; @@ -258,6 +278,10 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { notrim = 1; ACTF("optional symbol 'afl_custom_init_trim' not found."); + } else { + + OKF("Found 'afl_custom_init_trim'."); + } /* "afl_custom_trim", optional */ @@ -267,6 +291,10 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { notrim = 1; ACTF("optional symbol 'afl_custom_trim' not found."); + } else { + + OKF("Found 'afl_custom_trim'."); + } /* "afl_custom_post_trim", optional */ @@ -276,6 +304,10 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { notrim = 1; ACTF("optional symbol 'afl_custom_post_trim' not found."); + } else { + + OKF("Found 'afl_custom_post_trim'."); + } if (notrim) { @@ -295,6 +327,10 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { ACTF("optional symbol 'afl_custom_havoc_mutation' not found."); + } else { + + OKF("Found 'afl_custom_havoc_mutation'."); + } /* "afl_custom_havoc_mutation", optional */ @@ -304,6 +340,10 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { ACTF("optional symbol 'afl_custom_havoc_mutation_probability' not found."); + } else { + + OKF("Found 'afl_custom_havoc_mutation_probability'."); + } /* "afl_custom_queue_get", optional */ @@ -312,6 +352,10 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { ACTF("optional symbol 'afl_custom_queue_get' not found."); + } else { + + OKF("Found 'afl_custom_queue_get'."); + } /* "afl_custom_fuzz_send", optional */ @@ -320,6 +364,10 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { ACTF("optional symbol 'afl_custom_fuzz_send' not found."); + } else { + + OKF("Found 'afl_custom_fuzz_send'."); + } /* "afl_custom_queue_new_entry", optional */ @@ -328,13 +376,21 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { ACTF("optional symbol 'afl_custom_queue_new_entry' not found"); + } else { + + OKF("Found 'afl_custom_queue_new_entry'."); + } /* "afl_custom_describe", optional */ mutator->afl_custom_describe = dlsym(dh, "afl_custom_describe"); if (!mutator->afl_custom_describe) { - ACTF("Symbol 'afl_custom_describe' not found."); + ACTF("optional symbol 'afl_custom_describe' not found."); + + } else { + + OKF("Found 'afl_custom_describe'."); } -- cgit 1.4.1