aboutsummaryrefslogtreecommitdiff
path: root/examples/argv_fuzzing
diff options
context:
space:
mode:
authorAndrea Fioraldi <andreafioraldi@gmail.com>2020-02-03 13:11:10 +0100
committerAndrea Fioraldi <andreafioraldi@gmail.com>2020-02-03 13:11:10 +0100
commit2fe7889912c9bb340f302a037585b7b1836ac94f (patch)
tree5c3e4e5829f45dce46794ebc2681732738d689fe /examples/argv_fuzzing
parente2eedefc65bec1a04605f117a11ca8bdf9d80323 (diff)
downloadafl++-2fe7889912c9bb340f302a037585b7b1836ac94f.tar.gz
move custom and pythoon mutators examples into examples/
Diffstat (limited to 'examples/argv_fuzzing')
-rw-r--r--examples/argv_fuzzing/Makefile41
-rw-r--r--examples/argv_fuzzing/README.md16
-rw-r--r--examples/argv_fuzzing/argv-fuzz-inl.h90
-rw-r--r--examples/argv_fuzzing/argvfuzz.c49
4 files changed, 196 insertions, 0 deletions
diff --git a/examples/argv_fuzzing/Makefile b/examples/argv_fuzzing/Makefile
new file mode 100644
index 00000000..ab16be87
--- /dev/null
+++ b/examples/argv_fuzzing/Makefile
@@ -0,0 +1,41 @@
+#
+# american fuzzy lop++ - argvfuzz
+# --------------------------------
+#
+# Copyright 2019-2020 Kjell Braden <afflux@pentabarf.de>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+
+.PHONY: all install clean
+
+PREFIX ?= /usr/local
+BIN_PATH = $(PREFIX)/bin
+HELPER_PATH = $(PREFIX)/lib/afl
+
+CFLAGS = -fPIC -Wall -Wextra
+LDFLAGS = -shared
+
+ifneq "$(filter Linux GNU%,$(shell uname))" ""
+ LDFLAGS += -ldl
+endif
+
+all: argvfuzz32.so argvfuzz64.so
+
+argvfuzz32.so: argvfuzz.c
+ -$(CC) -m32 $(CFLAGS) $^ $(LDFLAGS) -o $@ || echo "argvfuzz32 build failure (that's fine)"
+
+argvfuzz64.so: argvfuzz.c
+ -$(CC) $(CFLAGS) $^ $(LDFLAGS) -o $@
+
+install: argvfuzz32.so argvfuzz64.so
+ install -d -m 755 $(DESTDIR)$(HELPER_PATH)/
+ if [ -f argvfuzz32.so ]; then set -e; install -m 755 argvfuzz32.so $(DESTDIR)$(HELPER_PATH)/; fi
+ install -m 755 argvfuzz64.so $(DESTDIR)$(HELPER_PATH)/
+
+clean:
+ rm -f argvfuzz32.so argvfuzz64.so
diff --git a/examples/argv_fuzzing/README.md b/examples/argv_fuzzing/README.md
new file mode 100644
index 00000000..fa8cad80
--- /dev/null
+++ b/examples/argv_fuzzing/README.md
@@ -0,0 +1,16 @@
+# argvfuzz
+
+afl supports fuzzing file inputs or stdin. When source is available,
+`argv-fuzz-inl.h` can be used to change `main()` to build argv from stdin.
+
+`argvfuzz` tries to provide the same functionality for binaries. When loaded
+using `LD_PRELOAD`, it will hook the call to `__libc_start_main` and replace
+argv using the same logic of `argv-fuzz-inl.h`.
+
+A few conditions need to be fulfilled for this mechanism to work correctly:
+
+1. As it relies on hooking the loader, it cannot work on static binaries.
+2. If the target binary does not use the default libc's `_start` implementation
+ (crt1.o), the hook may not run.
+3. The hook will replace argv with pointers to `.data` of `argvfuzz.so`. If the
+ target binary expects argv to be living on the stack, things may go wrong.
diff --git a/examples/argv_fuzzing/argv-fuzz-inl.h b/examples/argv_fuzzing/argv-fuzz-inl.h
new file mode 100644
index 00000000..4d880020
--- /dev/null
+++ b/examples/argv_fuzzing/argv-fuzz-inl.h
@@ -0,0 +1,90 @@
+/*
+ american fuzzy lop++ - sample argv fuzzing wrapper
+ ------------------------------------------------
+
+ Originally written by Michal Zalewski
+
+ Copyright 2015 Google Inc. All rights reserved.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at:
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ This file shows a simple way to fuzz command-line parameters with stock
+ afl-fuzz. To use, add:
+
+ #include "/path/to/argv-fuzz-inl.h"
+
+ ...to the file containing main(), ideally placing it after all the
+ standard includes. Next, put AFL_INIT_ARGV(); near the very beginning of
+ main().
+
+ This will cause the program to read NUL-delimited input from stdin and
+ put it in argv[]. Two subsequent NULs terminate the array. Empty
+ params are encoded as a lone 0x02. Lone 0x02 can't be generated, but
+ that shouldn't matter in real life.
+
+ If you would like to always preserve argv[0], use this instead:
+ AFL_INIT_SET0("prog_name");
+
+*/
+
+#ifndef _HAVE_ARGV_FUZZ_INL
+#define _HAVE_ARGV_FUZZ_INL
+
+#include <unistd.h>
+
+#define AFL_INIT_ARGV() \
+ do { \
+ \
+ argv = afl_init_argv(&argc); \
+ \
+ } while (0)
+
+#define AFL_INIT_SET0(_p) \
+ do { \
+ \
+ argv = afl_init_argv(&argc); \
+ argv[0] = (_p); \
+ if (!argc) argc = 1; \
+ \
+ } while (0)
+
+#define MAX_CMDLINE_LEN 100000
+#define MAX_CMDLINE_PAR 1000
+
+static char** afl_init_argv(int* argc) {
+
+ static char in_buf[MAX_CMDLINE_LEN];
+ static char* ret[MAX_CMDLINE_PAR];
+
+ char* ptr = in_buf;
+ int rc = 0;
+
+ if (read(0, in_buf, MAX_CMDLINE_LEN - 2) < 0) {}
+
+ while (*ptr) {
+
+ ret[rc] = ptr;
+ if (ret[rc][0] == 0x02 && !ret[rc][1]) ret[rc]++;
+ rc++;
+
+ while (*ptr)
+ ptr++;
+ ptr++;
+
+ }
+
+ *argc = rc;
+
+ return ret;
+
+}
+
+#undef MAX_CMDLINE_LEN
+#undef MAX_CMDLINE_PAR
+
+#endif /* !_HAVE_ARGV_FUZZ_INL */
+
diff --git a/examples/argv_fuzzing/argvfuzz.c b/examples/argv_fuzzing/argvfuzz.c
new file mode 100644
index 00000000..4251ca4c
--- /dev/null
+++ b/examples/argv_fuzzing/argvfuzz.c
@@ -0,0 +1,49 @@
+/*
+ american fuzzy lop++ - LD_PRELOAD for fuzzing argv in binaries
+ ------------------------------------------------------------
+
+ Copyright 2019-2020 Kjell Braden <afflux@pentabarf.de>
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at:
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ */
+
+#define _GNU_SOURCE /* for RTLD_NEXT */
+#include <dlfcn.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include "argv-fuzz-inl.h"
+
+int __libc_start_main(int (*main)(int, char **, char **), int argc, char **argv,
+ void (*init)(void), void (*fini)(void),
+ void (*rtld_fini)(void), void *stack_end) {
+
+ int (*orig)(int (*main)(int, char **, char **), int argc, char **argv,
+ void (*init)(void), void (*fini)(void), void (*rtld_fini)(void),
+ void *stack_end);
+ int sub_argc;
+ char **sub_argv;
+
+ (void)argc;
+ (void)argv;
+
+ orig = dlsym(RTLD_NEXT, __func__);
+
+ if (!orig) {
+
+ fprintf(stderr, "hook did not find original %s: %s\n", __func__, dlerror());
+ exit(EXIT_FAILURE);
+
+ }
+
+ sub_argv = afl_init_argv(&sub_argc);
+
+ return orig(main, sub_argc, sub_argv, init, fini, rtld_fini, stack_end);
+
+}
+