diff options
-rw-r--r-- | afl-fuzz.c | 17 | ||||
-rw-r--r-- | custom_mutators/simple_mutator.c | 40 | ||||
-rw-r--r-- | docs/custom_mutator.txt | 34 |
3 files changed, 91 insertions, 0 deletions
diff --git a/afl-fuzz.c b/afl-fuzz.c index a1388a55..73efdfb1 100644 --- a/afl-fuzz.c +++ b/afl-fuzz.c @@ -369,7 +369,24 @@ static u32 a_extras_cnt; /* Total number of tokens available */ static u8* (*post_handler)(u8* buf, u32* len); /* hooks for the custom mutator function */ +/** + * Perform custom mutations on a given input + * @param data Input data to be mutated + * @param size Size of input data + * @param mutated_out Buffer to store the mutated input + * @param max_size Maximum size of the mutated output. The mutation must not produce data larger than max_size. + * @param seed Seed used for the mutation. The mutation should produce the same output given the same seed. + * @return Size of the mutated output. + */ static size_t (*custom_mutator)(u8 *data, size_t size, u8* mutated_out, size_t max_size, unsigned int seed); +/** + * A post-processing function to use right before AFL writes the test case to disk in order to execute the target. + * If this functionality is not needed, Simply don't define this function. + * @param data Buffer containing the test case to be executed. + * @param size Size of the test case. + * @param new_data Buffer to store the test case after processing + * @return Size of data after processing. + */ static size_t (*pre_save_handler)(u8 *data, size_t size, u8 **new_data); diff --git a/custom_mutators/simple_mutator.c b/custom_mutators/simple_mutator.c new file mode 100644 index 00000000..5c40d462 --- /dev/null +++ b/custom_mutators/simple_mutator.c @@ -0,0 +1,40 @@ +/* + Simple Custom Mutator for AFL + + Written by Khaled Yakdan <yakdan@code-intelligence.de> + + This a simple mutator that assumes that the generates messages starting with one + of the three strings GET, PUT, or DEL followed by a payload. The mutator randomly + selects a commend and mutates the payload of the seed provided as input. +*/ + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +static const char *commands[] = { + "GET", + "PUT", + "DEL", +}; + +static size_t data_size = 100; + +size_t afl_custom_mutator (uint8_t *data, size_t size, uint8_t* mutated_out, size_t max_size, unsigned int seed) { + + // Seed the PRNG + srand(seed); + + // Make sure that the packet size does not exceed the maximum size expected by the fuzzer + size_t mutated_size = data_size <= max_size ? data_size : max_size; + + // Randomly select a command string to add as a header to the packet + memcpy(mutated_out, commands[rand() % 3], 3); + + // Mutate the payload of the packet + for (int i = 3 ; i < mutated_size ; i++) { + mutated_out[i] = (data[i] + rand() % 10) & 0xff; + } + + return mutated_size; +} diff --git a/docs/custom_mutator.txt b/docs/custom_mutator.txt new file mode 100644 index 00000000..3b1b93b9 --- /dev/null +++ b/docs/custom_mutator.txt @@ -0,0 +1,34 @@ +================================================== +Adding custom mutators to AFL using +================================================== +This file describes how you can implement custom mutations to be used in AFL. + +Implemented by Khaled Yakdan from Code Intelligence <yakdan@code-intelligence.de> + + +1) Description +-------------- + +Custom mutator libraries can be passed to afl-fuzz to perform custom mutations +on test cases beyond those available in AFL - for example, to enable structure-aware +fuzzing by using libraries that perform mutations according to a given grammar. + +The custom mutator library is passed to afl-fuzz via the AFL_CUSTOM_MUTATOR_LIBRARY +environment variable. The library must export the afl_custom_mutator() function and +must be compiled as a shared object. For example: + $CC -shared -Wall -O3 <lib-name>.c -o <lib-name>.so + +AFL will call the afl_custom_mutator() function every time it needs to mutate +a test case. For some cases, the format of the mutated data returned from +the custom mutator is not suitable to directly execute the target with this input. +For example, when using libprotobuf-mutator, the data returned is in a protobuf +format which corresponds to a given grammar. In order to execute the target, +the protobuf data must be converted to the plain-text format expected by the target. +In such scenarios, the user can define the afl_pre_save_handler() function. This function +is then transforms the data into the format expected by the API before executing the target. +afl_pre_save_handler is optional and does not have to be implemented if its functionality +is not needed. + +2) Example +---------- +A simple example is provided in ../custom_mutators/ \ No newline at end of file |