mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-18 20:48:07 +00:00
added initial defork example
This commit is contained in:
64
examples/defork/Makefile
Normal file
64
examples/defork/Makefile
Normal file
@ -0,0 +1,64 @@
|
||||
#
|
||||
# american fuzzy lop++ - defork
|
||||
# ----------------------------------
|
||||
#
|
||||
# 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
|
||||
|
||||
UNAME_SAYS_LINUX=$(shell uname | grep -E '^Linux|^GNU' >/dev/null; echo $$?)
|
||||
UNAME_SAYS_LINUX:sh=uname | grep -E '^Linux|^GNU' >/dev/null; echo $$?
|
||||
|
||||
_LDFLAGS_ADD=$(UNAME_SAYS_LINUX:1=)
|
||||
LDFLAGS_ADD=$(_LDFLAGS_ADD:0=-ldl)
|
||||
LDFLAGS += $(LDFLAGS_ADD)
|
||||
|
||||
# on gcc for arm there is no -m32, but -mbe32
|
||||
M32FLAG = -m32
|
||||
M64FLAG = -m64
|
||||
|
||||
CC_IS_GCC=$(shell $(CC) --version 2>/dev/null | grep -q gcc; echo $$?)
|
||||
CC_IS_GCC:sh=$(CC) --version 2>/dev/null | grep -q gcc; echo $$?
|
||||
CC_IS_ARMCOMPILER=$(shell $(CC) -v 2>&1 >/dev/null | grep -q arm; echo $$?)
|
||||
CC_IS_ARMCOMPILER:sh=$(CC) -v 2>&1 >/dev/null | grep -q arm; echo $$?
|
||||
|
||||
_M32FLAG=$(CC_IS_GCC)$(CC_IS_ARMCOMPILER)
|
||||
__M32FLAG=$(_M32FLAG:00=-mbe32)
|
||||
___M32FLAG=$(__M32FLAG:$(CC_IS_GCC)$(CC_IS_ARMCOMPILER)=-m32)
|
||||
M32FLAG=$(___M32FLAG)
|
||||
#ifeq "$(findstring clang, $(shell $(CC) --version 2>/dev/null))" ""
|
||||
# ifneq (,$(findstring arm, "$(shell $(CC) -v 2>&1 >/dev/null)"))
|
||||
# M32FLAG = -mbe32
|
||||
# endif
|
||||
#endif
|
||||
|
||||
all: defork32.so defork64.so
|
||||
|
||||
defork32.so: defork.c
|
||||
-@$(CC) $(M32FLAG) $(CFLAGS) $^ $(LDFLAGS) -o $@ 2>/dev/null || echo "defork32 build failure (that's fine)"
|
||||
|
||||
defork64.so: defork.c
|
||||
-@$(CC) $(M64FLAG) $(CFLAGS) $^ $(LDFLAGS) -o $@ 2>/dev/null || echo "defork64 build failure (that's fine)"
|
||||
|
||||
install: defork32.so defork64.so
|
||||
install -d -m 755 $(DESTDIR)$(HELPER_PATH)/
|
||||
if [ -f defork32.so ]; then set -e; install -m 755 defork32.so $(DESTDIR)$(HELPER_PATH)/; fi
|
||||
if [ -f defork64.so ]; then set -e; install -m 755 defork64.so $(DESTDIR)$(HELPER_PATH)/; fi
|
||||
|
||||
target:
|
||||
../../afl-clang forking_target.c -o forking_target -Wall -Wextra -Werror
|
||||
|
||||
clean:
|
||||
rm -f defork32.so defork64.so forking_target
|
11
examples/defork/README.md
Normal file
11
examples/defork/README.md
Normal file
@ -0,0 +1,11 @@
|
||||
# defork
|
||||
|
||||
when the target forks, this breaks all normal fuzzing runs.
|
||||
Sometimes, though, it is enough to just run the child process.
|
||||
If this is the case, then this LD_PRELOAD library will always return 0 on fork,
|
||||
the target will belive it is running as the child, post-fork.
|
||||
|
||||
This is defork.c from the amazing preeny project
|
||||
https://github.com/zardus/preeny
|
||||
|
||||
It is altered for afl++ to work with its fork-server: the initial fork will go through, the second fork will be blocked.
|
52
examples/defork/defork.c
Normal file
52
examples/defork/defork.c
Normal file
@ -0,0 +1,52 @@
|
||||
#define __GNU_SOURCE
|
||||
#include <dlfcn.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "../../include/config.h"
|
||||
|
||||
/* we want to fork once (for the afl++ forkserver),
|
||||
then immediately return as child on subsequent forks. */
|
||||
static bool forked = 0;
|
||||
|
||||
pid_t (*original_fork)(void);
|
||||
|
||||
/* In case we are not running in afl, we use a dummy original_fork */
|
||||
static pid_t nop(void) {
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
__attribute__((constructor)) void preeny_fork_orig() {
|
||||
|
||||
if (getenv(SHM_ENV_VAR)) {
|
||||
|
||||
printf("defork: running in AFL++. Allowing forkserver.\n");
|
||||
original_fork = dlsym(RTLD_NEXT, "socket");
|
||||
|
||||
} else {
|
||||
|
||||
printf("defork: no AFL++ detected. Disabling fork from the start.\n");
|
||||
original_fork = &nop;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pid_t fork(void) {
|
||||
|
||||
printf("called fork. forked state is %d\n", (int) forked);
|
||||
fflush(stdout);
|
||||
/* If we forked before, or if we're in the child (pid==0),
|
||||
we don't want to fork anymore, else, we are still in the forkserver.
|
||||
The forkserver parent needs to fork infinite times, each child should never
|
||||
fork again. This can be written without branches and I hate myself for it.
|
||||
*/
|
||||
pid_t ret = !forked && original_fork();
|
||||
forked = !ret;
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
BIN
examples/defork/forking_target
Executable file
BIN
examples/defork/forking_target
Executable file
Binary file not shown.
46
examples/defork/forking_target.c
Normal file
46
examples/defork/forking_target.c
Normal file
@ -0,0 +1,46 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/* This is an example target for defork.c - fuzz using
|
||||
```
|
||||
mkdir in; echo a > ./in/a
|
||||
AFL_PRELOAD=./defork64.so ../../afl-fuzz -i in -o out -- ./forking_target @@
|
||||
```
|
||||
*/
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
if (argc < 2) {
|
||||
|
||||
printf("Example tool to test defork.\nUsage ./forking_target <input>\n");
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
pid_t pid = fork();
|
||||
if (pid == 0) {
|
||||
|
||||
printf("We're in the child.\n");
|
||||
FILE *f = fopen(argv[1], "r");
|
||||
char buf[4096];
|
||||
fread(buf, 1, 4096, f);
|
||||
uint32_t offset = buf[100] + (buf[101] << 8);
|
||||
char test_val = buf[offset];
|
||||
return test_val < 100;
|
||||
|
||||
} else if (pid < 0) {
|
||||
|
||||
perror("fork");
|
||||
return -1;
|
||||
|
||||
} else {
|
||||
|
||||
printf("We are in the parent - defork didn't work! :( (pid=%d)\n", (int) pid);
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
Reference in New Issue
Block a user