qemu ld_preload support and added socket_fuzzing ld_preload library
MODIFY
Makefile
Makefile
@@ -274,6 +274,8 @@ code-format:
./.custom-format.py -i gcc_plugin/*.c
#./.custom-format.py -i gcc_plugin/*.h
./.custom-format.py -i gcc_plugin/*.cc
+ ./.custom-format.py -i experimental/*/*.c
+ ./.custom-format.py -i experimental/*/*.h
./.custom-format.py -i qemu_mode/patches/*.h
./.custom-format.py -i qemu_mode/libcompcov/*.c
./.custom-format.py -i qemu_mode/libcompcov/*.cc
@@ -316,6 +318,7 @@ clean:
-$(MAKE) -C gcc_plugin clean
$(MAKE) -C libdislocator clean
$(MAKE) -C libtokencap clean
+ $(MAKE) -C experimental/socket_fuzzing clean
$(MAKE) -C experimental/argv_fuzzing clean
$(MAKE) -C qemu_mode/unsigaction clean
$(MAKE) -C qemu_mode/libcompcov clean
@@ -327,6 +330,7 @@ distrib: all radamsa
-$(MAKE) -C gcc_plugin
$(MAKE) -C libdislocator
$(MAKE) -C libtokencap
+ $(MAKE) -C experimental/socket_fuzzing
$(MAKE) -C experimental/argv_fuzzing
cd qemu_mode && sh ./build_qemu_support.sh
cd unicorn_mode && sh ./build_unicorn_support.sh
@@ -334,6 +338,7 @@ distrib: all radamsa
binary-only: all radamsa
$(MAKE) -C libdislocator
$(MAKE) -C libtokencap
+ $(MAKE) -C experimental/socket_fuzzing
$(MAKE) -C experimental/argv_fuzzing
cd qemu_mode && sh ./build_qemu_support.sh
cd unicorn_mode && sh ./build_unicorn_support.sh
@@ -385,6 +390,7 @@ endif
if [ -f libcompcov.so ]; then set -e; install -m 755 libcompcov.so $${DESTDIR}$(HELPER_PATH); fi
if [ -f libradamsa.so ]; then set -e; install -m 755 libradamsa.so $${DESTDIR}$(HELPER_PATH); fi
if [ -f afl-fuzz-document ]; then set -e; install -m 755 afl-fuzz-document $${DESTDIR}$(BIN_PATH); fi
+ $(MAKE) -C experimental/socket_fuzzing install
$(MAKE) -C experimental/argv_fuzzing install
set -e; ln -sf afl-gcc $${DESTDIR}$(BIN_PATH)/afl-g++

MODIFY
docs/ChangeLog
docs/ChangeLog
@@ -17,8 +17,10 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
Version ++2.59d (develop):
--------------------------
- - your patch? :-)
-
+ - added ./experimental/argv_fuzzing ld_preload library by Kjell Braden
+ - added preeny's desock_dup ld_preload library as
+ ./experimental/socket_fuzzing for network fuzzing
+ - we now set QEMU_SET_ENV from AFL_PRELOAD when qemu_mode is used
--------------------------

MODIFY
experimental/argv_fuzzing/Makefile
experimental/argv_fuzzing/Makefile
@@ -23,12 +23,13 @@ LDFLAGS = -shared -ldl
all: argvfuzz32.so argvfuzz64.so
argvfuzz32.so: argvfuzz.c
- $(CC) -m32 $(CFLAGS) $^ $(LDFLAGS) -o $@ || echo "argvfuzz32 build failure (that's fine)"
+ -$(CC) -m32 $(CFLAGS) $^ $(LDFLAGS) -o $@ || echo "argvfuzz32 build failure (that's fine)"
argvfuzz64.so: argvfuzz.c
- $(CC) $(CFLAGS) $^ $(LDFLAGS) -o $@
+ -$(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)/

MODIFY
experimental/argv_fuzzing/argv-fuzz-inl.h
experimental/argv_fuzzing/argv-fuzz-inl.h
#include <unistd.h>
-#define AFL_INIT_ARGV() do { argv = afl_init_argv(&argc); } while (0)
+#define AFL_INIT_ARGV() \
+ do { \
+ \
+ argv = afl_init_argv(&argc); \
+ \
+ } while (0)
-#define AFL_INIT_SET0(_p) do { \
+#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
@@ -55,7 +63,7 @@ static char** afl_init_argv(int* argc) {
char* ptr = in_buf;
int rc = 0;
- if (read(0, in_buf, MAX_CMDLINE_LEN - 2) < 0);
+ if (read(0, in_buf, MAX_CMDLINE_LEN - 2) < 0) {}
while (*ptr) {
@@ -63,7 +71,8 @@ static char** afl_init_argv(int* argc) {
if (ret[rc][0] == 0x02 && !ret[rc][1]) ret[rc]++;
rc++;
- while (*ptr) ptr++;
+ while (*ptr)
+ ptr++;
ptr++;
}
@@ -78,3 +87,4 @@ static char** afl_init_argv(int* argc) {
#undef MAX_CMDLINE_PAR
#endif /* !_HAVE_ARGV_FUZZ_INL */
+

MODIFY
experimental/persistent_demo/persistent_demo.c
experimental/persistent_demo/persistent_demo.c
#include <signal.h>
#include <string.h>
-
/* Main entry point. */
int main(int argc, char** argv) {
@@ -64,21 +63,28 @@ int main(int argc, char** argv) {
We just have some trivial inline code that faults on 'foo!'. */
/* do we have enough data? */
- if (len < 4)
- return 0;
+ if (len < 4) return 0;
if (buf[0] == 'f') {
+
printf("one\n");
if (buf[1] == 'o') {
+
printf("two\n");
if (buf[2] == 'o') {
+
printf("three\n");
if (buf[3] == '!') {
+
printf("four\n");
abort();
+
}
+
}
+
}
+
}
/*** END PLACEHOLDER CODE ***/
@@ -92,3 +98,4 @@ int main(int argc, char** argv) {
return 0;
}
+

MODIFY
experimental/post_library/post_library.so.c
experimental/post_library/post_library.so.c
in the targeted binary (as shown in ../libpng_no_checksum/). One possible
exception is the process of fuzzing binary-only software in QEMU mode.
- 2) The use of postprocessors for anything other than checksums is questionable
- and may cause more harm than good. AFL is normally pretty good about
- dealing with length fields, magic values, etc.
+ 2) The use of postprocessors for anything other than checksums is
+ questionable and may cause more harm than good. AFL is normally pretty good
+ about dealing with length fields, magic values, etc.
3) Postprocessors that do anything non-trivial must be extremely robust to
gracefully handle malformed data and other error conditions - otherwise,
@@ -117,3 +117,4 @@ const unsigned char* afl_postprocess(const unsigned char* in_buf,
return new_buf;
}
+

MODIFY
experimental/post_library/post_library_png.so.c
experimental/post_library/post_library_png.so.c
@@ -111,3 +111,4 @@ const unsigned char* afl_postprocess(const unsigned char* in_buf,
return new_buf;
}
+

ADD
experimental/socket_fuzzing/Makefile
+#
+# american fuzzy lop++ - socket_fuzz
+# ----------------------------------
+#
+# 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 -ldl
+
+all: socketfuzz32.so socketfuzz64.so
+
+socketfuzz32.so: socketfuzz.c
+ -$(CC) -m32 $(CFLAGS) $^ $(LDFLAGS) -o $@ || echo "socketfuzz32 build failure (that's fine)"
+
+socketfuzz64.so: socketfuzz.c
+ -$(CC) $(CFLAGS) $^ $(LDFLAGS) -o $@
+
+install: socketfuzz32.so socketfuzz64.so
+ install -d -m 755 $(DESTDIR)$(HELPER_PATH)/
+ if [ -f socketfuzz32.so ]; then set -e; install -m 755 socketfuzz32.so $(DESTDIR)$(HELPER_PATH)/; fi
+ install -m 755 socketfuzz64.so $(DESTDIR)$(HELPER_PATH)/
+
+clean:
+ rm -f socketfuzz32.so socketfuzz64.so

ADD
experimental/socket_fuzzing/README.md
+# socketfuzz
+
+when you want to fuzz a network service and you can not/do not want to modify
+the source (or just have a binary), then this LD_PRELOAD library will allow
+for sending input to stdin which the target binary will think is coming from
+a network socket.
+
+This is desock_dup.c from the amazing preeny project
+https://github.com/zardus/preeny
+
+It is packaged in afl++ to have it at hand if needed

ADD
experimental/socket_fuzzing/socketfuzz.c
+/*
+ * This is desock_dup.c from the amazing preeny project
+ * https://github.com/zardus/preeny
+ *
+ * It is packaged in afl++ to have it at hand if needed
+ *
+ */
+
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h> //
+#include <sys/socket.h> //
+#include <sys/stat.h> //
+#include <fcntl.h> //
+#include <netinet/in.h>
+#include <pthread.h>
+#include <signal.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include <stdio.h>
+#include <poll.h>
+//#include "logging.h" // switche from preeny_info() to fprintf(stderr, "Info: "
+
+//
+// originals
+//
+int (*original_close)(int);
+int (*original_dup2)(int, int);
+__attribute__((constructor)) void preeny_desock_dup_orig() {
+
+ original_close = dlsym(RTLD_NEXT, "close");
+ original_dup2 = dlsym(RTLD_NEXT, "dup2");
+
+}
+
+int close(int sockfd) {
+
+ if (sockfd <= 2) {
+
+ fprintf(stderr, "Info: Disabling close on %d\n", sockfd);
+ return 0;
+
+ } else {
+
+ return original_close(sockfd);
+
+ }
+
+}
+
+int dup2(int old, int new) {
+
+ if (new <= 2) {
+
+ fprintf(stderr, "Info: Disabling dup from %d to %d\n", old, new);
+ return 0;
+
+ } else {
+
+ return original_dup2(old, new);
+
+ }
+
+}
+
+int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
+
+ fprintf(stderr, "Info: Emulating accept on %d\n", sockfd);
+ return 0;
+
+}
+
+int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
+
+ fprintf(stderr, "Info: Emulating bind on port %d\n",
+ ntohs(((struct sockaddr_in *)addr)->sin_port));
+ return 0;
+
+}
+
+int listen(int sockfd, int backlog) {
+
+ return 0;
+
+}
+

MODIFY
src/afl-fuzz-stats.c
src/afl-fuzz-stats.c
@@ -576,10 +576,10 @@ void show_stats(void) {
" imported : " cRST "%-10s" bSTG bV "\n",
tmp, sync_id ? DI(queued_imported) : (u8*)"n/a");
- sprintf(tmp, "%s/%s, %s/%s, %s/%s",
- DI(stage_finds[STAGE_HAVOC]), DI(stage_cycles[STAGE_HAVOC]),
- DI(stage_finds[STAGE_SPLICE]), DI(stage_cycles[STAGE_SPLICE]),
- DI(stage_finds[STAGE_RADAMSA]), DI(stage_cycles[STAGE_RADAMSA]));
+ sprintf(tmp, "%s/%s, %s/%s, %s/%s", DI(stage_finds[STAGE_HAVOC]),
+ DI(stage_cycles[STAGE_HAVOC]), DI(stage_finds[STAGE_SPLICE]),
+ DI(stage_cycles[STAGE_SPLICE]), DI(stage_finds[STAGE_RADAMSA]),
+ DI(stage_cycles[STAGE_RADAMSA]));
SAYF(bV bSTOP " havoc/rad : " cRST "%-36s " bSTG bV bSTOP, tmp);
@@ -596,13 +596,12 @@ void show_stats(void) {
: cRST),
tmp);
- sprintf(tmp, "%s/%s, %s/%s",
- DI(stage_finds[STAGE_PYTHON]), DI(stage_cycles[STAGE_PYTHON]),
- DI(stage_finds[STAGE_CUSTOM_MUTATOR]),
+ sprintf(tmp, "%s/%s, %s/%s", DI(stage_finds[STAGE_PYTHON]),
+ DI(stage_cycles[STAGE_PYTHON]), DI(stage_finds[STAGE_CUSTOM_MUTATOR]),
DI(stage_cycles[STAGE_CUSTOM_MUTATOR]));
- SAYF(bV bSTOP " py/custom : " cRST "%-36s " bSTG bVR bH20 bH2 bH bRB
- "\n", tmp);
+ SAYF(bV bSTOP " py/custom : " cRST "%-36s " bSTG bVR bH20 bH2 bH bRB "\n",
+ tmp);
if (!bytes_trim_out) {
@@ -639,13 +638,11 @@ void show_stats(void) {
sprintf(tmp, "%s/%s", DI(stage_finds[STAGE_CUSTOM_MUTATOR]),
DI(stage_cycles[STAGE_CUSTOM_MUTATOR]));
- SAYF(bV bSTOP " custom mut. : " cRST "%-36s " bSTG bV RESET_G1,
- tmp);
+ SAYF(bV bSTOP " custom mut. : " cRST "%-36s " bSTG bV RESET_G1, tmp);
} else {
- SAYF(bV bSTOP " trim : " cRST "%-36s " bSTG bV RESET_G1,
- tmp);
+ SAYF(bV bSTOP " trim : " cRST "%-36s " bSTG bV RESET_G1, tmp);
}

MODIFY
src/afl-fuzz.c
src/afl-fuzz.c
@@ -705,13 +705,40 @@ int main(int argc, char** argv) {
if (dumb_mode == 2 && no_forkserver)
FATAL("AFL_DUMB_FORKSRV and AFL_NO_FORKSRV are mutually exclusive");
+ if (getenv("LD_PRELOAD"))
+ WARNF(
+ "LD_PRELOAD is set, are you sure that is want to you want to do "
+ "instead of using AFL_PRELOAD?");
+
if (getenv("AFL_PRELOAD")) {
+ if (qemu_mode) {
+
+ char* qemu_preload = getenv("QEMU_SET_ENV");
+ char buf[4096];
+
+ if (qemu_preload) {
+
+ snprintf(buf, sizeof(buf), "%s,LD_PRELOAD=%s", qemu_preload,
+ getenv("AFL_PRELOAD"));
+
+ } else {
+
+ snprintf(buf, sizeof(buf), "LD_PRELOAD=%s", getenv("AFL_PRELOAD"));
+
+ }
+
+ setenv("QEMU_SET_ENV", buf, 1);
+
+ } else {
+
setenv("LD_PRELOAD", getenv("AFL_PRELOAD"), 1);
setenv("DYLD_INSERT_LIBRARIES", getenv("AFL_PRELOAD"), 1);
}
+ }
+
if (getenv("AFL_LD_PRELOAD"))
FATAL("Use AFL_PRELOAD instead of AFL_LD_PRELOAD");

qemu ld_preload support and added socket_fuzzing ld_preload library