diff options
Diffstat (limited to 'custom_mutators')
-rw-r--r-- | custom_mutators/aflpp/aflpp.c | 2 | ||||
-rw-r--r-- | custom_mutators/aflpp/standalone/Makefile | 2 | ||||
-rw-r--r-- | custom_mutators/aflpp/standalone/README.md | 4 | ||||
-rw-r--r-- | custom_mutators/aflpp/standalone/aflpp-standalone.c | 167 | ||||
-rw-r--r-- | custom_mutators/atnwalk/README.md | 2 | ||||
-rw-r--r-- | custom_mutators/atnwalk/atnwalk.c | 3 | ||||
-rw-r--r-- | custom_mutators/autotokens/autotokens.cpp | 20 | ||||
-rw-r--r-- | custom_mutators/autotokens/standalone/Makefile | 19 | ||||
-rw-r--r-- | custom_mutators/autotokens/standalone/README.md | 12 | ||||
-rw-r--r-- | custom_mutators/autotokens/standalone/autotokens-standalone.c | 192 | ||||
-rw-r--r-- | custom_mutators/custom_send_tcp/Makefile | 7 | ||||
-rw-r--r-- | custom_mutators/custom_send_tcp/README.md | 13 | ||||
-rw-r--r-- | custom_mutators/custom_send_tcp/custom_send_tcp.c | 113 | ||||
m--------- | custom_mutators/gramatron/json-c | 0 | ||||
-rw-r--r-- | custom_mutators/grammar_mutator/GRAMMAR_VERSION | 2 | ||||
m--------- | custom_mutators/grammar_mutator/grammar_mutator | 0 | ||||
-rw-r--r-- | custom_mutators/radamsa/libradamsa.c | 2 |
17 files changed, 504 insertions, 56 deletions
diff --git a/custom_mutators/aflpp/aflpp.c b/custom_mutators/aflpp/aflpp.c index 0b236f76..ea50751a 100644 --- a/custom_mutators/aflpp/aflpp.c +++ b/custom_mutators/aflpp/aflpp.c @@ -48,7 +48,7 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size, u8 *ptr = realloc(data->buf, max_size); - if (ptr) { + if (!ptr) { return 0; diff --git a/custom_mutators/aflpp/standalone/Makefile b/custom_mutators/aflpp/standalone/Makefile index f1e99445..d7bc840d 100644 --- a/custom_mutators/aflpp/standalone/Makefile +++ b/custom_mutators/aflpp/standalone/Makefile @@ -4,7 +4,7 @@ CFLAGS = -O3 -funroll-loops -fPIC all: aflpp-standalone aflpp-standalone: aflpp-standalone.c - $(CC) $(CFLAGS) -I../../../include -I. -o aflpp-standalone aflpp-standalone.c ../../../src/afl-performance.c + $(CC) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -o aflpp-standalone aflpp-standalone.c ../../../src/afl-performance.c ../../../src/afl-fuzz-extras.c ../../../src/afl-common.c clean: rm -f *.o *~ aflpp-standalone core diff --git a/custom_mutators/aflpp/standalone/README.md b/custom_mutators/aflpp/standalone/README.md index a1ffb5f9..3c26a29a 100644 --- a/custom_mutators/aflpp/standalone/README.md +++ b/custom_mutators/aflpp/standalone/README.md @@ -5,6 +5,6 @@ this is the AFL++ havoc mutator as a standalone mutator just type `make` to build. ``` -aflpp-standalone inputfile outputfile [splicefile] +aflpp-standalone -h # to see all parameteres +cat file | aflpp-standalone -m 4 -x foo.dict - outputfile splicefile # example ``` - diff --git a/custom_mutators/aflpp/standalone/aflpp-standalone.c b/custom_mutators/aflpp/standalone/aflpp-standalone.c index 3a2cbc2f..c059ce11 100644 --- a/custom_mutators/aflpp/standalone/aflpp-standalone.c +++ b/custom_mutators/aflpp/standalone/aflpp-standalone.c @@ -1,6 +1,12 @@ #include "afl-fuzz.h" #include "afl-mutations.h" +#include <unistd.h> +#include <getopt.h> + +static int max_havoc = 16, verbose; +static unsigned char *dict; + typedef struct my_mutator { afl_state_t *afl; @@ -21,14 +27,14 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) { } - if ((data->buf = malloc(1024*1024)) == NULL) { + if ((data->buf = malloc(1024 * 1024)) == NULL) { perror("afl_custom_init alloc"); return NULL; } else { - data->buf_size = 1024*1024; + data->buf_size = 1024 * 1024; } @@ -36,9 +42,23 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) { data->afl = calloc(1, sizeof(afl_state_t)); data->afl->queue_cycle = 1; data->afl->fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY); - if (data->afl->fsrv.dev_urandom_fd < 0) { PFATAL("Unable to open /dev/urandom"); } + if (data->afl->fsrv.dev_urandom_fd < 0) { + + PFATAL("Unable to open /dev/urandom"); + + } + rand_set_seed(data->afl, getpid()); + if (dict) { + + load_extras(data->afl, dict); + if (verbose) + fprintf(stderr, "Loaded dictionary: %s (%u entries)\n", dict, + data->afl->extras_cnt); + + } + return data; } @@ -53,7 +73,7 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size, u8 *ptr = realloc(data->buf, max_size); - if (ptr) { + if (!ptr) { return 0; @@ -66,14 +86,20 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size, } - u32 havoc_steps = 1 + rand_below(data->afl, 16); + u32 havoc_steps = 1 + rand_below(data->afl, max_havoc); + if (verbose) fprintf(stderr, "Havoc steps: %u\n", havoc_steps); /* set everything up, costly ... :( */ memcpy(data->buf, buf, buf_size); /* the mutation */ - u32 out_buf_len = afl_mutate(data->afl, data->buf, buf_size, havoc_steps, - false, true, add_buf, add_buf_size, max_size); + u32 out_buf_len; + do { + + out_buf_len = afl_mutate(data->afl, data->buf, buf_size, havoc_steps, false, + true, add_buf, add_buf_size, max_size); + + } while (out_buf_len == buf_size && memcmp(buf, data->buf, buf_size) == 0); /* return size of mutated data */ *out_buf = data->buf; @@ -84,80 +110,143 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size, int main(int argc, char *argv[]) { if (argc > 1 && strncmp(argv[1], "-h", 2) == 0) { - printf("Syntax: %s [-v] [inputfile [outputfile [splicefile]]]\n\n", argv[0]); - printf("Reads a testcase from stdin when no input file (or '-') is specified,\n"); - printf("mutates according to AFL++'s mutation engine, and write to stdout when '-' or\n"); - printf("no output filename is given. As an optional third parameter you can give a file\n"); + + printf( + "Syntax: %s [-v] [-m maxmutations] [-x dict] [inputfile [outputfile " + "[splicefile]]]\n\n", + argv[0]); + printf( + "Reads a testcase from stdin when no input file (or '-') is " + "specified,\n"); + printf( + "mutates according to AFL++'s mutation engine, and write to stdout " + "when '-' or\n"); + printf( + "no output filename is given. As an optional third parameter you can " + "give a file\n"); printf("for splicing. Maximum input and output length is 1MB.\n"); - printf("The -v verbose option prints debug output to stderr.\n"); + printf("Options:\n"); + printf(" -v verbose debug output to stderr.\n"); + printf(" -m val max mutations (1-val, val default is 16)\n"); + printf(" -x file dictionary file (AFL++ format)\n"); return 0; + } - FILE *in = stdin, *out = stdout, *splice = NULL; - unsigned char *inbuf = malloc(1024 * 1024), *outbuf, *splicebuf = NULL; - int verbose = 0, splicelen = 0; + FILE *in = stdin, *out = stdout, *splice = NULL; + unsigned char *inbuf = malloc(1024 * 1024), *outbuf = NULL, *splicebuf = NULL; + int splicelen = 0, opt; + + while ((opt = getopt(argc, argv, "vm:x:")) > 0) { + + switch (opt) { + + case 'm': + max_havoc = atoi(optarg); + break; + case 'v': + verbose = 1; + break; + case 'x': + dict = optarg; + break; + default: + fprintf(stderr, "Error: unknown parameter -%c\n", opt); + exit(-1); + + } + + } + + if (max_havoc < 1) { + + fprintf(stderr, "Error: illegal -m value\n"); + exit(-1); - if (argc > 1 && strcmp(argv[1], "-v") == 0) { - verbose = 1; - argc--; - argv++; - fprintf(stderr, "Verbose active\n"); } my_mutator_t *data = afl_custom_init(NULL, 0); - if (argc > 1 && strcmp(argv[1], "-") != 0) { - if ((in = fopen(argv[1], "r")) == NULL) { + if (argc > optind && strcmp(argv[optind], "-") != 0) { + + if ((in = fopen(argv[optind], "r")) == NULL) { + perror(argv[1]); return -1; + } - if (verbose) fprintf(stderr, "Input: %s\n", argv[1]); + + if (verbose) fprintf(stderr, "Input: %s\n", argv[optind]); + } - size_t inlen = fread(inbuf, 1, 1024*1024, in); - + size_t inlen = fread(inbuf, 1, 1024 * 1024, in); + if (!inlen) { - fprintf(stderr, "Error: empty file %s\n", argv[1] ? argv[1] : "stdin"); + + fprintf(stderr, "Error: empty file %s\n", + argv[optind] ? argv[optind] : "stdin"); return -1; + } - if (argc > 2 && strcmp(argv[2], "-") != 0) { - if ((out = fopen(argv[2], "w")) == NULL) { - perror(argv[2]); + if (argc > optind + 1 && strcmp(argv[optind + 1], "-") != 0) { + + if ((out = fopen(argv[optind + 1], "w")) == NULL) { + + perror(argv[optind + 1]); return -1; + } - if (verbose) fprintf(stderr, "Output: %s\n", argv[2]); + + if (verbose) fprintf(stderr, "Output: %s\n", argv[optind + 1]); + } - if (argc > 3) { - if ((splice = fopen(argv[3], "r")) == NULL) { - perror(argv[3]); + if (argc > optind + 2) { + + if ((splice = fopen(argv[optind + 2], "r")) == NULL) { + + perror(argv[optind + 2]); return -1; + } - if (verbose) fprintf(stderr, "Splice: %s\n", argv[3]); - splicebuf = malloc(1024*1024); - size_t splicelen = fread(splicebuf, 1, 1024*1024, splice); + + if (verbose) fprintf(stderr, "Splice: %s\n", argv[optind + 2]); + splicebuf = malloc(1024 * 1024); + size_t splicelen = fread(splicebuf, 1, 1024 * 1024, splice); if (!splicelen) { - fprintf(stderr, "Error: empty file %s\n", argv[3]); + + fprintf(stderr, "Error: empty file %s\n", argv[optind + 2]); return -1; + } + if (verbose) fprintf(stderr, "Mutation splice length: %zu\n", splicelen); + } if (verbose) fprintf(stderr, "Mutation input length: %zu\n", inlen); - unsigned int outlen = afl_custom_fuzz(data, inbuf, inlen, &outbuf, splicebuf, splicelen, 1024*1024); + unsigned int outlen = afl_custom_fuzz(data, inbuf, inlen, &outbuf, splicebuf, + splicelen, 1024 * 1024); if (outlen == 0 || !outbuf) { + fprintf(stderr, "Error: no mutation data returned.\n"); return -1; + } if (verbose) fprintf(stderr, "Mutation output length: %u\n", outlen); if (fwrite(outbuf, 1, outlen, out) != outlen) { + fprintf(stderr, "Warning: incomplete write.\n"); return -1; + } - + return 0; + } + diff --git a/custom_mutators/atnwalk/README.md b/custom_mutators/atnwalk/README.md index 730349a3..7dbe8ee5 100644 --- a/custom_mutators/atnwalk/README.md +++ b/custom_mutators/atnwalk/README.md @@ -13,7 +13,7 @@ Just type `make` to build `atnwalk.so`. **NOTE:** The commands below just demonstrate an example how running ATNwalk looks like and require a working [testbed](https://github.com/atnwalk/testbed) ```bash -# create the required a random seed first +# create the required random seed first mkdir -p ~/campaign/example/seeds cd ~/campaign/example/seeds head -c1 /dev/urandom | ~/atnwalk/build/javascript/bin/decode -wb > seed.decoded 2> seed.encoded diff --git a/custom_mutators/atnwalk/atnwalk.c b/custom_mutators/atnwalk/atnwalk.c index c3a2cd95..45ccc181 100644 --- a/custom_mutators/atnwalk/atnwalk.c +++ b/custom_mutators/atnwalk/atnwalk.c @@ -180,7 +180,8 @@ size_t fail_fatal(int fd_socket, uint8_t **out_buf) { if (fd_socket != -1) { close(fd_socket); } *out_buf = NULL; - return 0; + fprintf(stderr, "atnwalk.socket not found in current directory!\n"); + exit(-1); } diff --git a/custom_mutators/autotokens/autotokens.cpp b/custom_mutators/autotokens/autotokens.cpp index 8135aba1..9bce3da7 100644 --- a/custom_mutators/autotokens/autotokens.cpp +++ b/custom_mutators/autotokens/autotokens.cpp @@ -39,6 +39,7 @@ extern "C" { #ifndef AFL_TXT_MAX_LEN #define AFL_TXT_MAX_LEN 65535 #endif +#define AUTOTOKENS_TXT_MIN_LEN 1 #if AUTOTOKENS_SPLICE_MIN >= AUTOTOKENS_SIZE_MIN #error SPLICE_MIN must be lower than SIZE_MIN @@ -57,8 +58,9 @@ typedef struct my_mutator { if (unlikely(debug)) fprintf #define IFDEBUG if (unlikely(debug)) +int module_disabled = 0; + static afl_state *afl_ptr; -static int module_disabled = 0; static int auto_disable = AUTOTOKENS_AUTO_DISABLE; static int debug = AUTOTOKENS_DEBUG; static int only_fav = AUTOTOKENS_ONLY_FAV; @@ -104,9 +106,9 @@ static void first_run(void *data) { if (afl_ptr->custom_only || !auto_disable) { return; } if (unlikely(afl_ptr->active_items == 1 && - afl_ptr->queue_cur->len < AFL_TXT_MIN_LEN)) { + afl_ptr->queue_cur->len < AUTOTOKENS_TXT_MIN_LEN)) { - if (afl_ptr->extras_cnt > 8) { + if (afl_ptr->extras_cnt) { u32 valid = 0; @@ -237,7 +239,7 @@ extern "C" u32 afl_custom_fuzz_count(void *data, const u8 *buf, } -extern "C" size_t afl_custom_fuzz(my_mutator_t *data, u8 *buf, size_t buf_size, +extern "C" size_t afl_custom_fuzz(void *data, u8 *buf, size_t buf_size, u8 **out_buf, u8 *add_buf, size_t add_buf_size, size_t max_size) { @@ -655,6 +657,7 @@ extern "C" unsigned char afl_custom_queue_get(void *data, if (current_id > whitespace_ids + 6 && afl_ptr->active_items == 1 && afl_ptr->queue_cur->len < AFL_TXT_MIN_LEN) { + retry_thin_air: DEBUGF(stderr, "Creating an entry from thin air...\n"); structure = new vector<u32>(); u32 item, prev, cnt = current_id >> 1; @@ -684,8 +687,6 @@ extern "C" unsigned char afl_custom_queue_get(void *data, } - create_from_thin_air = 0; - } if (entry == file_mapping.end()) { @@ -693,7 +694,7 @@ extern "C" unsigned char afl_custom_queue_get(void *data, // this input file was not analyzed for tokens yet, so let's do it! size_t len = afl_ptr->queue_cur->len; - if (len < AFL_TXT_MIN_LEN) { + if (len < AUTOTOKENS_TXT_MIN_LEN) { file_mapping[fn] = structure; // NULL ptr so we don't read the file again s = NULL; @@ -895,6 +896,7 @@ extern "C" unsigned char afl_custom_queue_get(void *data, if (tokens.size() < AUTOTOKENS_SIZE_MIN) { + if (create_from_thin_air) { goto retry_thin_air; } file_mapping[fn] = NULL; s = NULL; DEBUGF(stderr, "too few tokens\n"); @@ -955,7 +957,7 @@ extern "C" unsigned char afl_custom_queue_get(void *data, } -extern "C" my_mutator_t *afl_custom_init(afl_state *afl, unsigned int seed) { +extern "C" void *afl_custom_init(afl_state_t *afl, unsigned int seed) { (void)(seed); my_mutator_t *data = (my_mutator_t *)calloc(1, sizeof(my_mutator_t)); @@ -1070,7 +1072,7 @@ extern "C" my_mutator_t *afl_custom_init(afl_state *afl, unsigned int seed) { id_to_token[current_id] = "'"; ++current_id; - return data; + return (void *)data; } diff --git a/custom_mutators/autotokens/standalone/Makefile b/custom_mutators/autotokens/standalone/Makefile new file mode 100644 index 00000000..8d5baf13 --- /dev/null +++ b/custom_mutators/autotokens/standalone/Makefile @@ -0,0 +1,19 @@ + +CFLAGS = -g -O3 -funroll-loops -fPIC -D_STANDALONE_MODULE=1 -Wno-implicit-function-declaration +CXXFLAGS= -g -O3 -funroll-loops -fPIC -D_STANDALONE_MODULE=1 + +all: autotokens-standalone + +autotokens.o: ../autotokens.cpp + $(CXX) $(CXXFLAGS) -I../../../include -I. -I../.. -c ../autotokens.cpp + +autotokens-standalone: autotokens-standalone.c autotokens.o + $(CC) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -c autotokens-standalone.c + $(CC) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -c ../../../src/afl-performance.c + $(CC) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -c ../../../src/afl-fuzz-extras.c + $(CC) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -c ../../../src/afl-fuzz-queue.c + $(CC) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -c ../../../src/afl-common.c + $(CXX) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -o autotokens-standalone *.o + +clean: + rm -f *.o *~ autotokens-standalone core diff --git a/custom_mutators/autotokens/standalone/README.md b/custom_mutators/autotokens/standalone/README.md new file mode 100644 index 00000000..9e9babf7 --- /dev/null +++ b/custom_mutators/autotokens/standalone/README.md @@ -0,0 +1,12 @@ +# Autotokens standalone mutator + +this is a standalone version of the AFL++ autotokens custom mutator. + +just type `make` to build. + +You *MUST* use a dictionary file to have an effective grammarless grammar fuzzer! + +``` +autotokens-standalone -h # to see all parameteres +autotokens-standalone -x foo.dict inputfile outputfile # example +``` diff --git a/custom_mutators/autotokens/standalone/autotokens-standalone.c b/custom_mutators/autotokens/standalone/autotokens-standalone.c new file mode 100644 index 00000000..e7a09cb3 --- /dev/null +++ b/custom_mutators/autotokens/standalone/autotokens-standalone.c @@ -0,0 +1,192 @@ +#include "afl-fuzz.h" +#include "afl-mutations.h" + +#include <unistd.h> +#include <getopt.h> + +static int max_havoc = 16, verbose; +static unsigned char *dict, *mh = "16"; + +extern int module_disabled; + +void *afl_custom_init(afl_state_t *, unsigned int); + +int main(int argc, char *argv[]) { + + if (argc > 1 && strncmp(argv[1], "-h", 2) == 0) { + + printf( + "Syntax: %s [-v] [-m maxmutations] [-x dict] [inputfile [outputfile " + "[splicefile]]]\n\n", + argv[0]); + printf("Reads a testcase from a file (not stdin!),\n"); + printf("writes to stdout when '-' or\n"); + printf( + "no output filename is given. As an optional third parameter you can " + "give a file\n"); + printf("for splicing. Maximum input and output length is 1MB.\n"); + printf("Options:\n"); + printf(" -v verbose debug output to stderr.\n"); + printf(" -m val max mutations (1-val, val default is 16)\n"); + printf(" -x file dictionary file (AFL++ format)\n"); + printf("You can set the following environment variable parameters:\n"); + printf("AUTOTOKENS_COMMENT` - what character or string starts a comment which will be\n"); + printf(" removed. Default: \"/* ... */\"\n"); + return 0; + + } + + FILE *in = stdin, *out = stdout, *splice = NULL; + unsigned char *inbuf = malloc(1024 * 1024), *outbuf = NULL, *splicebuf = NULL; + int splicelen = 0, opt; + + while ((opt = getopt(argc, argv, "vm:x:")) > 0) { + + switch (opt) { + + case 'm': + max_havoc = atoi(optarg); + mh = optarg; + break; + case 'v': + verbose = 1; + break; + case 'x': + dict = optarg; + break; + default: + fprintf(stderr, "Error: unknown parameter -%c\n", opt); + exit(-1); + + } + + } + + if (max_havoc < 1) { + + fprintf(stderr, "Error: illegal -m value\n"); + exit(-1); + + } + + if (argc > optind && strcmp(argv[optind], "-") != 0) { + + if ((in = fopen(argv[optind], "r")) == NULL) { + + perror(argv[1]); + return -1; + + } + + if (verbose) fprintf(stderr, "Input: %s\n", argv[optind]); + + } + + size_t inlen = fread(inbuf, 1, 1024 * 1024, in); + + if (!inlen) { + + fprintf(stderr, "Error: empty file %s\n", + argv[optind] ? argv[optind] : "stdin"); + return -1; + + } + + if (argc > optind + 1 && strcmp(argv[optind + 1], "-") != 0) { + + if ((out = fopen(argv[optind + 1], "w")) == NULL) { + + perror(argv[optind + 1]); + return -1; + + } + + if (verbose) fprintf(stderr, "Output: %s\n", argv[optind + 1]); + + } + + if (argc > optind + 2) { + + if ((splice = fopen(argv[optind + 2], "r")) == NULL) { + + perror(argv[optind + 2]); + return -1; + + } + + if (verbose) fprintf(stderr, "Splice: %s\n", argv[optind + 2]); + splicebuf = malloc(1024 * 1024); + size_t splicelen = fread(splicebuf, 1, 1024 * 1024, splice); + if (!splicelen) { + + fprintf(stderr, "Error: empty file %s\n", argv[optind + 2]); + return -1; + + } + + if (verbose) fprintf(stderr, "Mutation splice length: %zu\n", splicelen); + + } + + /* configure autotokens */ + setenv("AUTOTOKENS_LEARN_DICT", "1", 0); + setenv("AUTOTOKENS_CREATE_FROM_THIN_AIR", "1", 0); + setenv("AUTOTOKENS_CHANGE_MAX", mh, 0); + + /* fake AFL++ state */ + afl_state_t *afl = (afl_state_t *)calloc(1, sizeof(afl_state_t)); + afl->queue_cycle = afl->havoc_div = afl->active_items = afl->queued_items = 1; + afl->shm.cmplog_mode = 0; + afl->fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY); + if (afl->fsrv.dev_urandom_fd < 0) { PFATAL("Unable to open /dev/urandom"); } + + rand_set_seed(afl, getpid()); + + if (dict) { + + load_extras(afl, dict); + if (verbose) + fprintf(stderr, "Loaded dictionary: %s (%u entries)\n", dict, + afl->extras_cnt); + + } + + // setup a fake queue entry + afl->queue_buf = malloc(64); + afl->queue_buf[0] = afl->queue_cur = + (struct queue_entry *)malloc(sizeof(struct queue_entry)); + afl->queue_cur->testcase_buf = inbuf; + afl->queue_cur->fname = (u8 *)argv[optind]; + afl->queue_cur->len = inlen; + afl->queue_cur->perf_score = 100; + afl->queue_cur->favored = afl->queue_cur->is_ascii = 1; + // afl->custom_only = 1; + + void *data = (void *)afl_custom_init(afl, (u32)0); + + u8 res = afl_custom_queue_get(inbuf, (u8 *)argv[optind]); + + if (verbose) fprintf(stderr, "Mutation input length: %zu\n", inlen); + unsigned int outlen = afl_custom_fuzz(data, inbuf, inlen, &outbuf, splicebuf, + splicelen, 1024 * 1024); + + if (outlen == 0 || !outbuf) { + + fprintf(stderr, "Error: no mutation data returned.\n"); + return -1; + + } + + if (verbose) fprintf(stderr, "Mutation output length: %u\n", outlen); + + if (fwrite(outbuf, 1, outlen, out) != outlen) { + + fprintf(stderr, "Warning: incomplete write.\n"); + return -1; + + } + + return 0; + +} + diff --git a/custom_mutators/custom_send_tcp/Makefile b/custom_mutators/custom_send_tcp/Makefile new file mode 100644 index 00000000..8549ccad --- /dev/null +++ b/custom_mutators/custom_send_tcp/Makefile @@ -0,0 +1,7 @@ +all: custom_send_tcp.so + +custom_send_tcp.so: + $(CC) -Wno-unused-result -g -O3 -shared -fPIC -o custom_send_tcp.so -I../../include custom_send_tcp.c + +clean: + rm -f custom_send_tcp.so *.o *~ core diff --git a/custom_mutators/custom_send_tcp/README.md b/custom_mutators/custom_send_tcp/README.md new file mode 100644 index 00000000..7b4bb869 --- /dev/null +++ b/custom_mutators/custom_send_tcp/README.md @@ -0,0 +1,13 @@ +# Send testcases via TCP custom mutator + +This custom mutator sends the fuzzing testcases via TCP. + +`AFL_CUSTOM_MUTATOR_LATE_SEND` - MUST be set! +`CUSTOM_SEND_IP` - the IP address to send to (basically only 127.0.0.1 makes sense) +`CUSTOM_SEND_PORT` - the TCP port to send to +`CUSTOM_SEND_READ` - if the custom mutator should wait for a reply from the target + +Example: +``` +CUSTOM_SEND_IP=127.0.0.1 CUSTOM_SEND_PORT=8000 CUSTOM_SEND_READ=1 AFL_CUSTOM_MUTATOR_LATE_SEND=1 AFL_CUSTOM_MUTATOR_LIBRARY=custom_send_tcp.so ./afl-fuzz ... +``` diff --git a/custom_mutators/custom_send_tcp/custom_send_tcp.c b/custom_mutators/custom_send_tcp/custom_send_tcp.c new file mode 100644 index 00000000..53689ced --- /dev/null +++ b/custom_mutators/custom_send_tcp/custom_send_tcp.c @@ -0,0 +1,113 @@ +#include <time.h> +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <arpa/inet.h> +#include <sys/select.h> + +#include "afl-fuzz.h" + +static int my_debug = 0; +static int my_read = 0; + +#define DEBUG(...) if (my_debug) printf(__VA_ARGS__) + +typedef struct tcp_send_mutator { + afl_state_t* afl; + struct sockaddr_in server_addr; +} tcp_send_mutator_t; + +void *afl_custom_init(afl_state_t* afl, uint32_t seed) { + const char* ip = getenv("CUSTOM_SEND_IP"); + const char* port = getenv("CUSTOM_SEND_PORT"); + + if (getenv("AFL_DEBUG")) my_debug = 1; + if (getenv("CUSTOM_SEND_READ")) my_read = 1; + + if (!ip || !port) { + fprintf(stderr, "You forgot to set CUSTOM_SEND_IP and/or CUSTOM_SEND_PORT\n"); + exit(1); + } + + tcp_send_mutator_t* mutator = calloc(1, sizeof(tcp_send_mutator_t)); + if (!mutator) { + fprintf(stderr, "Failed to allocate mutator struct\n"); + exit(1); + } + + mutator->afl = afl; + + bzero(&mutator->server_addr, sizeof(mutator->server_addr)); + mutator->server_addr.sin_family = AF_INET; + if (inet_pton(AF_INET, ip, &mutator->server_addr.sin_addr) <= 0) { + fprintf(stderr, "Could not convert target ip address!\n"); + exit(1); + } + mutator->server_addr.sin_port = htons(atoi(port)); + + printf("[+] Custom tcp send mutator setup ready to go!\n"); + + return mutator; +} + +int try_connect(tcp_send_mutator_t *mutator, int sock, int max_attempts) { + while (max_attempts > 0) { + if (connect(sock, (struct sockaddr*)&mutator->server_addr, sizeof(mutator->server_addr)) == 0) { + return 0; + } + + // Even with AFL_CUSTOM_LATE_SEND=1, there is a race between the + // application under test having started to listen for connections and + // afl_custom_fuzz_send being called. To address this race, we attempt + // to connect N times and sleep a short period of time in between + // connection attempts. + struct timespec t; + t.tv_sec = 0; + t.tv_nsec = 100; + nanosleep(&t, NULL); + --max_attempts; + } + return 1; +} + +void afl_custom_fuzz_send(tcp_send_mutator_t *mutator, uint8_t *buf, size_t buf_size) { + int sock = socket(AF_INET, SOCK_STREAM, 0); + + int written = 0; + if (sock >= 0 && try_connect(mutator, sock, 10000) == 0) { + DEBUG("connected, write()\n"); + written = write(sock, buf, buf_size); + } else { + DEBUG("socket() or connect() error: %d\n", errno); + } + + if (written < 0) { + DEBUG("write() error: %d\n", errno); + } else if (my_read) { + struct timeval timeout; + timeout.tv_sec = 1; + timeout.tv_usec = 0; + + fd_set set; + FD_ZERO(&set); + FD_SET(sock, &set); + + int select_res = select(sock + 1, &set, NULL, NULL, &timeout); + if (select_res == -1) { + DEBUG("select() error: %d\n", errno); + } else if (select_res == 0) { + DEBUG("read() timeout!\n"); + } else { + uint8_t buf[64]; + (void)read(sock, buf, sizeof(buf)); + } + } + + close(sock); +} + +void afl_custom_deinit(tcp_send_mutator_t* mutator) { + free(mutator); +} diff --git a/custom_mutators/gramatron/json-c b/custom_mutators/gramatron/json-c -Subproject 11546bfd07a575c47416924cb98de3d33a4e642 +Subproject af8dd4a307e7b837f9fa2959549548ace4afe08 diff --git a/custom_mutators/grammar_mutator/GRAMMAR_VERSION b/custom_mutators/grammar_mutator/GRAMMAR_VERSION index 02119caf..eea76ba3 100644 --- a/custom_mutators/grammar_mutator/GRAMMAR_VERSION +++ b/custom_mutators/grammar_mutator/GRAMMAR_VERSION @@ -1 +1 @@ -95a6857 +05d8f53 diff --git a/custom_mutators/grammar_mutator/grammar_mutator b/custom_mutators/grammar_mutator/grammar_mutator -Subproject 95a685773e571620cb6e2788dbbdba333e1b9bf +Subproject 05d8f537f8d656f0754e7ad5dcc653c42cb4f8f diff --git a/custom_mutators/radamsa/libradamsa.c b/custom_mutators/radamsa/libradamsa.c index e6838752..1dcf91d8 100644 --- a/custom_mutators/radamsa/libradamsa.c +++ b/custom_mutators/radamsa/libradamsa.c @@ -3707,7 +3707,7 @@ typedef intptr_t wdiff; 1024 * 1024 * 8 /* static malloc'd heap size if used as a library */ #define FBITS 24 /* bits in fixnum, on the way to 24 and beyond */ #define FMAX \ - ((1 << FBITS) - 1) /* maximum fixnum (and most negative fixnum) \ + ((1U << FBITS) - 1) /* maximum fixnum (and most negative fixnum) \ */ #define MAXOBJ 0xffff /* max words in tuple including header */ #define MAXPAYL \ |