diff options
-rw-r--r-- | .travis.yml | 8 | ||||
-rw-r--r-- | Dockerfile | 27 | ||||
-rw-r--r-- | README.md | 8 | ||||
-rwxr-xr-x | afl-wine-trace | 26 | ||||
-rw-r--r-- | dictionaries/regexp.dict | 244 | ||||
-rw-r--r-- | docs/ChangeLog | 4 | ||||
-rw-r--r-- | docs/QuickStartGuide.txt | 2 | ||||
-rw-r--r-- | include/afl-fuzz.h | 3 | ||||
-rw-r--r-- | libtokencap/libtokencap.so.c | 8 | ||||
-rwxr-xr-x | qemu_mode/build_qemu_support.sh | 5 | ||||
-rw-r--r-- | src/afl-fuzz-globals.c | 3 | ||||
-rw-r--r-- | src/afl-fuzz-one.c | 2 | ||||
-rw-r--r-- | src/afl-fuzz.c | 3 | ||||
-rwxr-xr-x | test/test.sh | 165 | ||||
-rwxr-xr-x | unicorn_mode/build_unicorn_support.sh | 6 | ||||
-rw-r--r-- | unicorn_mode/patches/afl-unicorn-tcg-runtime-inl.h | 74 | ||||
-rw-r--r-- | unicorn_mode/samples/compcov_x64/compcov_target.bin | bin | 86 -> 86 bytes | |||
-rw-r--r-- | unicorn_mode/samples/compcov_x64/compcov_target.c | 6 | ||||
-rwxr-xr-x | unicorn_mode/samples/compcov_x64/compcov_target.elf | bin | 5728 -> 13200 bytes |
19 files changed, 537 insertions, 57 deletions
diff --git a/.travis.yml b/.travis.yml index 87b3ef04..4569bd9c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,18 +3,16 @@ language: c env: - AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 AFL_NO_UI=1 AFL_STOP_MANUALLY=1 - - AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 AFL_NO_UI=1 AFL_EXIT_WHEN_DONE=1 + # - AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 AFL_NO_UI=1 AFL_EXIT_WHEN_DONE=1 # TODO: test AFL_BENCH_UNTIL_CRASH once we have a target that crashes - - AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 AFL_NO_UI=1 AFL_BENCH_JUST_ONE=1 + # - AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 AFL_NO_UI=1 AFL_BENCH_JUST_ONE=1 before_install: - sudo apt update - - sudo apt install -y libtool libtool-bin automake bison libglib2.0 build-essential clang gcc-8 gcc-8-plugin-dev libc++-8-dev -# libc++-7-dev + - sudo apt install -y libtool libtool-bin automake bison libglib2.0 build-essential clang gcc-7 gcc-7-plugin-dev libc++-7-dev script: - gcc -v - clang -v - make distrib - make tests - - make clean diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..558968d8 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,27 @@ +FROM ubuntu:eoan +MAINTAINER David Carlier <devnexen@gmail.com> +LABEL "about"="AFLplusplus docker image" +RUN apt-get update && apt-get install -y --no-install-recommends \ + automake \ + bison \ + build-essential \ + clang \ + clang-9 \ + flex \ + gcc-9 \ + gcc-9-plugin-dev \ + libc++-9-dev \ + libtool \ + libtool-bin \ + libglib2.0-dev \ + llvm-9-tools \ + python-setuptools \ + wget \ + && rm -fr /var/lib/apt/lists/* +RUN mkdir /app +WORKDIR ["/app"] +COPY . . +ENV CC=gcc-9 +ENV CXX=g++-9 +ENV LLVM_CONFIG=llvm-config-9 +RUN make clean && make distrib && make install diff --git a/README.md b/README.md index e8d4e6a8..583b7df8 100644 --- a/README.md +++ b/README.md @@ -115,6 +115,14 @@ afl++ binaries by passing the STATIC=1 argument to make: $ make all STATIC=1 ``` +Note that afl++ is faster and better the newer the compilers used. +Hence gcc-9 and especially llvm-9 should be the compilers of choice. +If your distribution does not have them, you can use the Dockerfile: + +```shell +$ docker build -t aflplusplus +``` + ## 1) Challenges of guided fuzzing diff --git a/afl-wine-trace b/afl-wine-trace index f8284d7e..65525a33 100755 --- a/afl-wine-trace +++ b/afl-wine-trace @@ -4,9 +4,10 @@ import os import sys import pefile import shutil +import subprocess if len(sys.argv) < 2: - print("[afl-wine-trace] usage: wine-cov binary [args...]\n") + print("[afl-wine-trace] usage: ./afl-wine-trace binary [args...]\n") exit(1) if os.getenv("AFL_PATH"): @@ -42,14 +43,20 @@ else: elif pe.FILE_HEADER.Machine == pefile.MACHINE_TYPE["IMAGE_FILE_MACHINE_I386"]: qemu_path += "i386" else: - print ("[wine-cov] unsuppoted architecture\n") + print ("[afl-wine-trace] unsuppoted architecture\n") exit(1) qemu_path = shutil.which(qemu_path) -if os.getenv("WINECOV_WINE_PATH"): - wine_path = os.getenv("WINECOV_WINE_PATH") +wine_path = None +if os.getenv("AFL_WINE_PATH"): + wine_path = os.getenv("AFL_WINE_PATH") else: - wine_path = "/usr/lib/wine/wine" + if not wine_path and shutil.which("wine"): + wine_path = shutil.which("wine") + if not wine_path and os.path.exists("/usr/bin/wine"): + wine_path = "/usr/bin/wine" + if not wine_path and os.path.exists("/usr/lib/wine/wine"): + wine_path = "/usr/lib/wine/wine" if pe.FILE_HEADER.Machine == pefile.MACHINE_TYPE["IMAGE_FILE_MACHINE_AMD64"] or pe.FILE_HEADER.Machine == pefile.MACHINE_TYPE["IMAGE_FILE_MACHINE_IA64"]: wine_path += "64" elif pe.FILE_HEADER.Machine == pefile.MACHINE_TYPE["IMAGE_FILE_MACHINE_I386"]: @@ -58,4 +65,11 @@ else: print ("[afl-wine-trace] unsopported architecture\n") exit(1) -os.execve(qemu_path, [qemu_path, wine_path] + sys.argv[1:], os.environ) +argv = sys.argv[1:] +for i in range(len(argv)): + if ".cur_input" in argv[i]: + argv[i] = subprocess.run([os.path.join(os.path.dirname(wine_path), "winepath"), "--windows", argv[i]], universal_newlines=True, stdout=subprocess.PIPE).stdout + break + +print("[afl-wine-trace] exec:", " ".join([qemu_path, wine_path] + argv)) +os.execve(qemu_path, [qemu_path, wine_path] + argv, os.environ) diff --git a/dictionaries/regexp.dict b/dictionaries/regexp.dict new file mode 100644 index 00000000..957d18e2 --- /dev/null +++ b/dictionaries/regexp.dict @@ -0,0 +1,244 @@ +# +# AFL dictionary for JS regex +# --------------------------- +# +# Contains various regular expressions. +# +# Created by Yang Guo <yangguo@chromium.org> +# +# Contributed by Dhiraj Mishra <dhiraj@inputzero.io> +# +"?" +"abc" +"()" +"[]" +"abc|def" +"abc|def|ghi" +"^xxx$" +"ab\\b\\d\\bcd" +"\\w|\\d" +"a*?" +"abc+" +"abc+?" +"xyz?" +"xyz??" +"xyz{0,1}" +"xyz{0,1}?" +"xyz{93}" +"xyz{1,32}" +"xyz{1,32}?" +"xyz{1,}" +"xyz{1,}?" +"a\\fb\\nc\\rd\\te\\vf" +"a\\nb\\bc" +"/^\d*\./" +"(?:foo)" +"(?: foo )" +"foo|(bar|baz)|quux" +"foo(?=bar)baz" +"foo(?!bar)baz" +"foo(?<=bar)baz" +"foo(?<!bar)baz" +"()" +"(?=)" +"[]" +"[x]" +"[xyz]" +"[a-zA-Z0-9]" +"[-123]" +"[^123]" +"]" +"}" +"[a-b-c]" +"[x\\dz]" +"[\\d-z]" +"[\\d-\\d]" +"[z-\\d]" +"\\cj\\cJ\\ci\\cI\\ck\\cK" +"\\c!" +"\\c_" +"\\c~" +"[\\c!]" +"[\\c_]" +"[\\c~]" +"[\\ca]" +"[\\cz]" +"[\\cA]" +"[\\cZ]" +"[\\c1]" +"\\[\\]\\{\\}\\(\\)\\%\\^\\#\\ " +"[\\[\\]\\{\\}\\(\\)\\%\\^\\#\\ ]" +"\\8" +"\\9" +"\\11" +"\\11a" +"\\011" +"\\118" +"\\111" +"\\1111" +"(x)(x)(x)\\1" +"(x)(x)(x)\\2" +"(x)(x)(x)\\3" +"(x)(x)(x)\\4" +"(x)(x)(x)\\1*" +"(x)(x)(x)\\3*" +"(x)(x)(x)\\4*" +"(x)(x)(x)(x)(x)(x)(x)(x)(x)(x)\\10" +"(x)(x)(x)(x)(x)(x)(x)(x)(x)(x)\\11" +"(a)\\1" +"(a\\1)" +"(\\1a)" +"(\\2)(\\1)" +"(?=a){0,10}a" +"(?=a){1,10}a" +"(?=a){9,10}a" +"(?!a)?a" +"\\1(a)" +"(?!(a))\\1" +"(?!\\1(a\\1)\\1)\\1" +"\\1\\2(a(?:\\1(b\\1\\2))\\2)\\1" +"[\\0]" +"[\\11]" +"[\\11a]" +"[\\011]" +"[\\00011]" +"[\\118]" +"[\\111]" +"[\\1111]" +"\\x60" +"\\x3z" +"\\c" +"\\u0034" +"\\u003z" +"foo[z]*" +"\\u{12345}" +"\\u{12345}\\u{23456}" +"\\u{12345}{3}" +"\\u{12345}*" +"\\ud808\\udf45*" +"[\\ud808\\udf45-\\ud809\\udccc]" +"a" +"a|b" +"a\\n" +"a$" +"a\\b!" +"a\\Bb" +"a*?" +"a?" +"a??" +"a{0,1}?" +"a{1,2}?" +"a+?" +"(a)" +"(a)\\1" +"(\\1a)" +"\\1(a)" +"a\\s" +"a\\S" +"a\\D" +"a\\w" +"a\\W" +"a." +"a\\q" +"a[a]" +"a[^a]" +"a[a-z]" +"a(?:b)" +"a(?=b)" +"a(?!b)" +"\\x60" +"\\u0060" +"\\cA" +"\\q" +"\\1112" +"(a)\\1" +"(?!a)?a\\1" +"(?:(?=a))a\\1" +"a{}" +"a{,}" +"a{" +"a{z}" +"a{12z}" +"a{12," +"a{12,3b" +"{}" +"{,}" +"{" +"{z}" +"{1z}" +"{12," +"{12,3b" +"a" +"abc" +"a[bc]d" +"a|bc" +"ab|c" +"a||bc" +"(?:ab)" +"(?:ab|cde)" +"(?:ab)|cde" +"(ab)" +"(ab|cde)" +"(ab)\\1" +"(ab|cde)\\1" +"(?:ab)?" +"(?:ab)+" +"a?" +"a+" +"a??" +"a*?" +"a+?" +"(?:a?)?" +"(?:a+)?" +"(?:a?)+" +"(?:a*)+" +"(?:a+)+" +"(?:a?)*" +"(?:a*)*" +"(?:a+)*" +"a{0}" +"(?:a+){0,0}" +"a*b" +"a+b" +"a*b|c" +"a+b|c" +"(?:a{5,1000000}){3,1000000}" +"(?:ab){4,7}" +"a\\bc" +"a\\sc" +"a\\Sc" +"a(?=b)c" +"a(?=bbb|bb)c" +"a(?!bbb|bb)c" +"\xe2\x81\xa3" +"[\xe2\x81\xa3]" +"\xed\xb0\x80" +"\xed\xa0\x80" +"(\xed\xb0\x80)\x01" +"((\xed\xa0\x80))\x02" +"\xf0\x9f\x92\xa9" +"\x01" +"\x0f" +"[-\xf0\x9f\x92\xa9]+" +"[\xf0\x9f\x92\xa9-\xf4\x8f\xbf\xbf]" +"\[DataMember\((.+?)\)\]" +"/\d{1,2}\/\d{1,2}\/\d{4}/" +"a*b\+\|[0-9]\|\d{1,9}" +"(?<=)" +"(?<=a)" +"(?<!)" +"(?<!a)" +"(?<a>)" +"(?<a>.)" +"(?<a>.)\\k<a>" +"\\p{Script=Greek}" +"\\P{sc=Greek}" +"\\p{Script_Extensions=Greek}" +"\\P{scx=Greek}" +"\\p{General_Category=Decimal_Number}" +"\\P{gc=Decimal_Number}" +"\\p{gc=Nd}" +"\\P{Decimal_Number}" +"\\p{Nd}" +"\\P{Any}" +"\\p{Changes_When_NFKC_Casefolded}" diff --git a/docs/ChangeLog b/docs/ChangeLog index 4c51502b..7bc6dec4 100644 --- a/docs/ChangeLog +++ b/docs/ChangeLog @@ -23,6 +23,10 @@ Version ++2.58d (dev): - llvm_mode: float splitting is now configured via AFL_LLVM_LAF_SPLIT_FLOATS - libtokencap: support for *BSD/OSX added - libcompcov floating point splitting support for qemu and unicorn + - Dockerfile by courtesy of devnexen + - ripped regex.dictionary from Google afl PR + - qemu and unicorn download scripts now try to download until the full + download succeeded. f*ckin travis fails downloading 40% of the time! - removed unnecessary warnings diff --git a/docs/QuickStartGuide.txt b/docs/QuickStartGuide.txt index 9190dc98..723611e3 100644 --- a/docs/QuickStartGuide.txt +++ b/docs/QuickStartGuide.txt @@ -45,6 +45,8 @@ how to hit the ground running: 7) compile and use llvm_mode (afl-clang-fast/afl-clang-fast++) as it is way faster and has a few cool features +8) There is a basic docker build with 'docker build -t aflplusplus .' + That's it. Sit back, relax, and - time permitting - try to skim through the following files: diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 637c2795..90f3b419 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -315,7 +315,8 @@ extern u8 skip_deterministic, /* Skip deterministic stages? */ deferred_mode, /* Deferred forkserver mode? */ fixed_seed, /* do not reseed */ fast_cal, /* Try to calibrate faster? */ - uses_asan; /* Target uses ASAN? */ + uses_asan, /* Target uses ASAN? */ + disable_trim; /* Never trim in fuzz_one */ extern s32 out_fd, /* Persistent fd for out_file */ #ifndef HAVE_ARC4RANDOM diff --git a/libtokencap/libtokencap.so.c b/libtokencap/libtokencap.so.c index 7495180d..467be05b 100644 --- a/libtokencap/libtokencap.so.c +++ b/libtokencap/libtokencap.so.c @@ -51,6 +51,7 @@ static struct mapping { void *st, *en; } __tokencap_ro[MAX_MAPPINGS]; static u32 __tokencap_ro_cnt; static u8 __tokencap_ro_loaded; static int __tokencap_out_file = -1; +static pid_t __tokencap_pid = -1; /* Identify read-only regions in memory. Only parameters that fall into these ranges are worth dumping when passed to strcmp() and so on. Read-write @@ -115,11 +116,11 @@ static void __tokencap_load_mappings(void) { #elif defined __FreeBSD__ || defined __OpenBSD__ || defined __NetBSD__ #if defined __FreeBSD__ - int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_VMMAP, -1}; + int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_VMMAP, __tokencap_pid}; #elif defined __OpenBSD__ - int mib[] = {CTL_KERN, KERN_PROC_VMMAP, getpid()}; + int mib[] = {CTL_KERN, KERN_PROC_VMMAP, __tokencap_pid}; #elif defined __NetBSD__ - int mib[] = {CTL_VM, VM_PROC, VM_PROC_MAP, getpid(), sizeof(struct kinfo_vmentry)}; + int mib[] = {CTL_VM, VM_PROC, VM_PROC_MAP, __tokencap_pid, sizeof(struct kinfo_vmentry)}; #endif char *buf, *low, *high; size_t miblen = sizeof(mib)/sizeof(mib[0]); @@ -431,6 +432,7 @@ __attribute__((constructor)) void __tokencap_init(void) { u8* fn = getenv("AFL_TOKEN_FILE"); if (fn) __tokencap_out_file = open(fn, O_RDWR | O_CREAT | O_APPEND, 0655); if (__tokencap_out_file == -1) __tokencap_out_file = STDERR_FILENO; + __tokencap_pid = getpid(); } diff --git a/qemu_mode/build_qemu_support.sh b/qemu_mode/build_qemu_support.sh index 6b9f91f9..c3983aa1 100755 --- a/qemu_mode/build_qemu_support.sh +++ b/qemu_mode/build_qemu_support.sh @@ -100,7 +100,10 @@ if [ ! "$CKSUM" = "$QEMU_SHA384" ]; then echo "[*] Downloading QEMU ${VERSION} from the web..." rm -f "$ARCHIVE" - wget -O "$ARCHIVE" -- "$QEMU_URL" || exit 1 + OK= + while [ -z "$OK" ]; do + wget -c -O "$ARCHIVE" -- "$QEMU_URL" && OK=1 + done CKSUM=`sha384sum -- "$ARCHIVE" 2>/dev/null | cut -d' ' -f1` diff --git a/src/afl-fuzz-globals.c b/src/afl-fuzz-globals.c index 36ba6e14..06eb06d8 100644 --- a/src/afl-fuzz-globals.c +++ b/src/afl-fuzz-globals.c @@ -122,7 +122,8 @@ u8 skip_deterministic, /* Skip deterministic stages? */ deferred_mode, /* Deferred forkserver mode? */ fixed_seed, /* do not reseed */ fast_cal, /* Try to calibrate faster? */ - uses_asan; /* Target uses ASAN? */ + uses_asan, /* Target uses ASAN? */ + disable_trim; /* Never trim in fuzz_one */ s32 out_fd, /* Persistent fd for out_file */ #ifndef HAVE_ARC4RANDOM diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index bed8d254..8ca219b5 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -449,7 +449,7 @@ u8 fuzz_one_original(char** argv) { * TRIMMING * ************/ - if (!dumb_mode && !queue_cur->trim_done && !custom_mutator) { + if (!dumb_mode && !queue_cur->trim_done && !custom_mutator && !disable_trim) { u8 res = trim_case(argv, queue_cur, in_buf); diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 14d7802d..26ed7b61 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -551,6 +551,9 @@ int main(int argc, char** argv) { } + if (getenv("AFL_DISABLE_TRIM")) + disable_trim = 1; + if (getenv("AFL_NO_UI") && getenv("AFL_FORCE_UI")) FATAL("AFL_NO_UI and AFL_FORCE_UI are mutually exclusive"); diff --git a/test/test.sh b/test/test.sh index 2d5c5e39..617401eb 100755 --- a/test/test.sh +++ b/test/test.sh @@ -24,6 +24,8 @@ $ECHO \\101 2>&1 | grep -qE '^A' || { } test -z "$ECHO" && { printf Error: printf command does not support octal character codes ; exit 1 ; } +CODE=0 + export AFL_EXIT_WHEN_DONE=1 export AFL_SKIP_CPUFREQ=1 export AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 @@ -75,16 +77,26 @@ test -e ../${AFL_GCC} -a -e ../afl-showmap -a -e ../afl-fuzz && { test -e test-instr.plain.0 -a -e test-instr.plain.1 && { diff -q test-instr.plain.0 test-instr.plain.1 > /dev/null 2>&1 && { $ECHO "$RED[!] ${AFL_GCC} instrumentation should be different on different input but is not" + CODE=1 } || $ECHO "$GREEN[+] ${AFL_GCC} instrumentation present and working correctly" - } || $ECHO "$RED[!] ${AFL_GCC} instrumentation failed" + } || { + $ECHO "$RED[!] ${AFL_GCC} instrumentation failed" + CODE=1 + } rm -f test-instr.plain.0 test-instr.plain.1 } || $ECHO "$RED[!] ${AFL_GCC} failed" test -e test-compcov.harden && { grep -Eqa 'stack_chk_fail|fstack-protector-all|fortified' test-compcov.harden > /dev/null 2>&1 && { $ECHO "$GREEN[+] ${AFL_GCC} hardened mode succeeded and is working" - } || $ECHO "$RED[!] ${AFL_GCC} hardened mode is not hardened" + } || { + $ECHO "$RED[!] ${AFL_GCC} hardened mode is not hardened" + CODE=1 + } rm -f test-compcov.harden - } || $ECHO "$RED[!] ${AFL_GCC} hardened mode compilation failed" + } || { + $ECHO "$RED[!] ${AFL_GCC} hardened mode compilation failed" + CODE=1 + } # now we want to be sure that afl-fuzz is working # make sure core_pattern is set to core on linux (test "$(uname -s)" = "Linux" && test "$(sysctl kernel.core_pattern)" != "kernel.core_pattern = core" && { @@ -109,6 +121,7 @@ test -e ../${AFL_GCC} -a -e ../afl-showmap -a -e ../afl-fuzz && { cat errors echo CUT------------------------------------------------------------------CUT $ECHO "$RED[!] afl-fuzz is not working correctly with ${AFL_GCC}" + CODE=1 } rm -rf in out errors } @@ -132,16 +145,29 @@ test -e ../afl-clang-fast && { test -e test-instr.plain.0 -a -e test-instr.plain.1 && { diff -q test-instr.plain.0 test-instr.plain.1 > /dev/null 2>&1 && { $ECHO "$RED[!] llvm_mode instrumentation should be different on different input but is not" + CODE=1 } || $ECHO "$GREEN[+] llvm_mode instrumentation present and working correctly" - } || $ECHO "$RED[!] llvm_mode instrumentation failed" + } || { + $ECHO "$RED[!] llvm_mode instrumentation failed" + CODE=1 + } rm -f test-instr.plain.0 test-instr.plain.1 - } || $ECHO "$RED[!] llvm_mode failed" + } || { + $ECHO "$RED[!] llvm_mode failed" + CODE=1 + } test -e test-compcov.harden && { grep -Eqa 'stack_chk_fail|fstack-protector-all|fortified' test-compcov.harden > /dev/null 2>&1 && { $ECHO "$GREEN[+] llvm_mode hardened mode succeeded and is working" - } || $ECHO "$RED[!] llvm_mode hardened mode is not hardened" + } || { + $ECHO "$RED[!] llvm_mode hardened mode is not hardened" + CODE=1 + } rm -f test-compcov.harden - } || $ECHO "$RED[!] llvm_mode hardened mode compilation failed" + } || { + $ECHO "$RED[!] llvm_mode hardened mode compilation failed" + CODE=1 + } # now we want to be sure that afl-fuzz is working (test "$(uname -s)" = "Linux" && test "$(sysctl kernel.core_pattern)" != "kernel.core_pattern = core" && { $ECHO "$YELLOW[!] we should not run afl-fuzz with enabled core dumps. Run 'sudo sh afl-system-config'.$RESET" @@ -150,6 +176,7 @@ test -e ../afl-clang-fast && { # make sure crash reporter is disabled on Mac OS X (test "$(uname -s)" = "Darwin" && test $(launchctl list 2>/dev/null | grep -q '\.ReportCrash$') && { $ECHO "$RED[!] we cannot run afl-fuzz with enabled crash reporter. Run 'sudo sh afl-system-config'.$RESET" + CODE=1 true }) || { mkdir -p in @@ -165,6 +192,7 @@ test -e ../afl-clang-fast && { cat errors echo CUT------------------------------------------------------------------CUT $ECHO "$RED[!] afl-fuzz is not working correctly with llvm_mode" + CODE=1 } rm -rf in out errors } @@ -175,30 +203,54 @@ test -e ../afl-clang-fast && { test -e test-compcov.instrim && { grep -Eq " [1-3] location" test.out && { $ECHO "$GREEN[+] llvm_mode InsTrim feature works correctly" - } || $ECHO "$RED[!] llvm_mode InsTrim feature failed" - } || $ECHO "$RED[!] llvm_mode InsTrim feature compilation failed" + } || { + $ECHO "$RED[!] llvm_mode InsTrim feature failed" + CODE=1 + } + } || { + $ECHO "$RED[!] llvm_mode InsTrim feature compilation failed" + CODE=1 + } rm -f test-compcov.instrim test.out AFL_LLVM_LAF_SPLIT_SWITCHES=1 AFL_LLVM_LAF_TRANSFORM_COMPARES=1 AFL_LLVM_LAF_SPLIT_COMPARES=1 ../afl-clang-fast -o test-compcov.compcov test-compcov.c > /dev/null 2> test.out test -e test-compcov.compcov && { grep -Eq " [3-9][0-9] location" test.out && { $ECHO "$GREEN[+] llvm_mode laf-intel/compcov feature works correctly" - } || $ECHO "$RED[!] llvm_mode laf-intel/compcov feature failed" - } || $ECHO "$RED[!] llvm_mode laf-intel/compcov feature compilation failed" + } || { + $ECHO "$RED[!] llvm_mode laf-intel/compcov feature failed" + CODE=1 + } + } || { + $ECHO "$RED[!] llvm_mode laf-intel/compcov feature compilation failed" + CODE=1 + } rm -f test-compcov.compcov test.out echo foobar.c > whitelist.txt AFL_LLVM_WHITELIST=whitelist.txt ../afl-clang-fast -o test-compcov test-compcov.c > test.out 2>&1 test -e test-compcov && { grep -q "No instrumentation targets found" test.out && { $ECHO "$GREEN[+] llvm_mode whitelist feature works correctly" - } || $ECHO "$RED[!] llvm_mode whitelist feature failed" - } || $ECHO "$RED[!] llvm_mode whitelist feature compilation failed" + } || { + $ECHO "$RED[!] llvm_mode whitelist feature failed" + CODE=1 + } + } || { + $ECHO "$RED[!] llvm_mode whitelist feature compilation failed" + CODE=1 + } rm -f test-compcov test.out whitelist.txt ../afl-clang-fast -o test-persistent ../experimental/persistent_demo/persistent_demo.c > /dev/null 2>&1 test -e test-persistent && { echo foo | ../afl-showmap -o /dev/null -q -r ./test-persistent && { $ECHO "$GREEN[+] llvm_mode persistent mode feature works correctly" - } || $ECHO "$RED[!] llvm_mode persistent mode feature failed to work" - } || $ECHO "$RED[!] llvm_mode persistent mode feature compilation failed" + } || { + $ECHO "$RED[!] llvm_mode persistent mode feature failed to work" + CODE=1 + } + } || { + $ECHO "$RED[!] llvm_mode persistent mode feature compilation failed" + CODE=1 + } rm -f test-persistent } || $ECHO "$YELLOW[-] llvm_mode not compiled, cannot test" @@ -214,17 +266,32 @@ test -e ../afl-gcc-fast && { test -e test-instr.plain.0 -a -e test-instr.plain.1 && { diff -q test-instr.plain.0 test-instr.plain.1 > /dev/null 2>&1 && { $ECHO "$RED[!] gcc_plugin instrumentation should be different on different input but is not" - } || $ECHO "$GREEN[+] gcc_plugin instrumentation present and working correctly" - } || $ECHO "$RED[!] gcc_plugin instrumentation failed" + CODE=1 + } || { + $ECHO "$GREEN[+] gcc_plugin instrumentation present and working correctly" + } + } || { + $ECHO "$RED[!] gcc_plugin instrumentation failed" + CODE=1 + } rm -f test-instr.plain.0 test-instr.plain.1 - } || $ECHO "$RED[!] gcc_plugin failed" + } || { + $ECHO "$RED[!] gcc_plugin failed" + CODE=1 + } test -e test-compcov.harden.gccpi && { grep -Eqa 'stack_chk_fail|fstack-protector-all|fortified' test-compcov.harden.gccpi > /dev/null 2>&1 && { $ECHO "$GREEN[+] gcc_plugin hardened mode succeeded and is working" - } || $ECHO "$RED[!] gcc_plugin hardened mode is not hardened" + } || { + $ECHO "$RED[!] gcc_plugin hardened mode is not hardened" + CODE=1 + } rm -f test-compcov.harden.gccpi - } || $ECHO "$RED[!] gcc_plugin hardened mode compilation failed" + } || { + $ECHO "$RED[!] gcc_plugin hardened mode compilation failed" + CODE=1 + } # now we want to be sure that afl-fuzz is working (test "$(uname -s)" = "Linux" && test "$(sysctl kernel.core_pattern)" != "kernel.core_pattern = core" && { $ECHO "$YELLOW[!] we should not run afl-fuzz with enabled core dumps. Run 'sudo sh afl-system-config'.$RESET" @@ -233,6 +300,7 @@ test -e ../afl-gcc-fast && { # make sure crash reporter is disabled on Mac OS X (test "$(uname -s)" = "Darwin" && test $(launchctl list 2>/dev/null | grep -q '\.ReportCrash$') && { $ECHO "$RED[!] we cannot run afl-fuzz with enabled crash reporter. Run 'sudo sh afl-system-config'.$RESET" + CODE=1 true }) || { mkdir -p in @@ -248,6 +316,7 @@ test -e ../afl-gcc-fast && { cat errors echo CUT------------------------------------------------------------------CUT $ECHO "$RED[!] afl-fuzz is not working correctly with gcc_plugin" + CODE=1 } rm -rf in out errors } @@ -259,15 +328,27 @@ test -e ../afl-gcc-fast && { test -e test-compcov && { echo 1 | ../afl-showmap -m ${MEM_LIMIT} -o - -r -- ./test-compcov 2>&1 | grep -q "Captured 1 tuples" && { $ECHO "$GREEN[+] gcc_plugin whitelist feature works correctly" - } || $ECHO "$RED[!] gcc_plugin whitelist feature failed" - } || $ECHO "$RED[!] gcc_plugin whitelist feature compilation failed" + } || { + $ECHO "$RED[!] gcc_plugin whitelist feature failed" + CODE=1 + } + } || { + $ECHO "$RED[!] gcc_plugin whitelist feature compilation failed" + CODE=1 + } rm -f test-compcov test.out whitelist.txt ../afl-gcc-fast -o test-persistent ../experimental/persistent_demo/persistent_demo.c > /dev/null 2>&1 test -e test-persistent && { echo foo | ../afl-showmap -o /dev/null -q -r ./test-persistent && { $ECHO "$GREEN[+] gcc_plugin persistent mode feature works correctly" - } || $ECHO "$RED[!] gcc_plugin persistent mode feature failed to work" - } || $ECHO "$RED[!] gcc_plugin persistent mode feature compilation failed" + } || { + $ECHO "$RED[!] gcc_plugin persistent mode feature failed to work" + CODE=1 + } + } || { + $ECHO "$RED[!] gcc_plugin persistent mode feature compilation failed" + CODE=1 + } rm -f test-persistent } || $ECHO "$YELLOW[-] gcc_plugin not compiled, cannot test" @@ -277,7 +358,10 @@ test -e ../libtokencap.so && { AFL_TOKEN_FILE=token.out LD_PRELOAD=../libtokencap.so DYLD_INSERT_LIBRARIES=../libtokencap.so DYLD_FORCE_FLAT_NAMESPACE=1 ./test-compcov foobar > /dev/null 2>&1 grep -q BUGMENOT token.out > /dev/null 2>&1 && { $ECHO "$GREEN[+] libtokencap did successfully capture tokens" - } || $ECHO "$RED[!] libtokencap did not capture tokens" + } || { + $ECHO "$RED[!] libtokencap did not capture tokens" + CODE=1 + } rm -f token.out } || $ECHO "$YELLOW[-] libtokencap is not compiled, cannot test" test -e ../libdislocator.so && { @@ -288,6 +372,7 @@ test -e ../libdislocator.so && { } > /dev/null 2>&1 grep -q BUFFEROVERFLOW test.out > /dev/null 2>&1 && { $ECHO "$RED[!] libdislocator did not detect the memory corruption" + CODE=1 } || $ECHO "$GREEN[+] libdislocator did successfully detect the memory corruption" rm -f test.out core test-compcov.core core.test-compcov } || $ECHO "$YELLOW[-] libdislocator is not compiled, cannot test" @@ -313,6 +398,7 @@ test -e ../afl-qemu-trace && { cat errors echo CUT------------------------------------------------------------------CUT $ECHO "$RED[!] afl-fuzz is not working correctly with qemu_mode" + CODE=1 } rm -f errors @@ -330,6 +416,7 @@ test -e ../afl-qemu-trace && { cat errors echo CUT------------------------------------------------------------------CUT $ECHO "$RED[!] afl-fuzz is not working correctly with qemu_mode libcompcov" + CODE=1 } } || $ECHO "$YELLOW[-] we cannot test qemu_mode libcompcov because it is not present" rm -f errors @@ -359,12 +446,16 @@ test -e ../afl-qemu-trace && { cat errors echo CUT------------------------------------------------------------------CUT $ECHO "$RED[!] afl-fuzz is not working correctly with persistent qemu_mode" + CODE=1 exit 1 } $ECHO "$YELLOW[?] we need a test case for qemu_mode unsigaction library" rm -rf in out errors } - } || $ECHO "$RED[-] gcc compilation of test targets failed - what is going on??" + } || { + $ECHO "$RED[-] gcc compilation of test targets failed - what is going on??" + CODE=1 + } rm -f test-instr test-compcov } || $ECHO "$YELLOW[-] qemu_mode is not compiled, cannot test" @@ -379,9 +470,9 @@ test -d ../unicorn_mode/unicorn && { mkdir -p in echo 0 > in/in $ECHO "$GREY[*] Using python binary $PY" - $ECHO "$GREY[*] running afl-fuzz for unicorn_mode, this will take approx 20 seconds" + $ECHO "$GREY[*] running afl-fuzz for unicorn_mode, this will take approx 25 seconds" { - ../afl-fuzz -V20 -U -i in -o out -d -- "$PY" ../unicorn_mode/samples/simple/simple_test_harness.py @@ >>errors 2>&1 + ../afl-fuzz -V25 -U -i in -o out -d -- "$PY" ../unicorn_mode/samples/simple/simple_test_harness.py @@ >>errors 2>&1 } >>errors 2>&1 test -n "$( ls out/queue/id:000002* 2> /dev/null )" && { $ECHO "$GREEN[+] afl-fuzz is working correctly with unicorn_mode" @@ -390,13 +481,17 @@ test -d ../unicorn_mode/unicorn && { cat errors echo CUT------------------------------------------------------------------CUT $ECHO "$RED[!] afl-fuzz is not working correctly with unicorn_mode" + CODE=1 } rm -f errors - $ECHO "$GREY[*] running afl-fuzz for unicorn_mode compcov, this will take approx 25 seconds" + printf '\x01\x01' > in/in + # This seed is close to the first byte of the comparison. + # If CompCov works, a new tuple will appear in the map => new input in queue + $ECHO "$GREY[*] running afl-fuzz for unicorn_mode compcov, this will take approx 35 seconds" { export AFL_COMPCOV_LEVEL=2 - ../afl-fuzz -V25 -U -i in -o out -d -- "$PY" ../unicorn_mode/samples/compcov_x64/compcov_test_harness.py @@ >>errors 2>&1 + ../afl-fuzz -V35 -U -i in -o out -d -- "$PY" ../unicorn_mode/samples/compcov_x64/compcov_test_harness.py @@ >>errors 2>&1 } >>errors 2>&1 test -n "$( ls out/queue/id:000001* 2> /dev/null )" && { $ECHO "$GREEN[+] afl-fuzz is working correctly with unicorn_mode compcov" @@ -405,12 +500,18 @@ test -d ../unicorn_mode/unicorn && { cat errors echo CUT------------------------------------------------------------------CUT $ECHO "$RED[!] afl-fuzz is not working correctly with unicorn_mode compcov" + CODE=1 } rm -rf in out errors } - } || $ECHO "$RED[-] missing sample binaries in unicorn_mode/samples/ - what is going on??" + } || { + $ECHO "$RED[-] missing sample binaries in unicorn_mode/samples/ - what is going on??" + CODE=1 + } } || $ECHO "$YELLOW[-] unicorn_mode is not compiled, cannot test" $ECHO "$GREY[*] all test cases completed.$RESET" - +test "$CODE" = "0" && $ECHO "$GREEN[+] all tests were successful :-)$RESET" +test "$CODE" = "0" || $ECHO "$RED[-] failure in tests :-($RESET" +exit $CODE diff --git a/unicorn_mode/build_unicorn_support.sh b/unicorn_mode/build_unicorn_support.sh index 91a1494f..885329bb 100755 --- a/unicorn_mode/build_unicorn_support.sh +++ b/unicorn_mode/build_unicorn_support.sh @@ -144,8 +144,10 @@ if [ ! "$CKSUM" = "$UNICORN_SHA384" ]; then echo "[*] Downloading Unicorn v1.0.1 from the web..." rm -f "$ARCHIVE" - # NetBSD does not support SSL in the userland, we gotta trust github url - wget -O "$ARCHIVE" -- "$UNICORN_URL" || exit 1 + OK= + while [ -z "$OK" ]; do + wget -c -O "$ARCHIVE" -- "$UNICORN_URL" && OK=1 + done CKSUM=`CKSUMCMD "$ARCHIVE" 2>/dev/null | cut -d' ' -f1` diff --git a/unicorn_mode/patches/afl-unicorn-tcg-runtime-inl.h b/unicorn_mode/patches/afl-unicorn-tcg-runtime-inl.h index 53ab654c..3603fae0 100644 --- a/unicorn_mode/patches/afl-unicorn-tcg-runtime-inl.h +++ b/unicorn_mode/patches/afl-unicorn-tcg-runtime-inl.h @@ -38,6 +38,78 @@ void HELPER(afl_compcov_log_16)(void* uc_ptr, uint64_t cur_loc, uint64_t arg1, u8* afl_area_ptr = ((struct uc_struct*)uc_ptr)->afl_area_ptr; + if ((arg1 & 0xff) == (arg2 & 0xff)) { INC_AFL_AREA(cur_loc); } + +} + +void HELPER(afl_compcov_log_32)(void* uc_ptr, uint64_t cur_loc, uint64_t arg1, + uint64_t arg2) { + + u8* afl_area_ptr = ((struct uc_struct*)uc_ptr)->afl_area_ptr; + + if ((arg1 & 0xff) == (arg2 & 0xff)) { + + INC_AFL_AREA(cur_loc); + if ((arg1 & 0xffff) == (arg2 & 0xffff)) { + + INC_AFL_AREA(cur_loc + 1); + if ((arg1 & 0xffffff) == (arg2 & 0xffffff)) { INC_AFL_AREA(cur_loc + 2); } + + } + + } + +} + +void HELPER(afl_compcov_log_64)(void* uc_ptr, uint64_t cur_loc, uint64_t arg1, + uint64_t arg2) { + + u8* afl_area_ptr = ((struct uc_struct*)uc_ptr)->afl_area_ptr; + + if ((arg1 & 0xff) == (arg2 & 0xff)) { + + INC_AFL_AREA(cur_loc); + if ((arg1 & 0xffff) == (arg2 & 0xffff)) { + + INC_AFL_AREA(cur_loc + 1); + if ((arg1 & 0xffffff) == (arg2 & 0xffffff)) { + + INC_AFL_AREA(cur_loc + 2); + if ((arg1 & 0xffffffff) == (arg2 & 0xffffffff)) { + + INC_AFL_AREA(cur_loc + 3); + if ((arg1 & 0xffffffffff) == (arg2 & 0xffffffffff)) { + + INC_AFL_AREA(cur_loc + 4); + if ((arg1 & 0xffffffffffff) == (arg2 & 0xffffffffffff)) { + + INC_AFL_AREA(cur_loc + 5); + if ((arg1 & 0xffffffffffffff) == (arg2 & 0xffffffffffffff)) { + + INC_AFL_AREA(cur_loc + 6); + + } + + } + + } + + } + + } + + } + + } + +} + +/* // Little endian CompCov +void HELPER(afl_compcov_log_16)(void* uc_ptr, uint64_t cur_loc, uint64_t arg1, + uint64_t arg2) { + + u8* afl_area_ptr = ((struct uc_struct*)uc_ptr)->afl_area_ptr; + if ((arg1 & 0xff00) == (arg2 & 0xff00)) { INC_AFL_AREA(cur_loc); } } @@ -99,4 +171,4 @@ void HELPER(afl_compcov_log_64)(void* uc_ptr, uint64_t cur_loc, uint64_t arg1, } } - +*/ diff --git a/unicorn_mode/samples/compcov_x64/compcov_target.bin b/unicorn_mode/samples/compcov_x64/compcov_target.bin index 091bf1db..2874860b 100644 --- a/unicorn_mode/samples/compcov_x64/compcov_target.bin +++ b/unicorn_mode/samples/compcov_x64/compcov_target.bin Binary files differdiff --git a/unicorn_mode/samples/compcov_x64/compcov_target.c b/unicorn_mode/samples/compcov_x64/compcov_target.c index eb1205b1..0c863b25 100644 --- a/unicorn_mode/samples/compcov_x64/compcov_target.c +++ b/unicorn_mode/samples/compcov_x64/compcov_target.c @@ -16,11 +16,9 @@ int main(void) { unsigned int *data_buf = (unsigned int *) DATA_ADDRESS; - if (data_buf[0] == 0xabadcafe) { - // Cause an 'invalid read' crash if data[0..3] == '\x01\x02\x03\x04' + if (((unsigned short*)data_buf)[0] == 0x0100) { unsigned char invalid_read = *(unsigned char *) 0x00000000; - } else if (data_buf[1] == data_buf[2] + 0x4141) { - // Cause an 'invalid read' crash if (0x10 < data[0] < 0x20) and data[1] > data[2] + } else if (data_buf[1] == data_buf[2] + 0xfffe) { unsigned char invalid_read = *(unsigned char *) 0x00000000; } diff --git a/unicorn_mode/samples/compcov_x64/compcov_target.elf b/unicorn_mode/samples/compcov_x64/compcov_target.elf index 7015fb46..0f1ad916 100755 --- a/unicorn_mode/samples/compcov_x64/compcov_target.elf +++ b/unicorn_mode/samples/compcov_x64/compcov_target.elf Binary files differ |