├── .clang-format ├── .custom-format.py ├── .gitignore ├── .travis.yml ├── Android.bp ├── Android.mk ├── CONTRIBUTING.md ├── Changelog ├── Dockerfile ├── LICENSE ├── Makefile ├── PATCHES ├── QuickStartGuide.txt ├── README.md ├── TODO ├── afl-cmin ├── afl-plot ├── afl-system-config ├── afl-whatsup ├── afl-wine-trace ├── config.h ├── custom_mutators ├── README └── simple_mutator.c ├── dictionaries ├── README.md ├── gif.dict ├── html_tags.dict ├── jpeg.dict ├── js.dict ├── json.dict ├── pdf.dict ├── png.dict ├── regexp.dict ├── sql.dict ├── tiff.dict ├── webp.dict └── xml.dict ├── docs ├── COPYING ├── ChangeLog ├── INSTALL ├── PATCHES ├── QuickStartGuide.txt ├── README.MOpt ├── README.md ├── README.radamsa.md ├── binaryonly_fuzzing.txt ├── custom_mutator.txt ├── env_variables.txt ├── historical_notes.txt ├── life_pro_tips.txt ├── notes_for_asan.txt ├── parallel_fuzzing.txt ├── perf_tips.txt ├── power_schedules.txt ├── python_mutators.txt ├── sister_projects.txt ├── status_screen.txt ├── technical_details.txt ├── visualization │ └── afl_gzip.png └── vuln_samples │ ├── bash-cmd-exec.var │ ├── bash-uninit-mem.var │ ├── ffmpeg-h264-bad-ptr-800m.mp4 │ ├── ffmpeg-h264-bad-read.mp4 │ ├── ffmpeg-h264-call-stack-overflow.mp4 │ ├── file-fpu-exception.elf │ ├── firefox-bmp-leak.bmp │ ├── firefox-chrome-leak.jpg │ ├── firefox-gif-leak.gif │ ├── firefox-gif-leak2.gif │ ├── jxrlib-crash.jxr │ ├── jxrlib-crash2.jxr │ ├── jxrlib-crash3.jxr │ ├── jxrlib-crash4.jxr │ ├── lesspipe-cpio-bad-write.cpio │ ├── libjpeg-sos-leak.jpg │ ├── libjpeg-turbo-dht-leak.jpg │ ├── libtiff-bad-write.tif │ ├── libtiff-uninit-mem.tif │ ├── libtiff-uninit-mem2.tif │ ├── libtiff-uninit-mem3.tif │ ├── libtiff-uninit-mem4.tif │ ├── libxml2-bad-read.xml │ ├── msie-dht-leak.jpg │ ├── msie-jxr-mem-leak.jxr │ ├── msie-png-mem-leak.png │ ├── msie-tiff-mem-leak.tif │ ├── msie-zlib-dos.png │ ├── openssl-null-ptr.der │ ├── openssl-null-ptr2.der │ ├── photoshop-mem-leak.jpg │ ├── sqlite-bad-free.sql │ ├── sqlite-bad-ptr.sql │ ├── sqlite-bad-ptr2.sql │ ├── sqlite-bad-ptr3.sql │ ├── sqlite-heap-overflow.sql │ ├── sqlite-heap-overwrite.sql │ ├── sqlite-negative-memset.sql │ ├── sqlite-null-ptr1.sql │ ├── sqlite-null-ptr10.sql │ ├── sqlite-null-ptr11.sql │ ├── sqlite-null-ptr12.sql │ ├── sqlite-null-ptr13.sql │ ├── sqlite-null-ptr14.sql │ ├── sqlite-null-ptr15.sql │ ├── sqlite-null-ptr2.sql │ ├── sqlite-null-ptr3.sql │ ├── sqlite-null-ptr4.sql │ ├── sqlite-null-ptr5.sql │ ├── sqlite-null-ptr6.sql │ ├── sqlite-null-ptr7.sql │ ├── sqlite-null-ptr8.sql │ ├── sqlite-null-ptr9.sql │ ├── sqlite-oob-read.sql │ ├── sqlite-oob-write.sql │ ├── sqlite-stack-buf-overflow.sql │ ├── sqlite-stack-exhaustion.sql │ ├── sqlite-unint-mem.sql │ ├── sqlite-use-after-free.sql │ ├── strings-bfd-badptr.elf │ ├── strings-bfd-badptr2.elf │ ├── strings-stack-overflow │ ├── strings-unchecked-ctr.elf │ ├── tcpdump-arp-crash.pcap │ ├── tcpdump-ppp-crash.pcap │ ├── unrtf-arbitrary-read.rtf │ └── unzip-t-mem-corruption.zip ├── experimental ├── README.experiments ├── argv_fuzzing │ ├── Makefile │ ├── README.md │ ├── argv-fuzz-inl.h │ └── argvfuzz.c ├── asan_cgroups │ └── limit_memory.sh ├── bash_shellshock │ └── shellshock-fuzz.diff ├── canvas_harness │ └── canvas_harness.html ├── clang_asm_normalize │ └── as ├── crash_triage │ └── triage_crashes.sh ├── distributed_fuzzing │ └── sync_script.sh ├── libpng_no_checksum │ └── libpng-nocrc.patch ├── persistent_demo │ └── persistent_demo.c ├── post_library │ ├── post_library.so.c │ └── post_library_png.so.c └── socket_fuzzing │ ├── Makefile │ ├── README.md │ └── socketfuzz.c ├── gcc_plugin ├── Makefile ├── README.gcc.md ├── README.whitelist.md ├── afl-gcc-fast.c ├── afl-gcc-pass.so.cc └── afl-gcc-rt.o.c ├── include ├── afl-as.h ├── afl-fuzz.h ├── alloc-inl.h ├── android-ashmem.h ├── common.h ├── config.h ├── debug.h ├── forkserver.h ├── hash.h ├── sharedmem.h └── types.h ├── libdislocator ├── Makefile ├── README.dislocator.md └── libdislocator.so.c ├── libtokencap ├── Makefile ├── README.tokencap.md └── libtokencap.so.c ├── llvm_mode ├── LLVMInsTrim.so.cc ├── Makefile ├── MarkNodes.cc ├── MarkNodes.h ├── README.instrim.md ├── README.laf-intel.md ├── README.md ├── README.neverzero.md ├── README.whitelist.md ├── afl-clang-fast.c ├── afl-llvm-pass.so.cc ├── afl-llvm-rt.o.c ├── compare-transform-pass.so.cc ├── split-compares-pass.so.cc └── split-switches-pass.so.cc ├── python_mutators ├── README ├── XmlMutatorMin.py ├── common.py ├── example.py ├── simple-chunk-replace.py └── wrapper_afl_min.py ├── qbdi_mode ├── README.md ├── assets │ └── screen1.png ├── build.sh ├── demo-so.c └── template.cpp ├── qemu_mode ├── README.md ├── build_qemu_support.sh ├── libcompcov │ ├── Makefile │ ├── README.md │ ├── compcovtest.cc │ ├── libcompcov.so.c │ └── pmparser.h ├── patches │ ├── afl-qemu-common.h │ ├── afl-qemu-cpu-inl.h │ ├── afl-qemu-cpu-translate-inl.h │ ├── afl-qemu-floats.h │ ├── afl-qemu-tcg-inl.h │ ├── afl-qemu-translate-inl.h │ ├── arm-translate.diff │ ├── cpu-exec.diff │ ├── elfload.diff │ ├── i386-fpu_helper.diff │ ├── i386-ops_sse.diff │ ├── i386-translate.diff │ ├── softfloat.diff │ ├── syscall.diff │ ├── tcg.diff │ └── translate-all.diff └── unsigaction │ ├── Makefile │ ├── README.md │ └── unsigaction.c ├── src ├── README.src ├── afl-analyze.c ├── afl-as.c ├── afl-common.c ├── afl-forkserver.c ├── afl-fuzz-bitmap.c ├── afl-fuzz-extras.c ├── afl-fuzz-globals.c ├── afl-fuzz-init.c ├── afl-fuzz-misc.c ├── afl-fuzz-one.c ├── afl-fuzz-python.c ├── afl-fuzz-queue.c ├── afl-fuzz-run.c ├── afl-fuzz-stats.c ├── afl-fuzz.c ├── afl-gcc.c ├── afl-gotcpu.c ├── afl-sharedmem.c ├── afl-showmap.c ├── afl-tmin.c └── third_party │ └── libradamsa │ ├── .gitignore │ ├── LICENSE │ ├── Makefile │ ├── README.md │ ├── libradamsa-test.c │ ├── libradamsa.c │ └── radamsa.h ├── test-instr.c ├── test ├── test-compcov.c ├── test-performance.sh └── test.sh ├── testcases ├── README.testcases ├── archives │ ├── common │ │ ├── ar │ │ │ └── small_archive.a │ │ ├── bzip2 │ │ │ └── small_archive.bz2 │ │ ├── cab │ │ │ └── small_archive.cab │ │ ├── compress │ │ │ └── small_archive.Z │ │ ├── cpio │ │ │ └── small_archive.cpio │ │ ├── gzip │ │ │ └── small_archive.gz │ │ ├── lzo │ │ │ └── small_archive.lzo │ │ ├── rar │ │ │ └── small_archive.rar │ │ ├── tar │ │ │ └── small_archive.tar │ │ ├── xz │ │ │ └── small_archive.xz │ │ └── zip │ │ │ └── small_archive.zip │ └── exotic │ │ ├── arj │ │ └── small_archive.arj │ │ ├── lha │ │ └── small_archive.lha │ │ ├── lrzip │ │ └── small_archive.lrz │ │ ├── lzip │ │ └── small_archive.lz │ │ ├── lzma │ │ └── small_archive.lzma │ │ ├── rzip │ │ └── small_archive.rz │ │ └── zoo │ │ └── small_archive.zoo ├── images │ ├── bmp │ │ └── not_kitty.bmp │ ├── gif │ │ └── not_kitty.gif │ ├── ico │ │ └── not_kitty.ico │ ├── jp2 │ │ └── not_kitty.jp2 │ ├── jpeg │ │ └── not_kitty.jpg │ ├── jxr │ │ └── not_kitty.jxr │ ├── png │ │ ├── not_kitty.png │ │ ├── not_kitty_alpha.png │ │ ├── not_kitty_gamma.png │ │ └── not_kitty_icc.png │ ├── tiff │ │ └── not_kitty.tiff │ └── webp │ │ └── not_kitty.webp ├── multimedia │ └── h264 │ │ └── small_movie.mp4 └── others │ ├── elf │ └── small_exec.elf │ ├── js │ └── small_script.js │ ├── pcap │ └── small_capture.pcap │ ├── pdf │ └── small.pdf │ ├── rtf │ └── small_document.rtf │ ├── sql │ └── simple_queries.sql │ ├── text │ └── hello_world.txt │ └── xml │ └── small_document.xml ├── types.h └── unicorn_mode ├── README.md ├── build_unicorn_support.sh ├── helper_scripts ├── template_test_harness.py ├── unicorn_dumper_gdb.py ├── unicorn_dumper_ida.py ├── unicorn_dumper_lldb.py ├── unicorn_dumper_pwndbg.py └── unicorn_loader.py ├── patches ├── afl-unicorn-common.h ├── afl-unicorn-cpu-inl.h ├── afl-unicorn-cpu-translate-inl.h ├── afl-unicorn-tcg-op-inl.h ├── afl-unicorn-tcg-runtime-inl.h ├── compcov.diff └── patches.diff └── samples ├── compcov_x64 ├── COMPILE.md ├── compcov_target.bin ├── compcov_target.c ├── compcov_target.elf ├── compcov_test_harness.py └── sample_inputs │ └── sample1.bin └── simple ├── COMPILE.md ├── sample_inputs ├── sample1.bin ├── sample2.bin ├── sample3.bin ├── sample4.bin └── sample5.bin ├── simple_target.bin ├── simple_target.c ├── simple_test_harness.py └── simple_test_harness_alt.py /.gitignore: -------------------------------------------------------------------------------- 1 | .test 2 | .test2 3 | *.o 4 | *.so 5 | afl-analyze 6 | afl-as 7 | afl-clang 8 | afl-clang++ 9 | afl-clang-fast 10 | afl-clang-fast++ 11 | afl-fuzz 12 | afl-g++ 13 | afl-gcc 14 | afl-gcc-fast 15 | afl-g++-fast 16 | afl-gotcpu 17 | afl-qemu-trace 18 | afl-showmap 19 | afl-tmin 20 | afl-analyze.8 21 | afl-clang-fast++.8 22 | afl-clang-fast.8 23 | afl-cmin.8 24 | afl-fuzz.8 25 | afl-gcc.8 26 | afl-gcc-fast.8 27 | afl-g++-fast.8 28 | afl-gotcpu.8 29 | afl-plot.8 30 | afl-showmap.8 31 | afl-system-config.8 32 | afl-tmin.8 33 | afl-whatsup.8 34 | qemu_mode/libcompcov/compcovtest 35 | as 36 | qemu_mode/qemu-* 37 | core\.* 38 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | 3 | branches: 4 | only: 5 | - master 6 | 7 | matrix: 8 | include: 9 | - os: linux 10 | dist: bionic 11 | env: NAME="bionic-amd64" MODERN="yes" GCC="7" 12 | - os: linux 13 | dist: xenial 14 | env: NAME="xenial-amd64" MODERN="no" GCC="5" EXTRA="libtool-bin clang-6.0" 15 | - os: linux 16 | dist: trusty 17 | env: NAME="trusty-amd64" MODERN="no" GCC="4.8" 18 | - os: linux 19 | dist: xenial 20 | arch: arm64 21 | env: NAME="xenial-arm64" MODERN="no" GCC="5" EXTRA="libtool-bin clang-6.0" AFL_NO_X86="1" CPU_TARGET="aarch64" 22 | # - os: osx 23 | # osx_image: xcode11.2 24 | # env: NAME="osx" HOMEBREW_NO_ANALYTICS="1" LINK="http://releases.llvm.org/9.0.0/" NAME="clang+llvm-9.0.0-x86_64-darwin-apple" 25 | 26 | jobs: 27 | allow_failures: 28 | - os: osx 29 | 30 | env: 31 | - AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 AFL_NO_UI=1 AFL_STOP_MANUALLY=1 32 | # - AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 AFL_NO_UI=1 AFL_EXIT_WHEN_DONE=1 33 | # TODO: test AFL_BENCH_UNTIL_CRASH once we have a target that crashes 34 | # - AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 AFL_NO_UI=1 AFL_BENCH_JUST_ONE=1 35 | 36 | before_install: 37 | # export LLVM_DIR=${TRAVIS_BUILD_DIR}/${LLVM_PACKAGE} 38 | - echo Testing on $NAME 39 | - if [ "$TRAVIS_OS_NAME" = "osx" ]; then wget "$LINK""$NAME".tar.xz ; export LLVM_CONFIG=`pwd`/"$NAME" ; tar xJf "$NAME".tar.xz ; fi 40 | - if [ "$MODERN" = "yes" ]; then sudo apt update ; sudo apt upgrade ; sudo apt install -y libtool libtool-bin automake bison libglib2.0 build-essential clang gcc-"$GCC" gcc-"$GCC"-plugin-dev libc++-"$GCC"-dev ; fi 41 | - if [ "$MODERN" = "no" ]; then sudo apt update ; sudo apt install -y libtool $EXTRA libpixman-1-dev automake bison libglib2.0 build-essential gcc-"$GCC" gcc-"$GCC"-plugin-dev libc++-dev ; fi 42 | 43 | script: 44 | - gcc -v 45 | - clang -v 46 | - if [ "$TRAVIS_OS_NAME" = "osx" ]; then export LLVM_CONFIG=`pwd`/"$NAME" ; make source-only ; fi 47 | - if [ "$TRAVIS_OS_NAME" = "linux" -a "$TRAVIS_CPU_ARCH" = "amd64" ]; then make distrib ; fi 48 | - if [ "$TRAVIS_CPU_ARCH" = "arm64" ] ; then make ; cd qemu_mode && sh ./build_qemu_support.sh ; cd .. ; fi 49 | - make tests 50 | -------------------------------------------------------------------------------- /Android.bp: -------------------------------------------------------------------------------- 1 | cc_defaults { 2 | name: "afl-defaults", 3 | 4 | cflags: [ 5 | "-funroll-loops", 6 | "-Wno-pointer-sign", 7 | "-Wno-pointer-arith", 8 | "-Wno-sign-compare", 9 | "-Wno-unused-parameter", 10 | "-Wno-unused-function", 11 | "-Wno-format", 12 | "-Wno-user-defined-warnings", 13 | "-DUSE_TRACE_PC=1", 14 | "-DBIN_PATH=\"out/host/linux-x86/bin\"", 15 | "-DDOC_PATH=\"out/host/linux-x86/shared/doc/afl\"", 16 | "-D__USE_GNU", 17 | ], 18 | } 19 | 20 | cc_binary { 21 | name: "afl-fuzz", 22 | static_executable: true, 23 | host_supported: true, 24 | 25 | defaults: [ 26 | "afl-defaults", 27 | ], 28 | 29 | srcs: [ 30 | "afl-fuzz.c", 31 | ], 32 | } 33 | 34 | cc_binary { 35 | name: "afl-showmap", 36 | static_executable: true, 37 | host_supported: true, 38 | 39 | defaults: [ 40 | "afl-defaults", 41 | ], 42 | 43 | srcs: [ 44 | "afl-showmap.c", 45 | ], 46 | } 47 | 48 | cc_binary { 49 | name: "afl-tmin", 50 | static_executable: true, 51 | host_supported: true, 52 | 53 | defaults: [ 54 | "afl-defaults", 55 | ], 56 | 57 | srcs: [ 58 | "afl-tmin.c", 59 | ], 60 | } 61 | 62 | cc_binary { 63 | name: "afl-analyze", 64 | static_executable: true, 65 | host_supported: true, 66 | 67 | defaults: [ 68 | "afl-defaults", 69 | ], 70 | 71 | srcs: [ 72 | "afl-analyze.c", 73 | ], 74 | } 75 | 76 | cc_binary { 77 | name: "afl-gotcpu", 78 | static_executable: true, 79 | host_supported: true, 80 | 81 | defaults: [ 82 | "afl-defaults", 83 | ], 84 | 85 | srcs: [ 86 | "afl-gotcpu.c", 87 | ], 88 | } 89 | 90 | cc_binary_host { 91 | name: "afl-clang-fast", 92 | static_executable: true, 93 | 94 | defaults: [ 95 | "afl-defaults", 96 | ], 97 | 98 | cflags: [ 99 | "-D__ANDROID__", 100 | "-DAFL_PATH=\"out/host/linux-x86/lib64\"", 101 | ], 102 | 103 | srcs: [ 104 | "llvm_mode/afl-clang-fast.c", 105 | ], 106 | } 107 | 108 | cc_binary_host { 109 | name: "afl-clang-fast++", 110 | static_executable: true, 111 | 112 | defaults: [ 113 | "afl-defaults", 114 | ], 115 | 116 | cflags: [ 117 | "-D__ANDROID__", 118 | "-DAFL_PATH=\"out/host/linux-x86/lib64\"", 119 | ], 120 | 121 | srcs: [ 122 | "llvm_mode/afl-clang-fast.c", 123 | ], 124 | } 125 | 126 | cc_library_static { 127 | name: "afl-llvm-rt", 128 | compile_multilib: "both", 129 | vendor_available: true, 130 | host_supported: true, 131 | recovery_available: true, 132 | 133 | defaults: [ 134 | "afl-defaults", 135 | ], 136 | 137 | srcs: [ 138 | "llvm_mode/afl-llvm-rt.o.c", 139 | ], 140 | } 141 | -------------------------------------------------------------------------------- /Android.mk: -------------------------------------------------------------------------------- 1 | Makefile -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to submit a Pull Request to AFLplusplus 2 | 3 | Each modified source file, before merging, must be formatted. 4 | 5 | ``` 6 | make code-formatter 7 | ``` 8 | 9 | This should be fine if you modified one of the files already present in the 10 | project, otherwise run: 11 | 12 | ``` 13 | ./.custom-format.py -i file-that-you-have-created.c 14 | ``` 15 | 16 | Regarding the coding style, please follow the AFL style. 17 | No camel case at all and use the AFL's macros when possible (e.g. WARNF, FATAL, ...). 18 | 19 | Remember that AFLplusplus has to build and run on many platforms, so generalize your Makefiles (or your patches to our pre-existing Makefiles) to be as much general as possible. 20 | -------------------------------------------------------------------------------- /Changelog: -------------------------------------------------------------------------------- 1 | docs/ChangeLog -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:eoan 2 | MAINTAINER David Carlier 3 | LABEL "about"="AFLplusplus docker image" 4 | RUN apt-get update && apt-get install -y \ 5 | --no-install-suggests --no-install-recommends \ 6 | automake \ 7 | bison \ 8 | build-essential \ 9 | clang \ 10 | clang-9 \ 11 | flex \ 12 | gcc-9 \ 13 | gcc-9-plugin-dev \ 14 | gcc-9-multilib \ 15 | libc++-9-dev \ 16 | libtool \ 17 | libtool-bin \ 18 | libglib2.0-dev \ 19 | llvm-9-dev \ 20 | python-setuptools \ 21 | python2.7-dev \ 22 | wget \ 23 | ca-certificates \ 24 | libpixman-1-dev \ 25 | && rm -rf /var/lib/apt/lists/* 26 | ARG CC=gcc-9 27 | ARG CXX=g++-9 28 | ARG LLVM_CONFIG=llvm-config-9 29 | COPY . /app 30 | RUN cd /app && make clean && make distrib && \ 31 | make install && cd .. && rm -rf /app 32 | WORKDIR /work 33 | -------------------------------------------------------------------------------- /PATCHES: -------------------------------------------------------------------------------- 1 | docs/PATCHES -------------------------------------------------------------------------------- /QuickStartGuide.txt: -------------------------------------------------------------------------------- 1 | docs/QuickStartGuide.txt -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | 2 | Roadmap 2.60: 3 | ============= 4 | 5 | afl-fuzz: 6 | - radamsa mutator (via dlopen()) 7 | 8 | gcc_plugin: 9 | - laf-intel 10 | 11 | libdislocator: 12 | - add a wrapper for posix_memalign 13 | 14 | qemu_mode: 15 | - update to 4.x (probably this will be skipped :( ) 16 | - instrim for QEMU mode via static analysis (with r2pipe? or angr?) 17 | Idea: The static analyzer outputs a map in which each edge that must be 18 | skipped is marked with 1. QEMU loads it at startup in the parent process. 19 | 20 | custom_mutators: 21 | - rip what Superion is doing into custom mutators for js, php, etc. 22 | 23 | enhance test/test.sh script for checking if compcov features are working 24 | correctly (especially float splitting) 25 | 26 | 27 | The far away future: 28 | ==================== 29 | 30 | Problem: Average targets (tiff, jpeg, unrar) go through 1500 edges. 31 | At afl's default map that means ~16 collisions and ~3 wrappings. 32 | Solution #1: increase map size. 33 | every +1 decreases fuzzing speed by ~10% and halfs the collisions 34 | birthday paradox predicts collisions at this # of edges: 35 | mapsize => collisions 36 | 2^16 = 302 37 | 2^17 = 427 38 | 2^18 = 603 39 | 2^19 = 853 40 | 2^20 = 1207 41 | 2^21 = 1706 42 | 2^22 = 2412 43 | 2^23 = 3411 44 | 2^24 = 4823 45 | Increasing the map is an easy solution but also not a good one. 46 | Solution #2: use dynamic map size and collision free basic block IDs 47 | This only works in llvm_mode and llvm >= 9 though 48 | A potential good future solution. Heiko/hexcoder follows this up 49 | Solution #3: write instruction pointers to a big shared map 50 | 512kb/1MB shared map and the instrumented code writes the instruction 51 | pointer into the map. Map must be big enough but could be command line 52 | controlled. 53 | Good: complete coverage information, nothing is lost. choice of analysis 54 | impacts speed, but this can be decided by user options 55 | Neutral: a little bit slower but no loss of coverage 56 | Bad: completely changes how afl uses the map and the scheduling. 57 | Overall another very good solution, Marc Heuse/vanHauser follows this up 58 | 59 | -------------------------------------------------------------------------------- /afl-system-config: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | test "$1" = "-h" && { 3 | echo afl-system-config by Marc Heuse 4 | echo 5 | echo $0 6 | echo 7 | echo afl-system-config has no command line options 8 | echo 9 | echo afl-system reconfigures the system to a high performance fuzzing state 10 | echo WARNING: this reduces the security of the system 11 | echo 12 | exit 1 13 | } 14 | 15 | PLATFORM=`uname -s` 16 | echo This reconfigures the system to have a better fuzzing performance 17 | if [ '!' "$EUID" = 0 ] && [ '!' `id -u` = 0 ] ; then 18 | echo Error you need to be root to run this 19 | exit 1 20 | fi 21 | if [ "$PLATFORM" = "Linux" ] ; then 22 | sysctl -w kernel.core_pattern=core 23 | sysctl -w kernel.randomize_va_space=0 24 | sysctl -w kernel.sched_child_runs_first=1 25 | sysctl -w kernel.sched_autogroup_enabled=1 26 | sysctl -w kernel.sched_migration_cost_ns=50000000 27 | sysctl -w kernel.sched_latency_ns=250000000 28 | echo never > /sys/kernel/mm/transparent_hugepage/enabled 29 | test -e /sys/devices/system/cpu/cpufreq/scaling_governor && echo performance | tee /sys/devices/system/cpu/cpufreq/scaling_governor 30 | test -e /sys/devices/system/cpu/cpufreq/policy0/scaling_governor && echo performance | tee /sys/devices/system/cpu/cpufreq/policy*/scaling_governor 31 | test -e /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor && echo performance | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor 32 | test -e /sys/devices/system/cpu/intel_pstate/no_turbo && echo 0 > /sys/devices/system/cpu/intel_pstate/no_turbo 33 | test -e /sys/devices/system/cpu/cpufreq/boost && echo 1 > /sys/devices/system/cpu/cpufreq/boost 34 | echo 35 | echo It is recommended to boot the kernel with lots of security off - if you are running a machine that is in a secured network - so set this: 36 | echo '/etc/default/grub:GRUB_CMDLINE_LINUX_DEFAULT="ibpb=off ibrs=off kpti=off l1tf=off mds=off mitigations=off no_stf_barrier noibpb noibrs nopcid nopti nospec_store_bypass_disable nospectre_v1 nospectre_v2 pcid=off pti=off spec_store_bypass_disable=off spectre_v2=off stf_barrier=off"' 37 | fi 38 | if [ "$PLATFORM" = "FreeBSD" ] ; then 39 | sysctl kern.elf32.aslr.enable=0 40 | sysctl kern.elf64.aslr.enable=0 41 | echo 42 | echo It is recommended to boot the kernel with lots of security off - if you are running a machine that is in a secured network - so set this: 43 | echo 'sysctl hw.ibrs_disable=1' 44 | echo 45 | echo 'Setting kern.pmap.pg_ps_enabled=0 into /boot/loader.conf might be helpful too.' 46 | fi 47 | if [ "$PLATFORM" = "OpenBSD" ] ; then 48 | echo 49 | echo 'System security features cannot be disabled on OpenBSD.' 50 | fi 51 | if [ "$PLATFORM" = "NetBSD" ] ; then 52 | echo 53 | echo It is recommended to enable unprivileged users to set cpu affinity 54 | echo to be able to use afl-gotcpu meaningfully. 55 | /sbin/sysctl -w security.models.extensions.user_set_cpu_affinity=1 56 | fi 57 | if [ "$PLATFORM" = "Darwin" ] ; then 58 | if [ $(launchctl list 2>/dev/null | grep -q '\.ReportCrash$') ] ; then 59 | echo We unload the default crash reporter here 60 | SL=/System/Library; PL=com.apple.ReportCrash 61 | launchctl unload -w ${SL}/LaunchAgents/${PL}.plist 62 | sudo launchctl unload -w ${SL}/LaunchDaemons/${PL}.Root.plist 63 | fi 64 | fi 65 | echo 66 | echo Also use AFL_TMPDIR to use a tmpfs for the input file 67 | -------------------------------------------------------------------------------- /afl-wine-trace: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import os 4 | import sys 5 | import pefile 6 | import shutil 7 | import subprocess 8 | 9 | if len(sys.argv) < 2: 10 | print("[afl-wine-trace] usage: ./afl-wine-trace binary [args...]\n") 11 | exit(1) 12 | 13 | if os.getenv("AFL_PATH"): 14 | my_dir = os.getenv("AFL_PATH") 15 | else: 16 | my_dir = os.path.dirname(os.path.abspath(__file__)) 17 | 18 | os.environ["WINELOADERNOEXEC"] = "1" 19 | 20 | pe = pefile.PE(sys.argv[1]) 21 | 22 | if "AFL_ENTRYPOINT" not in os.environ: 23 | os.environ["AFL_ENTRYPOINT"] = "0x%x" % (pe.OPTIONAL_HEADER.ImageBase + pe.OPTIONAL_HEADER.AddressOfEntryPoint) 24 | if not os.getenv("AFL_INST_LIBS"): 25 | if "AFL_CODE_START" not in os.environ: 26 | os.environ["AFL_CODE_START"] = "0x%x" % (pe.OPTIONAL_HEADER.ImageBase + pe.OPTIONAL_HEADER.BaseOfCode) 27 | if "AFL_CODE_END" not in os.environ: 28 | os.environ["AFL_CODE_END"] = "0x%x" % (pe.OPTIONAL_HEADER.ImageBase + pe.OPTIONAL_HEADER.BaseOfCode + pe.OPTIONAL_HEADER.SizeOfCode) 29 | 30 | if pe.FILE_HEADER.Machine == pefile.MACHINE_TYPE["IMAGE_FILE_MACHINE_AMD64"] or pe.FILE_HEADER.Machine == pefile.MACHINE_TYPE["IMAGE_FILE_MACHINE_IA64"]: 31 | os.environ["LD_PRELOAD"] = os.path.join(my_dir, "qemu_mode/unsigaction/unsigaction64.so") 32 | else: 33 | os.environ["LD_PRELOAD"] = os.path.join(my_dir, "qemu_mode/unsigaction/unsigaction32.so") 34 | 35 | if os.getenv("WINECOV_QEMU_PATH"): 36 | qemu_path = os.getenv("WINECOV_QEMU_PATH") 37 | elif os.path.exists(os.path.join(my_dir, "afl-qemu-trace")): 38 | qemu_path = os.path.join(my_dir, "afl-qemu-trace") 39 | else: 40 | qemu_path = "qemu-" 41 | if pe.FILE_HEADER.Machine == pefile.MACHINE_TYPE["IMAGE_FILE_MACHINE_AMD64"] or pe.FILE_HEADER.Machine == pefile.MACHINE_TYPE["IMAGE_FILE_MACHINE_IA64"]: 42 | qemu_path += "x86_64" 43 | elif pe.FILE_HEADER.Machine == pefile.MACHINE_TYPE["IMAGE_FILE_MACHINE_I386"]: 44 | qemu_path += "i386" 45 | else: 46 | print ("[afl-wine-trace] unsuppoted architecture\n") 47 | exit(1) 48 | qemu_path = shutil.which(qemu_path) 49 | 50 | wine_path = None 51 | if os.getenv("AFL_WINE_PATH"): 52 | wine_path = os.getenv("AFL_WINE_PATH") 53 | else: 54 | if not wine_path and shutil.which("wine"): 55 | wine_path = shutil.which("wine") 56 | if not wine_path and os.path.exists("/usr/bin/wine"): 57 | wine_path = "/usr/bin/wine" 58 | if not wine_path and os.path.exists("/usr/lib/wine/wine"): 59 | wine_path = "/usr/lib/wine/wine" 60 | if pe.FILE_HEADER.Machine == pefile.MACHINE_TYPE["IMAGE_FILE_MACHINE_AMD64"] or pe.FILE_HEADER.Machine == pefile.MACHINE_TYPE["IMAGE_FILE_MACHINE_IA64"]: 61 | wine_path += "64" 62 | elif pe.FILE_HEADER.Machine == pefile.MACHINE_TYPE["IMAGE_FILE_MACHINE_I386"]: 63 | pass 64 | else: 65 | print ("[afl-wine-trace] unsopported architecture\n") 66 | exit(1) 67 | 68 | argv = sys.argv[1:] 69 | for i in range(len(argv)): 70 | if ".cur_input" in argv[i]: 71 | argv[i] = subprocess.run([os.path.join(os.path.dirname(wine_path), "winepath"), "--windows", argv[i]], universal_newlines=True, stdout=subprocess.PIPE).stdout 72 | break 73 | 74 | print("[afl-wine-trace] exec:", " ".join([qemu_path, wine_path] + argv)) 75 | os.execve(qemu_path, [qemu_path, wine_path] + argv, os.environ) 76 | -------------------------------------------------------------------------------- /config.h: -------------------------------------------------------------------------------- 1 | include/config.h -------------------------------------------------------------------------------- /custom_mutators/README: -------------------------------------------------------------------------------- 1 | This is a simple example for the AFL_CUSTOM_MUTATOR_LIBRARY feature. 2 | For more information see docs/custom_mutator.txt 3 | -------------------------------------------------------------------------------- /custom_mutators/simple_mutator.c: -------------------------------------------------------------------------------- 1 | /* 2 | Simple Custom Mutator for AFL 3 | 4 | Written by Khaled Yakdan 5 | 6 | This a simple mutator that assumes that the generates messages starting with 7 | one of the three strings GET, PUT, or DEL followed by a payload. The mutator 8 | randomly selects a commend and mutates the payload of the seed provided as 9 | input. 10 | */ 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | static const char *commands[] = { 17 | 18 | "GET", 19 | "PUT", 20 | "DEL", 21 | 22 | }; 23 | 24 | static size_t data_size = 100; 25 | 26 | size_t afl_custom_mutator(uint8_t *data, size_t size, uint8_t *mutated_out, 27 | size_t max_size, unsigned int seed) { 28 | 29 | // Seed the PRNG 30 | srand(seed); 31 | 32 | // Make sure that the packet size does not exceed the maximum size expected by 33 | // the fuzzer 34 | size_t mutated_size = data_size <= max_size ? data_size : max_size; 35 | 36 | // Randomly select a command string to add as a header to the packet 37 | memcpy(mutated_out, commands[rand() % 3], 3); 38 | 39 | // Mutate the payload of the packet 40 | for (int i = 3; i < mutated_size; i++) { 41 | 42 | mutated_out[i] = (data[i] + rand() % 10) & 0xff; 43 | 44 | } 45 | 46 | return mutated_size; 47 | 48 | } 49 | 50 | -------------------------------------------------------------------------------- /dictionaries/README.md: -------------------------------------------------------------------------------- 1 | # AFL dictionaries 2 | 3 | (See [../docs/README.md](../docs/README.md) for the general instruction manual.) 4 | 5 | This subdirectory contains a set of dictionaries that can be used in 6 | conjunction with the -x option to allow the fuzzer to effortlessly explore the 7 | grammar of some of the more verbose data formats or languages. The basic 8 | principle behind the operation of fuzzer dictionaries is outlined in section 10 9 | of the "main" README.md for the project. 10 | 11 | Custom dictionaries can be added at will. They should consist of a 12 | reasonably-sized set of rudimentary syntax units that the fuzzer will then try 13 | to clobber together in various ways. Snippets between 2 and 16 bytes are 14 | usually the sweet spot. 15 | 16 | Custom dictionaries can be created in two ways: 17 | 18 | - By creating a new directory and placing each token in a separate file, in 19 | which case, there is no need to escape or otherwise format the data. 20 | 21 | - By creating a flat text file where tokens are listed one per line in the 22 | format of name="value". The alphanumeric name is ignored and can be omitted, 23 | although it is a convenient way to document the meaning of a particular 24 | token. The value must appear in quotes, with hex escaping (\xNN) applied to 25 | all non-printable, high-bit, or otherwise problematic characters (\\ and \" 26 | shorthands are recognized, too). 27 | 28 | The fuzzer auto-selects the appropriate mode depending on whether the -x 29 | parameter is a file or a directory. 30 | 31 | In the file mode, every name field can be optionally followed by @, e.g.: 32 | 33 | `keyword_foo@1 = "foo"` 34 | 35 | Such entries will be loaded only if the requested dictionary level is equal or 36 | higher than this number. The default level is zero; a higher value can be set 37 | by appending @ to the dictionary file name, like so: 38 | 39 | `-x path/to/dictionary.dct@2` 40 | 41 | Good examples of dictionaries can be found in xml.dict and png.dict. 42 | -------------------------------------------------------------------------------- /dictionaries/gif.dict: -------------------------------------------------------------------------------- 1 | # 2 | # AFL dictionary for GIF images 3 | # ----------------------------- 4 | # 5 | # Created by Michal Zalewski 6 | # 7 | 8 | header_87a="87a" 9 | header_89a="89a" 10 | header_gif="GIF" 11 | 12 | marker_2c="," 13 | marker_3b=";" 14 | 15 | section_2101="!\x01\x12" 16 | section_21f9="!\xf9\x04" 17 | section_21fe="!\xfe" 18 | section_21ff="!\xff\x11" 19 | -------------------------------------------------------------------------------- /dictionaries/html_tags.dict: -------------------------------------------------------------------------------- 1 | # 2 | # AFL dictionary for HTML parsers (tags only) 3 | # ------------------------------------------- 4 | # 5 | # A basic collection of HTML tags likely to matter to HTML parsers. Does *not* 6 | # include any attributes or attribute values. 7 | # 8 | # Created by Michal Zalewski 9 | # 10 | 11 | tag_a="" 12 | tag_abbr="" 13 | tag_acronym="" 14 | tag_address="
" 15 | tag_annotation_xml="" 16 | tag_applet="" 17 | tag_area="" 18 | tag_article="
" 19 | tag_aside="