├── Android.mk ├── Changelog ├── PATCHES ├── types.h ├── config.h ├── docs ├── README.md ├── README.radamsa.md ├── vuln_samples │ ├── bash-cmd-exec.var │ ├── sqlite-null-ptr4.sql │ ├── bash-uninit-mem.var │ ├── sqlite-null-ptr10.sql │ ├── sqlite-null-ptr11.sql │ ├── sqlite-null-ptr3.sql │ ├── sqlite-null-ptr5.sql │ ├── sqlite-null-ptr2.sql │ ├── sqlite-null-ptr7.sql │ ├── sqlite-bad-ptr.sql │ ├── sqlite-null-ptr8.sql │ ├── sqlite-stack-exhaustion.sql │ ├── sqlite-null-ptr1.sql │ ├── sqlite-null-ptr12.sql │ ├── sqlite-null-ptr13.sql │ ├── sqlite-unint-mem.sql │ ├── libxml2-bad-read.xml │ ├── jxrlib-crash.jxr │ ├── jxrlib-crash2.jxr │ ├── jxrlib-crash3.jxr │ ├── jxrlib-crash4.jxr │ ├── msie-dht-leak.jpg │ ├── msie-zlib-dos.png │ ├── sqlite-null-ptr9.sql │ ├── sqlite-oob-read.sql │ ├── firefox-bmp-leak.bmp │ ├── firefox-gif-leak.gif │ ├── firefox-gif-leak2.gif │ ├── libjpeg-sos-leak.jpg │ ├── libtiff-bad-write.tif │ ├── msie-jxr-mem-leak.jxr │ ├── msie-png-mem-leak.png │ ├── openssl-null-ptr.der │ ├── openssl-null-ptr2.der │ ├── sqlite-bad-free.sql │ ├── sqlite-null-ptr6.sql │ ├── ffmpeg-h264-bad-read.mp4 │ ├── file-fpu-exception.elf │ ├── firefox-chrome-leak.jpg │ ├── libtiff-uninit-mem.tif │ ├── libtiff-uninit-mem2.tif │ ├── libtiff-uninit-mem3.tif │ ├── libtiff-uninit-mem4.tif │ ├── msie-tiff-mem-leak.tif │ ├── photoshop-mem-leak.jpg │ ├── strings-bfd-badptr.elf │ ├── strings-bfd-badptr2.elf │ ├── strings-stack-overflow │ ├── tcpdump-arp-crash.pcap │ ├── tcpdump-ppp-crash.pcap │ ├── unrtf-arbitrary-read.rtf │ ├── libjpeg-turbo-dht-leak.jpg │ ├── strings-unchecked-ctr.elf │ ├── unzip-t-mem-corruption.zip │ ├── ffmpeg-h264-bad-ptr-800m.mp4 │ ├── lesspipe-cpio-bad-write.cpio │ ├── sqlite-bad-ptr2.sql │ ├── ffmpeg-h264-call-stack-overflow.mp4 │ ├── sqlite-stack-buf-overflow.sql │ ├── sqlite-null-ptr15.sql │ ├── sqlite-bad-ptr3.sql │ ├── sqlite-heap-overflow.sql │ ├── sqlite-use-after-free.sql │ ├── sqlite-oob-write.sql │ ├── sqlite-null-ptr14.sql │ └── sqlite-negative-memset.sql ├── visualization │ └── afl_gzip.png ├── PATCHES ├── custom_mutator.txt ├── README.MOpt ├── QuickStartGuide.txt ├── life_pro_tips.txt └── power_schedules.txt ├── QuickStartGuide.txt ├── testcases ├── others │ ├── text │ │ └── hello_world.txt │ ├── js │ │ └── small_script.js │ ├── xml │ │ └── small_document.xml │ ├── rtf │ │ └── small_document.rtf │ ├── elf │ │ └── small_exec.elf │ ├── sql │ │ └── simple_queries.sql │ ├── pcap │ │ └── small_capture.pcap │ └── pdf │ │ └── small.pdf ├── images │ ├── bmp │ │ └── not_kitty.bmp │ ├── gif │ │ └── not_kitty.gif │ ├── ico │ │ └── not_kitty.ico │ ├── jp2 │ │ └── not_kitty.jp2 │ ├── jxr │ │ └── not_kitty.jxr │ ├── png │ │ ├── not_kitty.png │ │ ├── not_kitty_icc.png │ │ ├── not_kitty_alpha.png │ │ └── not_kitty_gamma.png │ ├── jpeg │ │ └── not_kitty.jpg │ ├── tiff │ │ └── not_kitty.tiff │ └── webp │ │ └── not_kitty.webp ├── multimedia │ └── h264 │ │ └── small_movie.mp4 ├── archives │ ├── common │ │ ├── cab │ │ │ └── small_archive.cab │ │ ├── gzip │ │ │ └── small_archive.gz │ │ ├── lzo │ │ │ └── small_archive.lzo │ │ ├── rar │ │ │ └── small_archive.rar │ │ ├── xz │ │ │ └── small_archive.xz │ │ ├── zip │ │ │ └── small_archive.zip │ │ ├── bzip2 │ │ │ └── small_archive.bz2 │ │ ├── cpio │ │ │ └── small_archive.cpio │ │ ├── compress │ │ │ └── small_archive.Z │ │ ├── ar │ │ │ └── small_archive.a │ │ └── tar │ │ │ └── small_archive.tar │ └── exotic │ │ ├── arj │ │ └── small_archive.arj │ │ ├── lha │ │ └── small_archive.lha │ │ ├── lzip │ │ └── small_archive.lz │ │ ├── rzip │ │ └── small_archive.rz │ │ ├── zoo │ │ └── small_archive.zoo │ │ ├── lrzip │ │ └── small_archive.lrz │ │ └── lzma │ │ └── small_archive.lzma └── README.testcases ├── unicorn_mode ├── samples │ ├── simple │ │ ├── sample_inputs │ │ │ ├── sample1.bin │ │ │ ├── sample2.bin │ │ │ ├── sample3.bin │ │ │ ├── sample4.bin │ │ │ └── sample5.bin │ │ ├── simple_target.bin │ │ ├── simple_target.c │ │ └── COMPILE.md │ └── compcov_x64 │ │ ├── sample_inputs │ │ └── sample1.bin │ │ ├── compcov_target.bin │ │ ├── compcov_target.elf │ │ ├── COMPILE.md │ │ └── compcov_target.c └── patches │ ├── afl-unicorn-common.h │ ├── afl-unicorn-cpu-translate-inl.h │ ├── afl-unicorn-tcg-op-inl.h │ └── patches.diff ├── src ├── third_party │ └── libradamsa │ │ ├── .gitignore │ │ ├── README.md │ │ ├── radamsa.h │ │ ├── Makefile │ │ ├── LICENSE │ │ └── libradamsa-test.c └── README.src ├── qbdi_mode ├── assets │ └── screen1.png ├── demo-so.c └── build.sh ├── qemu_mode ├── unsigaction │ ├── unsigaction.c │ ├── README.md │ └── Makefile ├── patches │ ├── softfloat.diff │ ├── tcg.diff │ ├── translate-all.diff │ ├── i386-translate.diff │ ├── cpu-exec.diff │ ├── i386-fpu_helper.diff │ ├── i386-ops_sse.diff │ ├── afl-qemu-translate-inl.h │ ├── elfload.diff │ ├── syscall.diff │ └── afl-qemu-common.h └── libcompcov │ ├── Makefile │ ├── README.md │ └── compcovtest.cc ├── custom_mutators ├── README └── simple_mutator.c ├── llvm_mode ├── MarkNodes.h ├── README.instrim.md ├── README.neverzero.md ├── README.laf-intel.md └── README.whitelist.md ├── dictionaries ├── gif.dict ├── webp.dict ├── jpeg.dict ├── json.dict ├── png.dict ├── tiff.dict ├── xml.dict ├── README.md ├── js.dict └── html_tags.dict ├── experimental ├── socket_fuzzing │ ├── README.md │ ├── Makefile │ └── socketfuzz.c ├── libpng_no_checksum │ └── libpng-nocrc.patch ├── argv_fuzzing │ ├── README.md │ ├── Makefile │ ├── argvfuzz.c │ └── argv-fuzz-inl.h ├── clang_asm_normalize │ └── as ├── README.experiments ├── bash_shellshock │ └── shellshock-fuzz.diff ├── distributed_fuzzing │ └── sync_script.sh ├── crash_triage │ └── triage_crashes.sh ├── persistent_demo │ └── persistent_demo.c ├── post_library │ └── post_library_png.so.c └── canvas_harness │ └── canvas_harness.html ├── .gitignore ├── CONTRIBUTING.md ├── python_mutators ├── README ├── common.py ├── simple-chunk-replace.py ├── example.py └── wrapper_afl_min.py ├── test └── test-compcov.c ├── Dockerfile ├── include ├── sharedmem.h ├── common.h ├── forkserver.h ├── hash.h ├── android-ashmem.h └── types.h ├── test-instr.c ├── libdislocator ├── Makefile └── README.dislocator.md ├── libtokencap ├── Makefile └── README.tokencap.md ├── TODO ├── .travis.yml ├── Android.bp ├── gcc_plugin └── README.whitelist.md ├── afl-system-config └── afl-wine-trace /Android.mk: -------------------------------------------------------------------------------- 1 | Makefile -------------------------------------------------------------------------------- /Changelog: -------------------------------------------------------------------------------- 1 | docs/ChangeLog -------------------------------------------------------------------------------- /PATCHES: -------------------------------------------------------------------------------- 1 | docs/PATCHES -------------------------------------------------------------------------------- /types.h: -------------------------------------------------------------------------------- 1 | include/types.h -------------------------------------------------------------------------------- /config.h: -------------------------------------------------------------------------------- 1 | include/config.h -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | ../README.md -------------------------------------------------------------------------------- /QuickStartGuide.txt: -------------------------------------------------------------------------------- 1 | docs/QuickStartGuide.txt -------------------------------------------------------------------------------- /testcases/others/text/hello_world.txt: -------------------------------------------------------------------------------- 1 | hello 2 | -------------------------------------------------------------------------------- /testcases/others/js/small_script.js: -------------------------------------------------------------------------------- 1 | if (1==1) eval('1'); -------------------------------------------------------------------------------- /testcases/others/xml/small_document.xml: -------------------------------------------------------------------------------- 1 | d 2 | -------------------------------------------------------------------------------- /unicorn_mode/samples/simple/sample_inputs/sample1.bin: -------------------------------------------------------------------------------- 1 | abcd -------------------------------------------------------------------------------- /unicorn_mode/samples/simple/sample_inputs/sample2.bin: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /unicorn_mode/samples/simple/sample_inputs/sample3.bin: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /unicorn_mode/samples/simple/sample_inputs/sample4.bin: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /unicorn_mode/samples/simple/sample_inputs/sample5.bin: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /docs/README.radamsa.md: -------------------------------------------------------------------------------- 1 | ../src/third_party/libradamsa/README.md -------------------------------------------------------------------------------- /docs/vuln_samples/bash-cmd-exec.var: -------------------------------------------------------------------------------- 1 | () { _; } >_[$($())] { id; } -------------------------------------------------------------------------------- /docs/vuln_samples/sqlite-null-ptr4.sql: -------------------------------------------------------------------------------- 1 | select n()AND+#00; 2 | -------------------------------------------------------------------------------- /testcases/others/rtf/small_document.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\pard Test\par} -------------------------------------------------------------------------------- /docs/vuln_samples/bash-uninit-mem.var: -------------------------------------------------------------------------------- 1 | () { x() { _; }; x() { _; } <O));insert into t0 2 | select randomblob(0)-trim(0); 3 | -------------------------------------------------------------------------------- /docs/vuln_samples/sqlite-null-ptr6.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/docs/vuln_samples/sqlite-null-ptr6.sql -------------------------------------------------------------------------------- /testcases/images/png/not_kitty_icc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/testcases/images/png/not_kitty_icc.png -------------------------------------------------------------------------------- /docs/vuln_samples/ffmpeg-h264-bad-read.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/docs/vuln_samples/ffmpeg-h264-bad-read.mp4 -------------------------------------------------------------------------------- /docs/vuln_samples/file-fpu-exception.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/docs/vuln_samples/file-fpu-exception.elf -------------------------------------------------------------------------------- /docs/vuln_samples/firefox-chrome-leak.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/docs/vuln_samples/firefox-chrome-leak.jpg -------------------------------------------------------------------------------- /docs/vuln_samples/libtiff-uninit-mem.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/docs/vuln_samples/libtiff-uninit-mem.tif -------------------------------------------------------------------------------- /docs/vuln_samples/libtiff-uninit-mem2.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/docs/vuln_samples/libtiff-uninit-mem2.tif -------------------------------------------------------------------------------- /docs/vuln_samples/libtiff-uninit-mem3.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/docs/vuln_samples/libtiff-uninit-mem3.tif -------------------------------------------------------------------------------- /docs/vuln_samples/libtiff-uninit-mem4.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/docs/vuln_samples/libtiff-uninit-mem4.tif -------------------------------------------------------------------------------- /docs/vuln_samples/msie-tiff-mem-leak.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/docs/vuln_samples/msie-tiff-mem-leak.tif -------------------------------------------------------------------------------- /docs/vuln_samples/photoshop-mem-leak.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/docs/vuln_samples/photoshop-mem-leak.jpg -------------------------------------------------------------------------------- /docs/vuln_samples/strings-bfd-badptr.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/docs/vuln_samples/strings-bfd-badptr.elf -------------------------------------------------------------------------------- /docs/vuln_samples/strings-bfd-badptr2.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/docs/vuln_samples/strings-bfd-badptr2.elf -------------------------------------------------------------------------------- /docs/vuln_samples/strings-stack-overflow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/docs/vuln_samples/strings-stack-overflow -------------------------------------------------------------------------------- /docs/vuln_samples/tcpdump-arp-crash.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/docs/vuln_samples/tcpdump-arp-crash.pcap -------------------------------------------------------------------------------- /docs/vuln_samples/tcpdump-ppp-crash.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/docs/vuln_samples/tcpdump-ppp-crash.pcap -------------------------------------------------------------------------------- /docs/vuln_samples/unrtf-arbitrary-read.rtf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/docs/vuln_samples/unrtf-arbitrary-read.rtf -------------------------------------------------------------------------------- /testcases/images/png/not_kitty_alpha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/testcases/images/png/not_kitty_alpha.png -------------------------------------------------------------------------------- /testcases/images/png/not_kitty_gamma.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/testcases/images/png/not_kitty_gamma.png -------------------------------------------------------------------------------- /testcases/multimedia/h264/small_movie.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/testcases/multimedia/h264/small_movie.mp4 -------------------------------------------------------------------------------- /testcases/others/pcap/small_capture.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/testcases/others/pcap/small_capture.pcap -------------------------------------------------------------------------------- /docs/vuln_samples/libjpeg-turbo-dht-leak.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/docs/vuln_samples/libjpeg-turbo-dht-leak.jpg -------------------------------------------------------------------------------- /docs/vuln_samples/strings-unchecked-ctr.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/docs/vuln_samples/strings-unchecked-ctr.elf -------------------------------------------------------------------------------- /docs/vuln_samples/unzip-t-mem-corruption.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/docs/vuln_samples/unzip-t-mem-corruption.zip -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /docs/vuln_samples/ffmpeg-h264-bad-ptr-800m.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/docs/vuln_samples/ffmpeg-h264-bad-ptr-800m.mp4 -------------------------------------------------------------------------------- /docs/vuln_samples/lesspipe-cpio-bad-write.cpio: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/docs/vuln_samples/lesspipe-cpio-bad-write.cpio -------------------------------------------------------------------------------- /testcases/archives/common/cab/small_archive.cab: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/testcases/archives/common/cab/small_archive.cab -------------------------------------------------------------------------------- /testcases/archives/common/gzip/small_archive.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/testcases/archives/common/gzip/small_archive.gz -------------------------------------------------------------------------------- /testcases/archives/common/lzo/small_archive.lzo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/testcases/archives/common/lzo/small_archive.lzo -------------------------------------------------------------------------------- /testcases/archives/common/rar/small_archive.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/testcases/archives/common/rar/small_archive.rar -------------------------------------------------------------------------------- /testcases/archives/common/xz/small_archive.xz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/testcases/archives/common/xz/small_archive.xz -------------------------------------------------------------------------------- /testcases/archives/common/zip/small_archive.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/testcases/archives/common/zip/small_archive.zip -------------------------------------------------------------------------------- /testcases/archives/exotic/arj/small_archive.arj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/testcases/archives/exotic/arj/small_archive.arj -------------------------------------------------------------------------------- /testcases/archives/exotic/lha/small_archive.lha: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/testcases/archives/exotic/lha/small_archive.lha -------------------------------------------------------------------------------- /testcases/archives/exotic/lzip/small_archive.lz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/testcases/archives/exotic/lzip/small_archive.lz -------------------------------------------------------------------------------- /testcases/archives/exotic/rzip/small_archive.rz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/testcases/archives/exotic/rzip/small_archive.rz -------------------------------------------------------------------------------- /testcases/archives/exotic/zoo/small_archive.zoo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/testcases/archives/exotic/zoo/small_archive.zoo -------------------------------------------------------------------------------- /unicorn_mode/samples/simple/simple_target.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/unicorn_mode/samples/simple/simple_target.bin -------------------------------------------------------------------------------- /testcases/archives/common/bzip2/small_archive.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/testcases/archives/common/bzip2/small_archive.bz2 -------------------------------------------------------------------------------- /testcases/archives/common/cpio/small_archive.cpio: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/testcases/archives/common/cpio/small_archive.cpio -------------------------------------------------------------------------------- /testcases/archives/exotic/lrzip/small_archive.lrz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/testcases/archives/exotic/lrzip/small_archive.lrz -------------------------------------------------------------------------------- /testcases/archives/exotic/lzma/small_archive.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/testcases/archives/exotic/lzma/small_archive.lzma -------------------------------------------------------------------------------- /docs/vuln_samples/sqlite-bad-ptr2.sql: -------------------------------------------------------------------------------- 1 | PRAGMA foreign_keys=1;CREATE TABLE t1("""0"PRIMARY KEy REFERENCES t1 ON DELETE SET NULL);REPLACE INTO t1 SELECT(0); 2 | -------------------------------------------------------------------------------- /testcases/archives/common/compress/small_archive.Z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/testcases/archives/common/compress/small_archive.Z -------------------------------------------------------------------------------- /unicorn_mode/samples/compcov_x64/compcov_target.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/unicorn_mode/samples/compcov_x64/compcov_target.bin -------------------------------------------------------------------------------- /unicorn_mode/samples/compcov_x64/compcov_target.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/unicorn_mode/samples/compcov_x64/compcov_target.elf -------------------------------------------------------------------------------- /docs/vuln_samples/ffmpeg-h264-call-stack-overflow.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uds-se/AFLplusplus/HEAD/docs/vuln_samples/ffmpeg-h264-call-stack-overflow.mp4 -------------------------------------------------------------------------------- /docs/vuln_samples/sqlite-stack-buf-overflow.sql: -------------------------------------------------------------------------------- 1 | SELECT printf('%*.*f',90000||006000000&6600000000,00000000000000000909000000000000.0000000000000000)""WHERE"">""; 2 | -------------------------------------------------------------------------------- /testcases/others/pdf/small.pdf: -------------------------------------------------------------------------------- 1 | %PDF-1.0 2 | 1 0 obj<>endobj 2 0 obj<>endobj 3 0 obj<>endobj trailer<> -------------------------------------------------------------------------------- /docs/vuln_samples/sqlite-null-ptr15.sql: -------------------------------------------------------------------------------- 1 | CREATE VIRTUAL TABLE t4 USING fts4(0,b,c,notindexed=0);INSERT INTO t4 VALUES('','','0');BEGIN;INSERT INTO t4 VALUES('','','0');INSERT INTO t4(t4)VALUES('integrity-check'); 2 | -------------------------------------------------------------------------------- /docs/vuln_samples/sqlite-bad-ptr3.sql: -------------------------------------------------------------------------------- 1 | create table t(l);PRAGMA writable_schema=ON; 2 | UPDATE sqlite_master SET sql='00000000000000000000000000000000000000000000000000000000000000000000000000000000[%S';PRAGMA t;SAVEPOINT x;ROLLBACK;VACUUM; 3 | -------------------------------------------------------------------------------- /docs/vuln_samples/sqlite-heap-overflow.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS t;CREATE VIRTUAL TABLE t0 USING fts4();insert into t0 select zeroblob(0);SAVEPOINT O;insert into t0 2 | select(0);SAVEPOINT E;insert into t0 SELECT 0 UNION SELECT 0'x'ORDER BY x; 3 | -------------------------------------------------------------------------------- /qemu_mode/unsigaction/README.md: -------------------------------------------------------------------------------- 1 | # unsigation 2 | 3 | This library disable sigaction when preloaded. 4 | 5 | Mainly needed by Wine mode but can be used as a separate tool. 6 | 7 | A similar solution can be found in is [preeny](https://github.com/zardus/preeny). 8 | -------------------------------------------------------------------------------- /docs/vuln_samples/sqlite-use-after-free.sql: -------------------------------------------------------------------------------- 1 | create table t(s);PRAGMA writable_schema=ON;UPDATE sqlite_master SET sql='ANALYZE;CREATE VIRTUAL TABLE t USING fts3;DROP TABLE t;DROP TABLE EXISTS t';PRAGMA r;SAVEPOINT T;ANALYZE;ROLLBACK;SAVEPOINT E;DROP TABLE IF EXISTS t; 2 | -------------------------------------------------------------------------------- /docs/vuln_samples/sqlite-oob-write.sql: -------------------------------------------------------------------------------- 1 | CREATE VIRTUAL TABLE t0 USING fts4(x,order=DESC); 2 | INSERT INTO t0(docid,x)VALUES(-1E0,'0(o'); 3 | INSERT INTO t0 VALUES(''); 4 | INSERT INTO t0 VALUES(''); 5 | INSeRT INTO t0 VALUES('o'); 6 | SELECT docid FROM t0 WHERE t0 MATCH'"0*o"'; 7 | -------------------------------------------------------------------------------- /llvm_mode/MarkNodes.h: -------------------------------------------------------------------------------- 1 | #ifndef __MARK_NODES__ 2 | #define __MARK_NODES__ 3 | 4 | #include "llvm/IR/BasicBlock.h" 5 | #include "llvm/IR/Function.h" 6 | #include 7 | 8 | std::pair, std::vector> 9 | markNodes(llvm::Function *F); 10 | 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /docs/vuln_samples/sqlite-null-ptr14.sql: -------------------------------------------------------------------------------- 1 | CREATE VIRTUAL TABLE x USING fts4();VALUES(0,0),(0,0),(0,0),(0,0);PRAGMA writable_schema=ON;UPDATE sqlite_master SET sql=''WHERE name='';UPDATE sqlite_master SET sql='CREATE table t(d CHECK(T(#0)';SAVEPOINT K;SAVEPOINT T;SAVEPOINT T;ANALYZE;ROLLBACK;SAVEPOINT E;DROP TABLE IF EXISTS t; 2 | -------------------------------------------------------------------------------- /src/third_party/libradamsa/README.md: -------------------------------------------------------------------------------- 1 | # libradamsa 2 | 3 | Pretranslated radamsa library. This code belongs to the radamsa author. 4 | 5 | > Original repository: https://gitlab.com/akihe/radamsa 6 | 7 | > Source commit: 7b2cc2d0 8 | 9 | > The code here is adapted for AFL++ with minor changes respect the original version 10 | -------------------------------------------------------------------------------- /testcases/archives/common/ar/small_archive.a: -------------------------------------------------------------------------------- 1 | ! 2 | limerick/ 1415337776 500 500 100640 191 ` 3 | There was a young man from Japan 4 | Whose limericks never would scan. 5 | When asked why that was, 6 | He replied "It's because 7 | I always try to cram as many words into the last line as I possibly can." 8 | 9 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /qemu_mode/patches/softfloat.diff: -------------------------------------------------------------------------------- 1 | diff --git a/fpu/softfloat.c b/fpu/softfloat.c 2 | index e1eef954..2f8d0d62 100644 3 | --- a/fpu/softfloat.c 4 | +++ b/fpu/softfloat.c 5 | @@ -7205,3 +7205,5 @@ float128 float128_scalbn(float128 a, int n, float_status *status) 6 | , status); 7 | 8 | } 9 | + 10 | +#include "../../patches/afl-qemu-floats.h" 11 | -------------------------------------------------------------------------------- /dictionaries/webp.dict: -------------------------------------------------------------------------------- 1 | # 2 | # AFL dictionary for WebP images 3 | # ------------------------------ 4 | # 5 | # Created by Michal Zalewski 6 | # 7 | 8 | header_RIFF="RIFF" 9 | header_WEBP="WEBP" 10 | 11 | section_ALPH="ALPH" 12 | section_ANIM="ANIM" 13 | section_ANMF="ANMF" 14 | section_EXIF="EXIF" 15 | section_FRGM="FRGM" 16 | section_ICCP="ICCP" 17 | section_VP8="VP8 " 18 | section_VP8L="VP8L" 19 | section_VP8X="VP8X" 20 | section_XMP="XMP " 21 | -------------------------------------------------------------------------------- /experimental/socket_fuzzing/README.md: -------------------------------------------------------------------------------- 1 | # socketfuzz 2 | 3 | when you want to fuzz a network service and you can not/do not want to modify 4 | the source (or just have a binary), then this LD_PRELOAD library will allow 5 | for sending input to stdin which the target binary will think is coming from 6 | a network socket. 7 | 8 | This is desock_dup.c from the amazing preeny project 9 | https://github.com/zardus/preeny 10 | 11 | It is packaged in afl++ to have it at hand if needed 12 | -------------------------------------------------------------------------------- /qemu_mode/patches/tcg.diff: -------------------------------------------------------------------------------- 1 | diff --git a/tcg/tcg.c b/tcg/tcg.c 2 | index e85133ef..54b9b390 100644 3 | --- a/tcg/tcg.c 4 | +++ b/tcg/tcg.c 5 | @@ -1612,6 +1612,9 @@ bool tcg_op_supported(TCGOpcode op) 6 | } 7 | } 8 | 9 | + 10 | +#include "../../patches/afl-qemu-tcg-inl.h" 11 | + 12 | /* Note: we convert the 64 bit args to 32 bit and do some alignment 13 | and endian swap. Maybe it would be better to do the alignment 14 | and endian swap in tcg_reg_alloc_call(). */ 15 | -------------------------------------------------------------------------------- /src/third_party/libradamsa/radamsa.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | extern void radamsa_init(); 5 | 6 | extern size_t radamsa(uint8_t *ptr, size_t len, 7 | uint8_t *target, size_t max, 8 | unsigned int seed); 9 | 10 | extern size_t radamsa_inplace(uint8_t *ptr, 11 | size_t len, 12 | size_t max, 13 | unsigned int seed); 14 | 15 | 16 | -------------------------------------------------------------------------------- /experimental/libpng_no_checksum/libpng-nocrc.patch: -------------------------------------------------------------------------------- 1 | --- pngrutil.c.orig 2014-06-12 03:35:16.000000000 +0200 2 | +++ pngrutil.c 2014-07-01 05:08:31.000000000 +0200 3 | @@ -268,7 +268,11 @@ 4 | if (need_crc != 0) 5 | { 6 | crc = png_get_uint_32(crc_bytes); 7 | - return ((int)(crc != png_ptr->crc)); 8 | + 9 | + if (crc != png_ptr->crc) 10 | + fprintf(stderr, "NOTE: CRC in the file is 0x%08x, change to 0x%08x\n", crc, png_ptr->crc); 11 | + 12 | + return ((int)(1 != 1)); 13 | } 14 | 15 | else 16 | -------------------------------------------------------------------------------- /dictionaries/jpeg.dict: -------------------------------------------------------------------------------- 1 | # 2 | # AFL dictionary for JPEG images 3 | # ------------------------------ 4 | # 5 | # Created by Michal Zalewski 6 | # 7 | 8 | header_jfif="JFIF\x00" 9 | header_jfxx="JFXX\x00" 10 | 11 | section_ffc0="\xff\xc0" 12 | section_ffc2="\xff\xc2" 13 | section_ffc4="\xff\xc4" 14 | section_ffd0="\xff\xd0" 15 | section_ffd8="\xff\xd8" 16 | section_ffd9="\xff\xd9" 17 | section_ffda="\xff\xda" 18 | section_ffdb="\xff\xdb" 19 | section_ffdd="\xff\xdd" 20 | section_ffe0="\xff\xe0" 21 | section_ffe1="\xff\xe1" 22 | section_fffe="\xff\xfe" 23 | -------------------------------------------------------------------------------- /docs/vuln_samples/sqlite-negative-memset.sql: -------------------------------------------------------------------------------- 1 | SELECT*from(select"",zeroblob(0),zeroblob(1E9),zeroblob(0),zeroblob(150000000),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(1E9),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0)),(select"",zeroblob(1E9),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(1E9),(0),zeroblob(150000000),(0),zeroblob(0),(0)EXCEPT select zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0),(0),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0)); 2 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /dictionaries/json.dict: -------------------------------------------------------------------------------- 1 | # 2 | # AFL dictionary for JSON 3 | # ----------------------- 4 | # 5 | # Just the very basics. 6 | # 7 | # Inspired by a dictionary by Jakub Wilk 8 | # 9 | 10 | "0" 11 | ",0" 12 | ":0" 13 | "0:" 14 | "-1.2e+3" 15 | 16 | "true" 17 | "false" 18 | "null" 19 | 20 | "\"\"" 21 | ",\"\"" 22 | ":\"\"" 23 | "\"\":" 24 | 25 | "{}" 26 | ",{}" 27 | ":{}" 28 | "{\"\":0}" 29 | "{{}}" 30 | 31 | "[]" 32 | ",[]" 33 | ":[]" 34 | "[0]" 35 | "[[]]" 36 | 37 | "''" 38 | "\\" 39 | "\\b" 40 | "\\f" 41 | "\\n" 42 | "\\r" 43 | "\\t" 44 | "\\u0000" 45 | "\\x00" 46 | "\\0" 47 | "\\uD800\\uDC00" 48 | "\\uDBFF\\uDFFF" 49 | 50 | "\"\":0" 51 | "//" 52 | "/**/" 53 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /qemu_mode/patches/translate-all.diff: -------------------------------------------------------------------------------- 1 | diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c 2 | index 639f0b27..21a45494 100644 3 | --- a/accel/tcg/translate-all.c 4 | +++ b/accel/tcg/translate-all.c 5 | @@ -59,6 +59,8 @@ 6 | #include "exec/log.h" 7 | #include "sysemu/cpus.h" 8 | 9 | +#include "../patches/afl-qemu-translate-inl.h" 10 | + 11 | /* #define DEBUG_TB_INVALIDATE */ 12 | /* #define DEBUG_TB_FLUSH */ 13 | /* make various TB consistency checks */ 14 | @@ -1721,6 +1723,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu, 15 | tcg_func_start(tcg_ctx); 16 | 17 | tcg_ctx->cpu = ENV_GET_CPU(env); 18 | + afl_gen_trace(pc); 19 | gen_intermediate_code(cpu, tb); 20 | tcg_ctx->cpu = NULL; 21 | 22 | -------------------------------------------------------------------------------- /python_mutators/README: -------------------------------------------------------------------------------- 1 | These are example and helper files for the AFL_PYTHON_MODULE feature. 2 | See docs/python_mutators.txt for more information 3 | 4 | Note that if you compile with python3.7 you must use python3 scripts, and if 5 | you use pyton2.7 to compile python2 scripts! 6 | 7 | 8 | example.py - this is the template you can use, the functions are there 9 | but they are empty 10 | 11 | simple-chunk-replace.py - this is a simple example where chunks are replaced 12 | 13 | common.py - this can be used for common functions and helpers. 14 | the examples do not use this though. But you can :) 15 | 16 | wrapper_afl_min.py - mutation of XML documents, loads XmlMutatorMin.py 17 | 18 | XmlMutatorMin.py - module for XML mutation 19 | -------------------------------------------------------------------------------- /unicorn_mode/samples/compcov_x64/COMPILE.md: -------------------------------------------------------------------------------- 1 | # Compiling compcov_target.c 2 | 3 | compcov_target.c was compiled without optimization, position-independent, 4 | and without standard libraries using the following command line: 5 | 6 | ``` 7 | gcc -o compcov_target.elf compcov_target.c -fPIC -O0 -nostdlib 8 | ``` 9 | 10 | The .text section from the resulting ELF binary was then extracted to create 11 | the raw binary blob that is loaded and emulated by compcov_test_harness.py: 12 | 13 | ``` 14 | objcopy -O binary --only-section=.text compcov_target.elf compcov_target.bin 15 | ``` 16 | 17 | Note that the output of this is padded with nulls for 16-byte alignment. This is 18 | important when emulating it, as NOPs will be added after the return of main() 19 | as necessary. 20 | -------------------------------------------------------------------------------- /qbdi_mode/demo-so.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // gcc -shared -o libdemo.so demo-so.c -w 4 | int target_func(char *buf, int size) { 5 | 6 | printf("buffer:%p, size:%p\n", buf, size); 7 | switch (buf[0]) { 8 | 9 | case 1: 10 | puts("222"); 11 | if (buf[1] == '\x44') { 12 | 13 | puts("null ptr deference"); 14 | *(char *)(0) = 1; 15 | 16 | } 17 | 18 | break; 19 | case 0xff: 20 | if (buf[2] == '\xff') { 21 | 22 | if (buf[1] == '\x44') { 23 | 24 | puts("crash...."); 25 | *(char *)(0xdeadbeef) = 1; 26 | 27 | } 28 | 29 | } 30 | 31 | break; 32 | default: puts("default action"); break; 33 | 34 | } 35 | 36 | return 1; 37 | 38 | } 39 | 40 | -------------------------------------------------------------------------------- /src/third_party/libradamsa/Makefile: -------------------------------------------------------------------------------- 1 | CUR_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) 2 | 3 | all: libradamsa.so 4 | 5 | libradamsa.so: libradamsa.a 6 | $(CC) -O3 -shared libradamsa.a -o libradamsa.so 7 | 8 | libradamsa.a: libradamsa.c radamsa.h 9 | @echo " ***************************************************************" 10 | @echo " * Compiling libradamsa, wait some minutes (~3 on modern CPUs) *" 11 | @echo " ***************************************************************" 12 | $(CC) -fPIC -O3 -I $(CUR_DIR) -o libradamsa.a -c libradamsa.c 13 | 14 | test: libradamsa.a libradamsa-test.c 15 | cc -O3 -I $(CUR_DIR) -o libradamsa-test libradamsa-test.c libradamsa.a 16 | ./libradamsa-test libradamsa-test.c | grep "library test passed" 17 | rm /tmp/libradamsa-*.fuzz 18 | 19 | clean: 20 | rm -f libradamsa.a libradamsa.so libradamsa-test 21 | -------------------------------------------------------------------------------- /test/test-compcov.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main(int argc, char** argv) { 7 | char *input = argv[1], *buf, buffer[20]; 8 | 9 | if (argc < 2) { 10 | ssize_t ret = read(0, buffer, sizeof(buffer) - 1); 11 | buffer[ret] = 0; 12 | input = buffer; 13 | } 14 | 15 | if (strcmp(input, "LIBTOKENCAP") == 0) 16 | printf("your string was libtokencap\n"); 17 | else if (strcmp(input, "BUGMENOT") == 0) 18 | printf("your string was bugmenot\n"); 19 | else if (strcmp(input, "BUFFEROVERFLOW") == 0) { 20 | buf = malloc(16); 21 | strcpy(buf, "TEST"); 22 | strcat(buf, input); 23 | printf("This will only crash with libdislocator: %s\n", buf); 24 | return 0; 25 | } else 26 | printf("I do not know your string\n"); 27 | 28 | return 0; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /experimental/argv_fuzzing/README.md: -------------------------------------------------------------------------------- 1 | # argvfuzz 2 | 3 | afl supports fuzzing file inputs or stdin. When source is available, 4 | `argv-fuzz-inl.h` can be used to change `main()` to build argv from stdin. 5 | 6 | `argvfuzz` tries to provide the same functionality for binaries. When loaded 7 | using `LD_PRELOAD`, it will hook the call to `__libc_start_main` and replace 8 | argv using the same logic of `argv-fuzz-inl.h`. 9 | 10 | A few conditions need to be fulfilled for this mechanism to work correctly: 11 | 12 | 1. As it relies on hooking the loader, it cannot work on static binaries. 13 | 2. If the target binary does not use the default libc's `_start` implementation 14 | (crt1.o), the hook may not run. 15 | 3. The hook will replace argv with pointers to `.data` of `argvfuzz.so`. If the 16 | target binary expects argv to be living on the stack, things may go wrong. 17 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /testcases/README.testcases: -------------------------------------------------------------------------------- 1 | ======================= 2 | AFL starting test cases 3 | ======================= 4 | 5 | (See ../docs/README for the general instruction manual.) 6 | 7 | The archives/, images/, multimedia/, and others/ subdirectories contain small, 8 | standalone files that can be used to seed afl-fuzz when testing parsers for a 9 | variety of common data formats. 10 | 11 | There is probably not much to be said about these files, except that they were 12 | optimized for size and stripped of any non-essential fluff. Some directories 13 | contain several examples that exercise various features of the underlying format. 14 | For example, there is a PNG file with and without a color profile. 15 | 16 | Additional test cases are always welcome. 17 | 18 | In addition to well-chosen starting files, many fuzzing jobs benefit from a 19 | small and concise dictionary. See ../dictionaries/README.dictionaries for more. 20 | -------------------------------------------------------------------------------- /dictionaries/png.dict: -------------------------------------------------------------------------------- 1 | # 2 | # AFL dictionary for PNG images 3 | # ----------------------------- 4 | # 5 | # Just the basic, standard-originating sections; does not include vendor 6 | # extensions. 7 | # 8 | # Created by Michal Zalewski 9 | # 10 | 11 | header_png="\x89PNG\x0d\x0a\x1a\x0a" 12 | 13 | section_IDAT="IDAT" 14 | section_IEND="IEND" 15 | section_IHDR="IHDR" 16 | section_PLTE="PLTE" 17 | section_bKGD="bKGD" 18 | section_cHRM="cHRM" 19 | section_fRAc="fRAc" 20 | section_gAMA="gAMA" 21 | section_gIFg="gIFg" 22 | section_gIFt="gIFt" 23 | section_gIFx="gIFx" 24 | section_hIST="hIST" 25 | section_iCCP="iCCP" 26 | section_iTXt="iTXt" 27 | section_oFFs="oFFs" 28 | section_pCAL="pCAL" 29 | section_pHYs="pHYs" 30 | section_sBIT="sBIT" 31 | section_sCAL="sCAL" 32 | section_sPLT="sPLT" 33 | section_sRGB="sRGB" 34 | section_sTER="sTER" 35 | section_tEXt="tEXt" 36 | section_tIME="tIME" 37 | section_tRNS="tRNS" 38 | section_zTXt="zTXt" 39 | -------------------------------------------------------------------------------- /unicorn_mode/samples/compcov_x64/compcov_target.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Sample target file to test afl-unicorn fuzzing capabilities. 3 | * This is a very trivial example that will crash pretty easily 4 | * in several different exciting ways. 5 | * 6 | * Input is assumed to come from a buffer located at DATA_ADDRESS 7 | * (0x00300000), so make sure that your Unicorn emulation of this 8 | * puts user data there. 9 | * 10 | * Written by Andrea Fioraldi 11 | */ 12 | 13 | // Magic address where mutated data will be placed 14 | #define DATA_ADDRESS 0x00300000 15 | 16 | int main(void) { 17 | unsigned int *data_buf = (unsigned int *) DATA_ADDRESS; 18 | 19 | if (((unsigned short*)data_buf)[0] == 0x0100) { 20 | unsigned char invalid_read = *(unsigned char *) 0x00000000; 21 | } else if (data_buf[1] == data_buf[2] + 0xfffe) { 22 | unsigned char invalid_read = *(unsigned char *) 0x00000000; 23 | } 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /llvm_mode/README.instrim.md: -------------------------------------------------------------------------------- 1 | # InsTrim 2 | 3 | InsTrim: Lightweight Instrumentation for Coverage-guided Fuzzing 4 | 5 | ## Introduction 6 | 7 | InsTrim uses CFG and markers to instrument just what is necessary in the 8 | binary in llvm_mode. It is about 20-25% faster but as a cost has a lower 9 | path discovery. 10 | 11 | ## Usage 12 | 13 | Set the environment variable `AFL_LLVM_INSTRIM=1` during compilation of 14 | the target. 15 | 16 | There is also an advanced mode which instruments loops in a way so that 17 | afl-fuzz can see which loop path has been selected but not being able to 18 | see how often the loop has been rerun. 19 | This again is a tradeoff for speed for less path information. 20 | To enable this mode set `AFL_LLVM_INSTRIM_LOOPHEAD=1`. 21 | 22 | ## Background 23 | 24 | The paper: [InsTrim: Lightweight Instrumentation for Coverage-guided Fuzzing] 25 | (https://www.ndss-symposium.org/wp-content/uploads/2018/07/bar2018_14_Hsu_paper.pdf) 26 | -------------------------------------------------------------------------------- /python_mutators/common.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | ''' 4 | Module containing functions shared between multiple AFL modules 5 | 6 | @author: Christian Holler (:decoder) 7 | 8 | @license: 9 | 10 | This Source Code Form is subject to the terms of the Mozilla Public 11 | License, v. 2.0. If a copy of the MPL was not distributed with this 12 | file, You can obtain one at http://mozilla.org/MPL/2.0/. 13 | 14 | @contact: choller@mozilla.com 15 | ''' 16 | 17 | from __future__ import print_function 18 | import random 19 | import os 20 | import re 21 | 22 | def randel(l): 23 | if not l: 24 | return None 25 | return l[random.randint(0,len(l)-1)] 26 | 27 | def randel_pop(l): 28 | if not l: 29 | return None 30 | return l.pop(random.randint(0,len(l)-1)) 31 | 32 | def write_exc_example(data, exc): 33 | exc_name = re.sub(r'[^a-zA-Z0-9]', '_', repr(exc)) 34 | 35 | if not os.path.exists(exc_name): 36 | with open(exc_name, 'w') as f: 37 | f.write(data) 38 | -------------------------------------------------------------------------------- /qemu_mode/unsigaction/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # american fuzzy lop - unsigaction 3 | # -------------------------------- 4 | # 5 | # Written by Andrea Fioraldi 6 | # 7 | # Copyright 2019 Andrea Fioraldi. All rights reserved. 8 | # 9 | # Licensed under the Apache License, Version 2.0 (the "License"); 10 | # you may not use this file except in compliance with the License. 11 | # You may obtain a copy of the License at: 12 | # 13 | # http://www.apache.org/licenses/LICENSE-2.0 14 | # 15 | 16 | ifndef AFL_NO_X86 17 | 18 | all: lib_i386 lib_amd64 19 | 20 | lib_i386: 21 | @$(CC) -m32 -fPIC -shared unsigaction.c -o unsigaction32.so 2>/dev/null ; if [ "$$?" = "0" ]; then echo "unsigaction32 build success"; else echo "unsigaction32 build failure (that's fine)"; fi 22 | 23 | lib_amd64: 24 | $(CC) -fPIC -shared unsigaction.c -o unsigaction64.so 25 | 26 | clean: 27 | rm -f unsigaction32.so unsigaction64.so 28 | 29 | else 30 | 31 | all: 32 | @echo "[!] Note: skipping compilation of unsigaction (AFL_NO_X86 set)." 33 | 34 | endif 35 | -------------------------------------------------------------------------------- /llvm_mode/README.neverzero.md: -------------------------------------------------------------------------------- 1 | # NeverZero counters for LLVM instrumentation 2 | 3 | ## Usage 4 | 5 | In larger, complex or reiterative programs the counters that collect the edge 6 | coverage can easily fill up and wrap around. 7 | This is not that much of an issue - unless by chance it wraps just to a value 8 | of zero when the program execution ends. 9 | In this case afl-fuzz is not able to see that the edge has been accessed and 10 | will ignore it. 11 | 12 | NeverZero prevents this behaviour. If a counter wraps, it jumps over the value 13 | 0 directly to a 1. This improves path discovery (by a very little amount) 14 | at a very little cost (one instruction per edge). 15 | 16 | (The alternative of saturated counters has been tested also and proved to be 17 | inferior in terms of path discovery.) 18 | 19 | This is implemented in afl-gcc, however for llvm_mode this is optional if 20 | the llvm version is below 9 - as there is a perfomance bug that is only fixed 21 | in version 9 and onwards. 22 | 23 | If you want to enable this for llvm < 9 then set 24 | 25 | ``` 26 | export AFL_LLVM_NOT_ZERO=1 27 | ``` 28 | -------------------------------------------------------------------------------- /src/third_party/libradamsa/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Aki Helin 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /experimental/socket_fuzzing/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # american fuzzy lop++ - socket_fuzz 3 | # ---------------------------------- 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at: 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | 12 | .PHONY: all install clean 13 | 14 | PREFIX ?= /usr/local 15 | BIN_PATH = $(PREFIX)/bin 16 | HELPER_PATH = $(PREFIX)/lib/afl 17 | 18 | CFLAGS = -fPIC -Wall -Wextra 19 | LDFLAGS = -shared -ldl 20 | 21 | all: socketfuzz32.so socketfuzz64.so 22 | 23 | socketfuzz32.so: socketfuzz.c 24 | -$(CC) -m32 $(CFLAGS) $^ $(LDFLAGS) -o $@ || echo "socketfuzz32 build failure (that's fine)" 25 | 26 | socketfuzz64.so: socketfuzz.c 27 | -$(CC) $(CFLAGS) $^ $(LDFLAGS) -o $@ 28 | 29 | install: socketfuzz32.so socketfuzz64.so 30 | install -d -m 755 $(DESTDIR)$(HELPER_PATH)/ 31 | if [ -f socketfuzz32.so ]; then set -e; install -m 755 socketfuzz32.so $(DESTDIR)$(HELPER_PATH)/; fi 32 | install -m 755 socketfuzz64.so $(DESTDIR)$(HELPER_PATH)/ 33 | 34 | clean: 35 | rm -f socketfuzz32.so socketfuzz64.so 36 | -------------------------------------------------------------------------------- /include/sharedmem.h: -------------------------------------------------------------------------------- 1 | /* 2 | american fuzzy lop++ - shared memory related header 3 | --------------------------------------------------- 4 | 5 | Originally written by Michal Zalewski 6 | 7 | Forkserver design by Jann Horn 8 | 9 | Now maintained by by Marc Heuse , 10 | Heiko Eißfeldt and 11 | Andrea Fioraldi 12 | 13 | Copyright 2016, 2017 Google Inc. All rights reserved. 14 | Copyright 2019 AFLplusplus Project. All rights reserved. 15 | 16 | Licensed under the Apache License, Version 2.0 (the "License"); 17 | you may not use this file except in compliance with the License. 18 | You may obtain a copy of the License at: 19 | 20 | http://www.apache.org/licenses/LICENSE-2.0 21 | 22 | Shared code to handle the shared memory. This is used by the fuzzer 23 | as well the other components like afl-tmin, afl-showmap, etc... 24 | 25 | */ 26 | 27 | #ifndef __AFL_SHAREDMEM_H 28 | #define __AFL_SHAREDMEM_H 29 | 30 | void setup_shm(unsigned char dumb_mode); 31 | void remove_shm(void); 32 | 33 | #endif 34 | 35 | -------------------------------------------------------------------------------- /experimental/argv_fuzzing/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # american fuzzy lop - argvfuzz 3 | # -------------------------------- 4 | # 5 | # Copyright 2019 Kjell Braden 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at: 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | 14 | .PHONY: all install clean 15 | 16 | PREFIX ?= /usr/local 17 | BIN_PATH = $(PREFIX)/bin 18 | HELPER_PATH = $(PREFIX)/lib/afl 19 | 20 | CFLAGS = -fPIC -Wall -Wextra 21 | LDFLAGS = -shared -ldl 22 | 23 | all: argvfuzz32.so argvfuzz64.so 24 | 25 | argvfuzz32.so: argvfuzz.c 26 | -$(CC) -m32 $(CFLAGS) $^ $(LDFLAGS) -o $@ || echo "argvfuzz32 build failure (that's fine)" 27 | 28 | argvfuzz64.so: argvfuzz.c 29 | -$(CC) $(CFLAGS) $^ $(LDFLAGS) -o $@ 30 | 31 | install: argvfuzz32.so argvfuzz64.so 32 | install -d -m 755 $(DESTDIR)$(HELPER_PATH)/ 33 | if [ -f argvfuzz32.so ]; then set -e; install -m 755 argvfuzz32.so $(DESTDIR)$(HELPER_PATH)/; fi 34 | install -m 755 argvfuzz64.so $(DESTDIR)$(HELPER_PATH)/ 35 | 36 | clean: 37 | rm -f argvfuzz32.so argvfuzz64.so 38 | -------------------------------------------------------------------------------- /src/README.src: -------------------------------------------------------------------------------- 1 | Quick explanation about the files here: 2 | 3 | afl-analyze.c - afl-analyze binary tool 4 | afl-as.c - afl-as binary tool 5 | afl-gotcpu.c - afl-gotcpu binary tool 6 | afl-showmap.c - afl-showmap binary tool 7 | afl-tmin.c - afl-tmin binary tool 8 | afl-fuzz.c - afl-fuzz binary tool (just main() and usage()) 9 | afl-fuzz-bitmap.c - afl-fuzz bitmap handling 10 | afl-fuzz-extras.c - afl-fuzz the *extra* function calls 11 | afl-fuzz-globals.c - afl-fuzz global variables 12 | afl-fuzz-init.c - afl-fuzz initialization 13 | afl-fuzz-misc.c - afl-fuzz misc functions 14 | afl-fuzz-one.c - afl-fuzz fuzzer_one big loop, this is where the mutation is happening 15 | afl-fuzz-python.c - afl-fuzz the python mutator extension 16 | afl-fuzz-queue.c - afl-fuzz handling the queue 17 | afl-fuzz-run.c - afl-fuzz running the target 18 | afl-fuzz-stats.c - afl-fuzz writing the statistics file 19 | afl-gcc.c - afl-gcc binary tool (deprecated) 20 | afl-common.c - common functions, used by afl-analyze, afl-fuzz, afl-showmap and afl-tmin 21 | afl-forkserver.c - forkserver implementation, used by afl-fuzz and afl-tmin 22 | afl-sharedmem.c - sharedmem implementation, used by afl-fuzz and afl-tmin 23 | -------------------------------------------------------------------------------- /include/common.h: -------------------------------------------------------------------------------- 1 | /* 2 | american fuzzy lop++ - common routines header 3 | --------------------------------------------- 4 | 5 | Originally written by Michal Zalewski 6 | 7 | Now maintained by by Marc Heuse , 8 | Heiko Eißfeldt and 9 | Andrea Fioraldi 10 | 11 | Copyright 2016, 2017 Google Inc. All rights reserved. 12 | Copyright 2019 AFLplusplus Project. All rights reserved. 13 | 14 | Licensed under the Apache License, Version 2.0 (the "License"); 15 | you may not use this file except in compliance with the License. 16 | You may obtain a copy of the License at: 17 | 18 | http://www.apache.org/licenses/LICENSE-2.0 19 | 20 | Gather some functions common to multiple executables 21 | 22 | - detect_file_args 23 | 24 | */ 25 | 26 | #ifndef __AFLCOMMON_H 27 | #define __AFLCOMMON_H 28 | #include "types.h" 29 | 30 | extern u8* target_path; /* Path to target binary */ 31 | 32 | void detect_file_args(char** argv, u8* prog_in); 33 | 34 | char** get_qemu_argv(u8* own_loc, char** argv, int argc); 35 | char** get_wine_argv(u8* own_loc, char** argv, int argc); 36 | #endif 37 | 38 | -------------------------------------------------------------------------------- /dictionaries/tiff.dict: -------------------------------------------------------------------------------- 1 | # 2 | # AFL dictionary for TIFF images 3 | # ------------------------------ 4 | # 5 | # Just the basic, standard-originating sections; does not include vendor 6 | # extensions. 7 | # 8 | # Created by Michal Zalewski 9 | # 10 | 11 | header_ii="II*\x00" 12 | header_mm="MM\x00*" 13 | 14 | section_100="\x00\x01" 15 | section_101="\x01\x01" 16 | section_102="\x02\x01" 17 | section_103="\x03\x01" 18 | section_106="\x06\x01" 19 | section_107="\x07\x01" 20 | section_10D="\x0d\x01" 21 | section_10E="\x0e\x01" 22 | section_10F="\x0f\x01" 23 | section_110="\x10\x01" 24 | section_111="\x11\x01" 25 | section_112="\x12\x01" 26 | section_115="\x15\x01" 27 | section_116="\x16\x01" 28 | section_117="\x17\x01" 29 | section_11A="\x1a\x01" 30 | section_11B="\x1b\x01" 31 | section_11C="\x1c\x01" 32 | section_11D="\x1d\x01" 33 | section_11E="\x1e\x01" 34 | section_11F="\x1f\x01" 35 | section_122="\"\x01" 36 | section_123="#\x01" 37 | section_124="$\x01" 38 | section_125="%\x01" 39 | section_128="(\x01" 40 | section_129=")\x01" 41 | section_12D="-\x01" 42 | section_131="1\x01" 43 | section_132="2\x01" 44 | section_13B=";\x01" 45 | section_13C="<\x01" 46 | section_13D="=\x01" 47 | section_13E=">\x01" 48 | section_13F="?\x01" 49 | section_140="@\x01" 50 | section_FE="\xfe\x00" 51 | section_FF="\xff\x00" 52 | -------------------------------------------------------------------------------- /test-instr.c: -------------------------------------------------------------------------------- 1 | /* 2 | american fuzzy lop - a trivial program to test the build 3 | -------------------------------------------------------- 4 | 5 | Written by Michal Zalewski 6 | 7 | Copyright 2014 Google Inc. All rights reserved. 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at: 12 | 13 | http://www.apache.org/licenses/LICENSE-2.0 14 | 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | int main(int argc, char** argv) { 22 | 23 | char buff[8]; 24 | char* buf = buff; 25 | 26 | // we support command line parameter and stdin 27 | if (argc > 1) { 28 | 29 | buf = argv[1]; 30 | printf("Input %s - ", buf); 31 | 32 | } else if (read(0, buf, sizeof(buf)) < 1) { 33 | 34 | printf("Hum?\n"); 35 | return 1; 36 | 37 | } 38 | 39 | // we support three input cases (plus a 4th if stdin is used but there is no 40 | // input) 41 | if (buf[0] == '0') 42 | printf("Looks like a zero to me!\n"); 43 | else if (buf[0] == '1') 44 | printf("Pretty sure that is a one!\n"); 45 | else 46 | printf("Neither one or zero? How quaint!\n"); 47 | 48 | return 0; 49 | 50 | } 51 | 52 | -------------------------------------------------------------------------------- /libdislocator/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # american fuzzy lop - libdislocator 3 | # ---------------------------------- 4 | # 5 | # Written by Michal Zalewski 6 | # 7 | # Copyright 2016 Google Inc. All rights reserved. 8 | # 9 | # Licensed under the Apache License, Version 2.0 (the "License"); 10 | # you may not use this file except in compliance with the License. 11 | # You may obtain a copy of the License at: 12 | # 13 | # http://www.apache.org/licenses/LICENSE-2.0 14 | # 15 | 16 | PREFIX ?= /usr/local 17 | HELPER_PATH = $(PREFIX)/lib/afl 18 | 19 | VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2) 20 | 21 | CFLAGS ?= -O3 -funroll-loops -I ../include/ 22 | CFLAGS += -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign 23 | 24 | ifdef USEHUGEPAGE 25 | CFLAGS += -DUSEHUGEPAGE 26 | endif 27 | 28 | all: libdislocator.so 29 | 30 | VPATH = .. 31 | libdislocator.so: libdislocator.so.c ../config.h 32 | $(CC) $(CFLAGS) -shared -fPIC $< -o ../$@ $(LDFLAGS) 33 | 34 | .NOTPARALLEL: clean 35 | 36 | clean: 37 | rm -f *.o *.so *~ a.out core core.[1-9][0-9]* 38 | rm -f ../libdislocator.so 39 | 40 | install: all 41 | install -m 755 -d $${DESTDIR}$(HELPER_PATH) 42 | install -m 755 ../libdislocator.so $${DESTDIR}$(HELPER_PATH) 43 | install -m 644 README.dislocator.md $${DESTDIR}$(HELPER_PATH) 44 | 45 | -------------------------------------------------------------------------------- /qemu_mode/libcompcov/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # american fuzzy lop - libcompcov 3 | # -------------------------------- 4 | # 5 | # Written by Andrea Fioraldi 6 | # 7 | # Copyright 2019 Andrea Fioraldi. All rights reserved. 8 | # 9 | # Licensed under the Apache License, Version 2.0 (the "License"); 10 | # you may not use this file except in compliance with the License. 11 | # You may obtain a copy of the License at: 12 | # 13 | # http://www.apache.org/licenses/LICENSE-2.0 14 | # 15 | 16 | PREFIX ?= /usr/local 17 | HELPER_PATH = $(PREFIX)/lib/afl 18 | 19 | VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2) 20 | 21 | CFLAGS ?= -O3 -funroll-loops -I ../../include/ 22 | CFLAGS += -Wall -Wno-unused-result -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign 23 | LDFLAGS += -ldl 24 | 25 | all: libcompcov.so 26 | 27 | libcompcov.so: libcompcov.so.c ../../config.h 28 | $(CC) $(CFLAGS) -shared -fPIC $< -o ../../$@ $(LDFLAGS) 29 | 30 | .NOTPARALLEL: clean 31 | 32 | clean: 33 | rm -f *.o *.so *~ a.out core core.[1-9][0-9]* 34 | rm -f ../../libcompcov.so compcovtest 35 | 36 | compcovtest: compcovtest.cc 37 | $(CXX) -std=c++11 $< -o $@ 38 | 39 | install: all 40 | install -m 755 ../../libcompcov.so $${DESTDIR}$(HELPER_PATH) 41 | install -m 644 README.compcov $${DESTDIR}$(HELPER_PATH) 42 | 43 | -------------------------------------------------------------------------------- /unicorn_mode/samples/simple/simple_target.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Sample target file to test afl-unicorn fuzzing capabilities. 3 | * This is a very trivial example that will crash pretty easily 4 | * in several different exciting ways. 5 | * 6 | * Input is assumed to come from a buffer located at DATA_ADDRESS 7 | * (0x00300000), so make sure that your Unicorn emulation of this 8 | * puts user data there. 9 | * 10 | * Written by Nathan Voss 11 | */ 12 | 13 | // Magic address where mutated data will be placed 14 | #define DATA_ADDRESS 0x00300000 15 | 16 | int main(void) { 17 | unsigned char *data_buf = (unsigned char *) DATA_ADDRESS; 18 | 19 | if (data_buf[20] != 0) { 20 | // Cause an 'invalid read' crash if data[0..3] == '\x01\x02\x03\x04' 21 | unsigned char invalid_read = *(unsigned char *) 0x00000000; 22 | } else if (data_buf[0] > 0x10 && data_buf[0] < 0x20 && data_buf[1] > data_buf[2]) { 23 | // Cause an 'invalid read' crash if (0x10 < data[0] < 0x20) and data[1] > data[2] 24 | unsigned char invalid_read = *(unsigned char *) 0x00000000; 25 | } else if (data_buf[9] == 0x00 && data_buf[10] != 0x00 && data_buf[11] == 0x00) { 26 | // Cause a crash if data[10] is not zero, but [9] and [11] are zero 27 | unsigned char invalid_read = *(unsigned char *) 0x00000000; 28 | } 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /llvm_mode/README.laf-intel.md: -------------------------------------------------------------------------------- 1 | # laf-intel instrumentation 2 | 3 | ## Usage 4 | 5 | By default these passes will not run when you compile programs using 6 | afl-clang-fast. Hence, you can use AFL as usual. 7 | To enable the passes you must set environment variables before you 8 | compile the target project. 9 | 10 | The following options exist: 11 | 12 | `export AFL_LLVM_LAF_SPLIT_SWITCHES=1` 13 | 14 | Enables the split-switches pass. 15 | 16 | `export AFL_LLVM_LAF_TRANSFORM_COMPARES=1` 17 | 18 | Enables the transform-compares pass (strcmp, memcmp, strncmp, 19 | strcasecmp, strncasecmp). 20 | 21 | `export AFL_LLVM_LAF_SPLIT_COMPARES=1` 22 | 23 | Enables the split-compares pass. 24 | By default it will 25 | 1. simplify operators >= (and <=) into chains of > (<) and == comparisons 26 | 2. change signed integer comparisons to a chain of sign-only comparison 27 | and unsigned comparisons 28 | 3. split all unsigned integer comparisons with bit widths of 29 | 64, 32 or 16 bits to chains of 8 bits comparisons. 30 | 31 | You can change the behaviour of the last step by setting 32 | `export AFL_LLVM_LAF_SPLIT_COMPARES_BITW=`, where 33 | bit_width may be 64, 32 or 16. 34 | 35 | A new experimental feature is splitting floating point comparisons into a 36 | series of sign, exponent and mantissa comparisons followed by splitting each 37 | of them into 8 bit comparisons when necessary. 38 | It is activated with the `AFL_LLVM_LAF_SPLIT_FLOATS` setting, available only 39 | when `AFL_LLVM_LAF_SPLIT_COMPARES` is set. 40 | -------------------------------------------------------------------------------- /experimental/argv_fuzzing/argvfuzz.c: -------------------------------------------------------------------------------- 1 | /* 2 | american fuzzy lop - LD_PRELOAD for fuzzing argv in binaries 3 | ------------------------------------------------------------ 4 | 5 | Copyright 2019 Kjell Braden 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at: 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | */ 14 | 15 | #define _GNU_SOURCE /* for RTLD_NEXT */ 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include "argv-fuzz-inl.h" 21 | 22 | int __libc_start_main(int (*main)(int, char **, char **), int argc, char **argv, 23 | void (*init)(void), void (*fini)(void), 24 | void (*rtld_fini)(void), void *stack_end) { 25 | 26 | int (*orig)(int (*main)(int, char **, char **), int argc, char **argv, 27 | void (*init)(void), void (*fini)(void), void (*rtld_fini)(void), 28 | void *stack_end); 29 | int sub_argc; 30 | char **sub_argv; 31 | 32 | (void)argc; 33 | (void)argv; 34 | 35 | orig = dlsym(RTLD_NEXT, __func__); 36 | 37 | if (!orig) { 38 | 39 | fprintf(stderr, "hook did not find original %s: %s\n", __func__, dlerror()); 40 | exit(EXIT_FAILURE); 41 | 42 | } 43 | 44 | sub_argv = afl_init_argv(&sub_argc); 45 | 46 | return orig(main, sub_argc, sub_argv, init, fini, rtld_fini, stack_end); 47 | 48 | } 49 | 50 | -------------------------------------------------------------------------------- /unicorn_mode/samples/simple/COMPILE.md: -------------------------------------------------------------------------------- 1 | # Compiling simple_target.c 2 | 3 | You shouldn't need to compile simple_target.c since a MIPS binary version is 4 | pre-built and shipped with afl-unicorn. This file documents how the binary 5 | was built in case you want to rebuild it or recompile it for any reason. 6 | 7 | The pre-built binary (simple_target.bin) was built by cross-compiling 8 | simple_target.c for MIPS using the mips-linux-gnu-gcc package on an Ubuntu 9 | 16.04 LTS system. This cross compiler (and associated binutils) was installed 10 | from apt-get packages: 11 | 12 | ``` 13 | sudo apt-get install gcc-mips-linux-gnu 14 | ``` 15 | 16 | simple_target.c was compiled without optimization, position-independent, 17 | and without standard libraries using the following command line: 18 | 19 | ``` 20 | mips-linux-gnu-gcc -o simple_target.elf simple_target.c -fPIC -O0 -nostdlib 21 | ``` 22 | 23 | The .text section from the resulting ELF binary was then extracted to create 24 | the raw binary blob that is loaded and emulated by simple_test_harness.py: 25 | 26 | ``` 27 | mips-linux-gnu-objcopy -O binary --only-section=.text simple_target.elf simple_target.bin 28 | ``` 29 | 30 | In summary, to recreate simple_taget.bin execute the following: 31 | 32 | ``` 33 | mips-linux-gnu-gcc -o simple_target.elf simple_target.c -fPIC -O0 -nostdlib 34 | && mips-linux-gnu-objcopy -O binary --only-section=.text simple_target.elf simple_target.bin 35 | && rm simple_target.elf 36 | ``` 37 | 38 | Note that the output of this is padded with nulls for 16-byte alignment. This is 39 | important when emulating it, as NOPs will be added after the return of main() 40 | as necessary. 41 | -------------------------------------------------------------------------------- /docs/PATCHES: -------------------------------------------------------------------------------- 1 | The following patches from https://github.com/vanhauser-thc/afl-patches 2 | have been installed or not installed: 3 | 4 | 5 | INSTALLED 6 | ========= 7 | afl-llvm-fix.diff by kcwu(at)csie(dot)org 8 | afl-sort-all_uniq-fix.diff by legarrec(dot)vincent(at)gmail(dot)com 9 | laf-intel.diff by heiko(dot)eissfeldt(at)hexco(dot)de 10 | afl-llvm-optimize.diff by mh(at)mh-sec(dot)de 11 | afl-fuzz-tmpdir.diff by mh(at)mh-sec(dot)de 12 | afl-fuzz-79x24.diff by heiko(dot)eissfeldt(at)hexco(dot)de 13 | afl-fuzz-fileextensionopt.diff tbd 14 | afl-as-AFL_INST_RATIO.diff by legarrec(dot)vincent(at)gmail(dot)com 15 | afl-qemu-ppc64.diff by william(dot)barsse(at)airbus(dot)com 16 | afl-qemu-optimize-entrypoint.diff by mh(at)mh-sec(dot)de 17 | afl-qemu-speed.diff by abiondo on github 18 | afl-qemu-optimize-map.diff by mh(at)mh-sec(dot)de 19 | 20 | + Custom mutator (native library) (by kyakdan) 21 | + unicorn_mode (modernized and updated by domenukk) 22 | + instrim (https://github.com/csienslab/instrim) was integrated 23 | + MOpt (github.com/puppet-meteor/MOpt-AFL) was imported 24 | + AFLfast additions (github.com/mboehme/aflfast) were incorporated. 25 | + Qemu 3.1 upgrade with enhancement patches (github.com/andreafioraldi/afl) 26 | + Python mutator modules support (github.com/choller/afl) 27 | + Whitelisting in LLVM mode (github.com/choller/afl) 28 | + forkserver patch for afl-tmin (github.com/nccgroup/TriforceAFL) 29 | 30 | 31 | NOT INSTALLED 32 | ============= 33 | afl-fuzz-context_sensitive.diff - changes too much of the behaviour 34 | afl-tmpfs.diff - same as afl-fuzz-tmpdir.diff but more complex 35 | afl-cmin-reduce-dataset.diff - unsure of the impact 36 | afl-llvm-fix2.diff - not needed with the other patches 37 | 38 | -------------------------------------------------------------------------------- /libtokencap/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # american fuzzy lop - libtokencap 3 | # -------------------------------- 4 | # 5 | # Written by Michal Zalewski 6 | # 7 | # Copyright 2016 Google Inc. All rights reserved. 8 | # 9 | # Licensed under the Apache License, Version 2.0 (the "License"); 10 | # you may not use this file except in compliance with the License. 11 | # You may obtain a copy of the License at: 12 | # 13 | # http://www.apache.org/licenses/LICENSE-2.0 14 | # 15 | 16 | PREFIX ?= /usr/local 17 | HELPER_PATH = $(PREFIX)/lib/afl 18 | 19 | VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2) 20 | 21 | CFLAGS ?= -O3 -funroll-loops -I ../include/ 22 | CFLAGS += -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign 23 | 24 | ifeq "$(shell uname)" "Linux" 25 | TARGETS = libtokencap.so 26 | LDFLAGS += -ldl 27 | endif 28 | ifeq "$(shell uname)" "Darwin" 29 | TARGETS = libtokencap.so 30 | LDFLAGS += -ldl 31 | endif 32 | ifeq "$(shell uname)" "FreeBSD" 33 | TARGETS = libtokencap.so 34 | endif 35 | ifeq "$(shell uname)" "OpenBSD" 36 | TARGETS = libtokencap.so 37 | endif 38 | ifeq "$(shell uname)" "NetBSD" 39 | TARGETS = libtokencap.so 40 | endif 41 | ifeq "$(shell uname)" "DragonFly" 42 | TARGETS = libtokencap.so 43 | LDFLAGS += -ldl 44 | endif 45 | all: $(TARGETS) 46 | 47 | VPATH = .. 48 | libtokencap.so: libtokencap.so.c ../config.h 49 | $(CC) $(CFLAGS) -shared -fPIC $< -o ../$@ $(LDFLAGS) 50 | 51 | .NOTPARALLEL: clean 52 | 53 | clean: 54 | rm -f *.o *.so *~ a.out core core.[1-9][0-9]* 55 | rm -f ../libtokencap.so 56 | 57 | install: all 58 | install -m 755 -d $${DESTDIR}$(HELPER_PATH) 59 | install -m 755 ../libtokencap.so $${DESTDIR}$(HELPER_PATH) 60 | install -m 644 README.tokencap.md $${DESTDIR}$(HELPER_PATH) 61 | 62 | -------------------------------------------------------------------------------- /qemu_mode/libcompcov/README.md: -------------------------------------------------------------------------------- 1 | # strcmp() / memcmp() CompareCoverage library for afl++ QEMU 2 | 3 | Written by Andrea Fioraldi 4 | 5 | This Linux-only companion library allows you to instrument `strcmp()`, `memcmp()`, 6 | and related functions to log the CompareCoverage of these libcalls. 7 | 8 | Use this with caution. While this can speedup a lot the bypass of hard 9 | branch conditions it can also waste a lot of time and take up unnecessary space 10 | in the shared memory when logging the coverage related to functions that 11 | doesn't process input-related data. 12 | 13 | To use the library, you *need* to make sure that your fuzzing target is linked 14 | dynamically and make use of strcmp(), memcmp(), and related functions. 15 | For optimized binaries this is an issue, those functions are often inlined 16 | and this module is not capable to log the coverage in this case. 17 | 18 | If you have the source code of the fuzzing target you should nto use this 19 | library and QEMU but build it with afl-clang-fast and the laf-intel options. 20 | 21 | To use this library make sure to preload it with AFL_PRELOAD. 22 | 23 | ``` 24 | export AFL_PRELOAD=/path/to/libcompcov.so 25 | export AFL_COMPCOV_LEVEL=1 26 | 27 | afl-fuzz -Q -i input -o output -- 28 | ``` 29 | 30 | The AFL_COMPCOV_LEVEL tells to QEMU and libcompcov how to log comaprisons. 31 | Level 1 logs just comparison with immediates / read-only memory and level 2 32 | logs all the comparisons. 33 | 34 | The library make use of https://github.com/ouadev/proc_maps_parser and so it is 35 | Linux specific. However this is not a strict dependency, other UNIX operating 36 | systems can be supported simply replacing the code related to the 37 | /proc/self/maps parsing. 38 | -------------------------------------------------------------------------------- /qemu_mode/patches/i386-translate.diff: -------------------------------------------------------------------------------- 1 | diff --git a/target/i386/translate.c b/target/i386/translate.c 2 | index 0dd5fbe4..a23da128 100644 3 | --- a/target/i386/translate.c 4 | +++ b/target/i386/translate.c 5 | @@ -32,6 +32,8 @@ 6 | #include "trace-tcg.h" 7 | #include "exec/log.h" 8 | 9 | +#include "../patches/afl-qemu-cpu-translate-inl.h" 10 | + 11 | #define PREFIX_REPZ 0x01 12 | #define PREFIX_REPNZ 0x02 13 | #define PREFIX_LOCK 0x04 14 | @@ -1343,9 +1345,11 @@ static void gen_op(DisasContext *s1, int op, TCGMemOp ot, int d) 15 | tcg_gen_atomic_fetch_add_tl(s1->cc_srcT, s1->A0, s1->T0, 16 | s1->mem_index, ot | MO_LE); 17 | tcg_gen_sub_tl(s1->T0, s1->cc_srcT, s1->T1); 18 | + afl_gen_compcov(s1->pc, s1->cc_srcT, s1->T1, ot, d == OR_EAX); 19 | } else { 20 | tcg_gen_mov_tl(s1->cc_srcT, s1->T0); 21 | tcg_gen_sub_tl(s1->T0, s1->T0, s1->T1); 22 | + afl_gen_compcov(s1->pc, s1->T0, s1->T1, ot, d == OR_EAX); 23 | gen_op_st_rm_T0_A0(s1, ot, d); 24 | } 25 | gen_op_update2_cc(s1); 26 | @@ -1389,6 +1393,7 @@ static void gen_op(DisasContext *s1, int op, TCGMemOp ot, int d) 27 | tcg_gen_mov_tl(cpu_cc_src, s1->T1); 28 | tcg_gen_mov_tl(s1->cc_srcT, s1->T0); 29 | tcg_gen_sub_tl(cpu_cc_dst, s1->T0, s1->T1); 30 | + afl_gen_compcov(s1->pc, s1->T0, s1->T1, ot, d == OR_EAX); 31 | set_cc_op(s1, CC_OP_SUBB + ot); 32 | break; 33 | } 34 | @@ -4508,6 +4513,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu) 35 | rex_w = -1; 36 | rex_r = 0; 37 | 38 | + AFL_QEMU_TARGET_i386_SNIPPET 39 | + 40 | next_byte: 41 | b = x86_ldub_code(env, s); 42 | /* Collect prefixes. */ 43 | -------------------------------------------------------------------------------- /unicorn_mode/patches/afl-unicorn-common.h: -------------------------------------------------------------------------------- 1 | /* 2 | american fuzzy lop++ - unicorn instrumentation 3 | ---------------------------------------------- 4 | 5 | Originally written by Andrew Griffiths and 6 | Michal Zalewski 7 | 8 | Adapted for afl-unicorn by Dominik Maier 9 | 10 | CompareCoverage and NeverZero counters by Andrea Fioraldi 11 | 12 | 13 | Copyright 2015, 2016, 2017 Google Inc. All rights reserved. 14 | Copyright 2019 AFLplusplus Project. All rights reserved. 15 | 16 | Licensed under the Apache License, Version 2.0 (the "License"); 17 | you may not use this file except in compliance with the License. 18 | You may obtain a copy of the License at: 19 | 20 | http://www.apache.org/licenses/LICENSE-2.0 21 | 22 | This code is a shim patched into the separately-distributed source 23 | code of Unicorn 1.0.1. It leverages the built-in QEMU tracing functionality 24 | to implement AFL-style instrumentation and to take care of the remaining 25 | parts of the AFL fork server logic. 26 | 27 | The resulting libunicorn binary is essentially a standalone instrumentation 28 | tool; for an example of how to leverage it for other purposes, you can 29 | have a look at afl-showmap.c. 30 | 31 | */ 32 | 33 | #include "../../config.h" 34 | 35 | /* NeverZero */ 36 | 37 | #if (defined(__x86_64__) || defined(__i386__)) && defined(AFL_QEMU_NOT_ZERO) 38 | #define INC_AFL_AREA(loc) \ 39 | asm volatile( \ 40 | "incb (%0, %1, 1)\n" \ 41 | "adcb $0, (%0, %1, 1)\n" \ 42 | : /* no out */ \ 43 | : "r"(afl_area_ptr), "r"(loc) \ 44 | : "memory", "eax") 45 | #else 46 | #define INC_AFL_AREA(loc) afl_area_ptr[loc]++ 47 | #endif 48 | 49 | -------------------------------------------------------------------------------- /qemu_mode/patches/cpu-exec.diff: -------------------------------------------------------------------------------- 1 | diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c 2 | index 870027d4..841ba557 100644 3 | --- a/accel/tcg/cpu-exec.c 4 | +++ b/accel/tcg/cpu-exec.c 5 | @@ -36,6 +36,8 @@ 6 | #include "sysemu/cpus.h" 7 | #include "sysemu/replay.h" 8 | 9 | +#include "../patches/afl-qemu-cpu-inl.h" 10 | + 11 | /* -icount align implementation. */ 12 | 13 | typedef struct SyncClocks { 14 | @@ -144,6 +146,8 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb) 15 | int tb_exit; 16 | uint8_t *tb_ptr = itb->tc.ptr; 17 | 18 | + AFL_QEMU_CPU_SNIPPET2; 19 | + 20 | qemu_log_mask_and_addr(CPU_LOG_EXEC, itb->pc, 21 | "Trace %d: %p [" 22 | TARGET_FMT_lx "/" TARGET_FMT_lx "/%#x] %s\n", 23 | @@ -397,11 +401,13 @@ static inline TranslationBlock *tb_find(CPUState *cpu, 24 | TranslationBlock *tb; 25 | target_ulong cs_base, pc; 26 | uint32_t flags; 27 | + bool was_translated = false, was_chained = false; 28 | 29 | tb = tb_lookup__cpu_state(cpu, &pc, &cs_base, &flags, cf_mask); 30 | if (tb == NULL) { 31 | mmap_lock(); 32 | tb = tb_gen_code(cpu, pc, cs_base, flags, cf_mask); 33 | + was_translated = true; 34 | mmap_unlock(); 35 | /* We add the TB in the virtual pc hash table for the fast lookup */ 36 | atomic_set(&cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)], tb); 37 | @@ -418,6 +424,10 @@ static inline TranslationBlock *tb_find(CPUState *cpu, 38 | /* See if we can patch the calling TB. */ 39 | if (last_tb) { 40 | tb_add_jump(last_tb, tb_exit, tb); 41 | + was_chained = true; 42 | + } 43 | + if (was_translated || was_chained) { 44 | + afl_request_tsl(pc, cs_base, flags, cf_mask, was_chained ? last_tb : NULL, tb_exit); 45 | } 46 | return tb; 47 | } 48 | -------------------------------------------------------------------------------- /python_mutators/simple-chunk-replace.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | ''' 4 | Simple Chunk Cross-Over Replacement Module for AFLFuzz 5 | 6 | @author: Christian Holler (:decoder) 7 | 8 | @license: 9 | 10 | This Source Code Form is subject to the terms of the Mozilla Public 11 | License, v. 2.0. If a copy of the MPL was not distributed with this 12 | file, You can obtain one at http://mozilla.org/MPL/2.0/. 13 | 14 | @contact: choller@mozilla.com 15 | ''' 16 | 17 | import random 18 | 19 | def init(seed): 20 | ''' 21 | Called once when AFLFuzz starts up. Used to seed our RNG. 22 | 23 | @type seed: int 24 | @param seed: A 32-bit random value 25 | ''' 26 | # Seed our RNG 27 | random.seed(seed) 28 | return 0 29 | 30 | def fuzz(buf, add_buf): 31 | ''' 32 | Called per fuzzing iteration. 33 | 34 | @type buf: bytearray 35 | @param buf: The buffer that should be mutated. 36 | 37 | @type add_buf: bytearray 38 | @param add_buf: A second buffer that can be used as mutation source. 39 | 40 | @rtype: bytearray 41 | @return: A new bytearray containing the mutated data 42 | ''' 43 | # Make a copy of our input buffer for returning 44 | ret = bytearray(buf) 45 | 46 | # Take a random fragment length between 2 and 32 (or less if add_buf is shorter) 47 | fragment_len = random.randint(1, min(len(add_buf), 32)) 48 | 49 | # Determine a random source index where to take the data chunk from 50 | rand_src_idx = random.randint(0, len(add_buf) - fragment_len) 51 | 52 | # Determine a random destination index where to put the data chunk 53 | rand_dst_idx = random.randint(0, len(buf)) 54 | 55 | # Make the chunk replacement 56 | ret[rand_dst_idx:rand_dst_idx + fragment_len] = add_buf[rand_src_idx:rand_src_idx + fragment_len] 57 | 58 | # Return data 59 | return ret 60 | -------------------------------------------------------------------------------- /dictionaries/xml.dict: -------------------------------------------------------------------------------- 1 | # 2 | # AFL dictionary for XML 3 | # ---------------------- 4 | # 5 | # Several basic syntax elements and attributes, modeled on libxml2. 6 | # 7 | # Created by Michal Zalewski 8 | # 9 | 10 | attr_encoding=" encoding=\"1\"" 11 | attr_generic=" a=\"1\"" 12 | attr_href=" href=\"1\"" 13 | attr_standalone=" standalone=\"no\"" 14 | attr_version=" version=\"1\"" 15 | attr_xml_base=" xml:base=\"1\"" 16 | attr_xml_id=" xml:id=\"1\"" 17 | attr_xml_lang=" xml:lang=\"1\"" 18 | attr_xml_space=" xml:space=\"1\"" 19 | attr_xmlns=" xmlns=\"1\"" 20 | 21 | entity_builtin="<" 22 | entity_decimal="" 23 | entity_external="&a;" 24 | entity_hex="" 25 | 26 | string_any="ANY" 27 | string_brackets="[]" 28 | string_cdata="CDATA" 29 | string_col_fallback=":fallback" 30 | string_col_generic=":a" 31 | string_col_include=":include" 32 | string_dashes="--" 33 | string_empty="EMPTY" 34 | string_empty_dblquotes="\"\"" 35 | string_empty_quotes="''" 36 | string_entities="ENTITIES" 37 | string_entity="ENTITY" 38 | string_fixed="#FIXED" 39 | string_id="ID" 40 | string_idref="IDREF" 41 | string_idrefs="IDREFS" 42 | string_implied="#IMPLIED" 43 | string_nmtoken="NMTOKEN" 44 | string_nmtokens="NMTOKENS" 45 | string_notation="NOTATION" 46 | string_parentheses="()" 47 | string_pcdata="#PCDATA" 48 | string_percent="%a" 49 | string_public="PUBLIC" 50 | string_required="#REQUIRED" 51 | string_schema=":schema" 52 | string_system="SYSTEM" 53 | string_ucs4="UCS-4" 54 | string_utf16="UTF-16" 55 | string_utf8="UTF-8" 56 | string_xmlns="xmlns:" 57 | 58 | tag_attlist="" 61 | tag_doctype="" 68 | tag_open_close="" 69 | tag_open_exclamation="" 72 | tag_xml_q="" 73 | -------------------------------------------------------------------------------- /experimental/clang_asm_normalize/as: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # american fuzzy lop - clang assembly normalizer 4 | # ---------------------------------------------- 5 | # 6 | # Written by Michal Zalewski 7 | # The idea for this wrapper comes from Ryan Govostes. 8 | # 9 | # Copyright 2013, 2014 Google Inc. All rights reserved. 10 | # 11 | # Licensed under the Apache License, Version 2.0 (the "License"); 12 | # you may not use this file except in compliance with the License. 13 | # You may obtain a copy of the License at: 14 | # 15 | # http://www.apache.org/licenses/LICENSE-2.0 16 | # 17 | # This 'as' wrapper should allow you to instrument unruly, hand-written 18 | # assembly with afl-as. 19 | # 20 | # Usage: 21 | # 22 | # export AFL_REAL_PATH=/path/to/directory/with/afl-as/ 23 | # AFL_PATH=/path/to/this/directory/ make clean all 24 | 25 | if [ "$#" -lt "2" ]; then 26 | echo "[-] Error: this utility can't be called directly." 1>&2 27 | exit 1 28 | fi 29 | 30 | if [ "$AFL_REAL_PATH" = "" ]; then 31 | echo "[-] Error: AFL_REAL_PATH not set!" 1>&2 32 | exit 1 33 | fi 34 | 35 | if [ ! -x "$AFL_REAL_PATH/afl-as" ]; then 36 | echo "[-] Error: AFL_REAL_PATH does not contain the 'afl-as' binary." 1>&2 37 | exit 1 38 | fi 39 | 40 | unset __AFL_AS_CMDLINE __AFL_FNAME 41 | 42 | while [ ! "$#" = "0" ]; do 43 | 44 | if [ "$#" = "1" ]; then 45 | __AFL_FNAME="$1" 46 | else 47 | __AFL_AS_CMDLINE="${__AFL_AS_CMDLINE} $1" 48 | fi 49 | 50 | shift 51 | 52 | done 53 | 54 | test "$TMPDIR" = "" && TMPDIR=/tmp 55 | 56 | TMPFILE=`mktemp $TMPDIR/.afl-XXXXXXXXXX.s` 57 | 58 | test "$TMPFILE" = "" && exit 1 59 | 60 | clang -cc1as -filetype asm -output-asm-variant 0 "${__AFL_FNAME}" >"$TMPFILE" 61 | 62 | ERR="$?" 63 | 64 | if [ ! "$ERR" = "0" ]; then 65 | rm -f "$TMPFILE" 66 | exit $ERR 67 | fi 68 | 69 | "$AFL_REAL_PATH/afl-as" ${__AFL_AS_CMDLINE} "$TMPFILE" 70 | 71 | ERR="$?" 72 | 73 | rm -f "$TMPFILE" 74 | 75 | exit "$ERR" 76 | -------------------------------------------------------------------------------- /include/forkserver.h: -------------------------------------------------------------------------------- 1 | /* 2 | american fuzzy lop++ - forkserver header 3 | ---------------------------------------- 4 | 5 | Originally written by Michal Zalewski 6 | 7 | Forkserver design by Jann Horn 8 | 9 | Now maintained by by Marc Heuse , 10 | Heiko Eißfeldt and 11 | Andrea Fioraldi 12 | 13 | Copyright 2016, 2017 Google Inc. All rights reserved. 14 | Copyright 2019 AFLplusplus Project. All rights reserved. 15 | 16 | Licensed under the Apache License, Version 2.0 (the "License"); 17 | you may not use this file except in compliance with the License. 18 | You may obtain a copy of the License at: 19 | 20 | http://www.apache.org/licenses/LICENSE-2.0 21 | 22 | Shared code that implements a forkserver. This is used by the fuzzer 23 | as well the other components like afl-tmin. 24 | 25 | */ 26 | 27 | #ifndef __AFL_FORKSERVER_H 28 | #define __AFL_FORKSERVER_H 29 | 30 | void handle_timeout(int sig); 31 | void init_forkserver(char **argv); 32 | 33 | #ifdef __APPLE__ 34 | #define MSG_FORK_ON_APPLE \ 35 | " - On MacOS X, the semantics of fork() syscalls are non-standard and " \ 36 | "may\n" \ 37 | " break afl-fuzz performance optimizations when running " \ 38 | "platform-specific\n" \ 39 | " targets. To fix this, set AFL_NO_FORKSRV=1 in the environment.\n\n" 40 | #else 41 | #define MSG_FORK_ON_APPLE "" 42 | #endif 43 | 44 | #ifdef RLIMIT_AS 45 | #define MSG_ULIMIT_USAGE " ( ulimit -Sv $[%llu << 10];" 46 | #else 47 | #define MSG_ULIMIT_USAGE " ( ulimit -Sd $[%llu << 10];" 48 | #endif /* ^RLIMIT_AS */ 49 | 50 | #endif 51 | 52 | -------------------------------------------------------------------------------- /experimental/README.experiments: -------------------------------------------------------------------------------- 1 | Here's a quick overview of the stuff you can find in this directory: 2 | 3 | - argv_fuzzing - a simple wrapper to allow cmdline to be fuzzed 4 | (e.g., to test setuid programs). 5 | 6 | - asan_cgroups - a contributed script to simplify fuzzing ASAN 7 | binaries with robust memory limits on Linux. 8 | 9 | - bash_shellshock - a simple hack used to find a bunch of 10 | post-Shellshock bugs in bash. 11 | 12 | - canvas_harness - a test harness used to find browser bugs with a 13 | corpus generated using simple image parsing 14 | binaries & afl-fuzz. 15 | 16 | - clang_asm_normalize - a script that makes it easy to instrument 17 | hand-written assembly, provided that you have clang. 18 | 19 | - crash_triage - a very rudimentary example of how to annotate crashes 20 | with additional gdb metadata. 21 | 22 | - distributed_fuzzing - a sample script for synchronizing fuzzer instances 23 | across multiple machines (see parallel_fuzzing.txt). 24 | 25 | - libpng_no_checksum - a sample patch for removing CRC checks in libpng. 26 | 27 | - persistent_demo - an example of how to use the LLVM persistent process 28 | mode to speed up certain fuzzing jobs. 29 | 30 | - post_library - an example of how to build postprocessors for AFL. 31 | 32 | Note that the minimize_corpus.sh tool has graduated from the experimental/ 33 | directory and is now available as ../afl-cmin. The LLVM mode has likewise 34 | graduated to ../llvm_mode/*. 35 | 36 | Most of the tools in this directory are meant chiefly as examples that need to 37 | be tweaked for your specific needs. They come with some basic documentation, 38 | but are not necessarily production-grade. 39 | -------------------------------------------------------------------------------- /qemu_mode/libcompcov/compcovtest.cc: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////// 2 | // 3 | // Author: Mateusz Jurczyk (mjurczyk@google.com) 4 | // 5 | // Copyright 2019 Google LLC 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // https://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | 20 | // solution: echo -ne 'The quick brown fox jumps over the lazy 21 | // dog\xbe\xba\xfe\xca\xbe\xba\xfe\xca\xde\xc0\xad\xde\xef\xbe' | ./compcovtest 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | int main() { 29 | 30 | char buffer[44] = {/* zero padding */}; 31 | fread(buffer, 1, sizeof(buffer) - 1, stdin); 32 | 33 | if (memcmp(&buffer[0], "The quick brown fox ", 20) != 0 || 34 | strncmp(&buffer[20], "jumps over ", 11) != 0 || 35 | strcmp(&buffer[31], "the lazy dog") != 0) { 36 | 37 | return 1; 38 | 39 | } 40 | 41 | uint64_t x = 0; 42 | fread(&x, sizeof(x), 1, stdin); 43 | if (x != 0xCAFEBABECAFEBABE) { return 2; } 44 | 45 | uint32_t y = 0; 46 | fread(&y, sizeof(y), 1, stdin); 47 | if (y != 0xDEADC0DE) { return 3; } 48 | 49 | uint16_t z = 0; 50 | fread(&z, sizeof(z), 1, stdin); 51 | 52 | switch (z) { 53 | 54 | case 0xBEEF: break; 55 | 56 | default: return 4; 57 | 58 | } 59 | 60 | printf("Puzzle solved, congrats!\n"); 61 | abort(); 62 | return 0; 63 | 64 | } 65 | 66 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /docs/custom_mutator.txt: -------------------------------------------------------------------------------- 1 | ================================================== 2 | Adding custom mutators to AFL using 3 | ================================================== 4 | This file describes how you can implement custom mutations to be used in AFL. 5 | 6 | Implemented by Khaled Yakdan from Code Intelligence 7 | 8 | 9 | 1) Description 10 | -------------- 11 | 12 | Custom mutator libraries can be passed to afl-fuzz to perform custom mutations 13 | on test cases beyond those available in AFL - for example, to enable structure-aware 14 | fuzzing by using libraries that perform mutations according to a given grammar. 15 | 16 | The custom mutator library is passed to afl-fuzz via the AFL_CUSTOM_MUTATOR_LIBRARY 17 | environment variable. The library must export the afl_custom_mutator() function and 18 | must be compiled as a shared object. For example: 19 | $CC -shared -Wall -O3 .c -o .so 20 | 21 | Note: unless AFL_CUSTOM_MUTATOR_ONLY is set, its state mutator like any others, 22 | so it will be used for some test cases, and other mutators for others. 23 | 24 | Only if AFL_CUSTOM_MUTATOR_ONLY is set the afl_custom_mutator() function will 25 | be called every time it needs to mutate test case! 26 | 27 | For some cases, the format of the mutated data returned from 28 | the custom mutator is not suitable to directly execute the target with this input. 29 | For example, when using libprotobuf-mutator, the data returned is in a protobuf 30 | format which corresponds to a given grammar. In order to execute the target, 31 | the protobuf data must be converted to the plain-text format expected by the target. 32 | In such scenarios, the user can define the afl_pre_save_handler() function. This function 33 | is then transforms the data into the format expected by the API before executing the target. 34 | afl_pre_save_handler is optional and does not have to be implemented if its functionality 35 | is not needed. 36 | 37 | 2) Example 38 | ---------- 39 | A simple example is provided in ../custom_mutators/ 40 | -------------------------------------------------------------------------------- /testcases/archives/common/tar/small_archive.tar: -------------------------------------------------------------------------------- 1 | limerick0000640000076400007640000000027712427053460012465 0ustar lcamtuflcamtufThere was a young man from Japan 2 | Whose limericks never would scan. 3 | When asked why that was, 4 | He replied "It's because 5 | I always try to cram as many words into the last line as I possibly can." 6 | -------------------------------------------------------------------------------- /src/third_party/libradamsa/libradamsa-test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | size_t filesize(char* filename) { 13 | struct stat st; 14 | stat(filename, &st); 15 | return st.st_size; 16 | } 17 | 18 | #define BUFSIZE 1024*1024 19 | 20 | void fail(char *why) { 21 | printf("fail: %s\n", why); 22 | exit(1); 23 | } 24 | 25 | void write_output(char *data, size_t len, int num) { 26 | char path[32]; 27 | int fd; 28 | int wrote; 29 | sprintf(path, "/tmp/libradamsa-%d.fuzz", num); 30 | fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); 31 | printf("Opened %s -> %d\n", path, fd); 32 | if (fd < 0) { 33 | fail("failed to open output file"); 34 | } 35 | wrote = write(fd, data, len); 36 | printf("wrote %d of %zu bytes\n", wrote, len); 37 | if (wrote != len) { 38 | fail("failed to write all of output at once"); 39 | } 40 | close(fd); 41 | printf("Wrote %zu bytes to %s\n", len, path); 42 | } 43 | 44 | int main(int nargs, char **argv) { 45 | char *spath = argv[1]; 46 | int fd = open(spath, O_RDONLY, 0); 47 | size_t len; 48 | char *input; 49 | char *output; 50 | int seed = 0; 51 | if (fd < 0) { 52 | fail("cannot open input file"); 53 | } 54 | len = filesize(spath); 55 | input = malloc(len); 56 | output = malloc(BUFSIZE); 57 | if (!input || !output) { 58 | fail("failed to allocate buffers\n"); 59 | } 60 | init(); 61 | if (len != read(fd, input, len)) { 62 | fail("failed to read the entire sample at once"); 63 | } 64 | while(seed++ < 100) { 65 | size_t n; 66 | n = radamsa((uint8_t *) input, len, (uint8_t *) output, BUFSIZE, seed); 67 | write_output(output, n, seed); 68 | printf("Fuzzed %zu -> %zu bytes\n", len, n); 69 | } 70 | printf("library test passed\n"); 71 | free(output); 72 | free(input); 73 | return 0; 74 | } 75 | 76 | -------------------------------------------------------------------------------- /experimental/bash_shellshock/shellshock-fuzz.diff: -------------------------------------------------------------------------------- 1 | This patch shows a very simple way to find post-Shellshock bugs in bash, as 2 | discussed here: 3 | 4 | http://lcamtuf.blogspot.com/2014/10/bash-bug-how-we-finally-cracked.html 5 | 6 | In essence, it shows a way to fuzz environmental variables. Instructions: 7 | 8 | 1) Download bash 4.3, apply this patch, compile with: 9 | 10 | CC=/path/to/afl-gcc ./configure 11 | make clean all 12 | 13 | Note that the harness puts the fuzzed output in $TEST_VARIABLE. With 14 | Florian's Shellshock patch (bash43-028), this is no longer passed down 15 | to the parser. 16 | 17 | 2) Create and cd to an empty directory, put the compiled bash binary in 18 | there, and run these commands: 19 | 20 | mkdir in_dir 21 | echo -n '() { a() { a; }; : >b; }' >in_dir/script.txt 22 | 23 | 3) Run the fuzzer with: 24 | 25 | /path/to/afl-fuzz -d -i in_dir -o out_dir ./bash -c : 26 | 27 | The -d parameter is advisable only if the tested shell is fairly slow 28 | or if you are in a hurry; will cover more ground faster, but 29 | less systematically. 30 | 31 | 4) Watch for crashes in out_dir/crashes/. Also watch for any new files 32 | created in cwd if you're interested in non-crash RCEs (files will be 33 | created whenever the shell executes "foo>bar" or something like 34 | that). You can correlate their creation date with new entries in 35 | out_dir/queue/. 36 | 37 | You can also modify the bash binary to directly check for more subtle 38 | fault conditions, or use the synthesized entries in out_dir/queue/ 39 | as a seed for other, possibly slower or more involved testing regimes. 40 | 41 | Expect several hours to get decent coverage. 42 | 43 | --- bash-4.3/shell.c.orig 2014-01-14 14:04:32.000000000 +0100 44 | +++ bash-4.3/shell.c 2015-04-30 05:56:46.000000000 +0200 45 | @@ -371,6 +371,14 @@ 46 | env = environ; 47 | #endif /* __OPENNT */ 48 | 49 | + { 50 | + 51 | + static char val[1024 * 16]; 52 | + read(0, val, sizeof(val) - 1); 53 | + setenv("TEST_VARIABLE", val, 1); 54 | + 55 | + } 56 | + 57 | USE_VAR(argc); 58 | USE_VAR(argv); 59 | USE_VAR(env); 60 | -------------------------------------------------------------------------------- /qemu_mode/patches/i386-fpu_helper.diff: -------------------------------------------------------------------------------- 1 | diff --git a/target/i386/fpu_helper.c b/target/i386/fpu_helper.c 2 | index ea5a0c48..89901315 100644 3 | --- a/target/i386/fpu_helper.c 4 | +++ b/target/i386/fpu_helper.c 5 | @@ -384,10 +384,16 @@ void helper_fxchg_ST0_STN(CPUX86State *env, int st_index) 6 | 7 | static const int fcom_ccval[4] = {0x0100, 0x4000, 0x0000, 0x4500}; 8 | 9 | +#include "../patches/afl-qemu-common.h" 10 | + 11 | void helper_fcom_ST0_FT0(CPUX86State *env) 12 | { 13 | int ret; 14 | 15 | + if (afl_compcov_level > 2 && env->eip < afl_end_code && 16 | + env->eip >= afl_start_code) 17 | + afl_float_compcov_log_80(env->eip, ST0, FT0); 18 | + 19 | ret = floatx80_compare(ST0, FT0, &env->fp_status); 20 | env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret + 1]; 21 | } 22 | @@ -396,6 +402,10 @@ void helper_fucom_ST0_FT0(CPUX86State *env) 23 | { 24 | int ret; 25 | 26 | + if (afl_compcov_level > 2 && env->eip < afl_end_code && 27 | + env->eip >= afl_start_code) 28 | + afl_float_compcov_log_80(env->eip, ST0, FT0); 29 | + 30 | ret = floatx80_compare_quiet(ST0, FT0, &env->fp_status); 31 | env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret + 1]; 32 | } 33 | @@ -407,6 +417,10 @@ void helper_fcomi_ST0_FT0(CPUX86State *env) 34 | int eflags; 35 | int ret; 36 | 37 | + if (afl_compcov_level > 2 && env->eip < afl_end_code && 38 | + env->eip >= afl_start_code) 39 | + afl_float_compcov_log_80(env->eip, ST0, FT0); 40 | + 41 | ret = floatx80_compare(ST0, FT0, &env->fp_status); 42 | eflags = cpu_cc_compute_all(env, CC_OP); 43 | eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1]; 44 | @@ -418,6 +432,10 @@ void helper_fucomi_ST0_FT0(CPUX86State *env) 45 | int eflags; 46 | int ret; 47 | 48 | + if (afl_compcov_level > 2 && env->eip < afl_end_code && 49 | + env->eip >= afl_start_code) 50 | + afl_float_compcov_log_80(env->eip, ST0, FT0); 51 | + 52 | ret = floatx80_compare_quiet(ST0, FT0, &env->fp_status); 53 | eflags = cpu_cc_compute_all(env, CC_OP); 54 | eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1]; 55 | -------------------------------------------------------------------------------- /unicorn_mode/patches/afl-unicorn-cpu-translate-inl.h: -------------------------------------------------------------------------------- 1 | /* 2 | american fuzzy lop++ - unicorn instrumentation 3 | ---------------------------------------------- 4 | 5 | Originally written by Andrew Griffiths and 6 | Michal Zalewski 7 | 8 | Adapted for afl-unicorn by Dominik Maier 9 | 10 | CompareCoverage and NeverZero counters by Andrea Fioraldi 11 | 12 | 13 | Copyright 2015, 2016, 2017 Google Inc. All rights reserved. 14 | Copyright 2019 AFLplusplus Project. All rights reserved. 15 | 16 | Licensed under the Apache License, Version 2.0 (the "License"); 17 | you may not use this file except in compliance with the License. 18 | You may obtain a copy of the License at: 19 | 20 | http://www.apache.org/licenses/LICENSE-2.0 21 | 22 | This code is a shim patched into the separately-distributed source 23 | code of Unicorn 1.0.1. It leverages the built-in QEMU tracing functionality 24 | to implement AFL-style instrumentation and to take care of the remaining 25 | parts of the AFL fork server logic. 26 | 27 | The resulting libunicorn binary is essentially a standalone instrumentation 28 | tool; for an example of how to leverage it for other purposes, you can 29 | have a look at afl-showmap.c. 30 | 31 | */ 32 | 33 | #include "../../config.h" 34 | 35 | static void afl_gen_compcov(TCGContext *s, uint64_t cur_loc, TCGv_i64 arg1, 36 | TCGv_i64 arg2, TCGMemOp ot, int is_imm) { 37 | 38 | if (!s->uc->afl_compcov_level || !s->uc->afl_area_ptr) return; 39 | 40 | if (!is_imm && s->uc->afl_compcov_level < 2) return; 41 | 42 | cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); 43 | cur_loc &= MAP_SIZE - 7; 44 | 45 | if (cur_loc >= s->uc->afl_inst_rms) return; 46 | 47 | switch (ot) { 48 | 49 | case MO_64: gen_afl_compcov_log_64(s, cur_loc, arg1, arg2); break; 50 | case MO_32: gen_afl_compcov_log_32(s, cur_loc, arg1, arg2); break; 51 | case MO_16: gen_afl_compcov_log_16(s, cur_loc, arg1, arg2); break; 52 | default: return; 53 | 54 | } 55 | 56 | } 57 | 58 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /qemu_mode/patches/i386-ops_sse.diff: -------------------------------------------------------------------------------- 1 | diff --git a/target/i386/ops_sse.h b/target/i386/ops_sse.h 2 | index ed059897..a5296caa 100644 3 | --- a/target/i386/ops_sse.h 4 | +++ b/target/i386/ops_sse.h 5 | @@ -997,6 +997,8 @@ SSE_HELPER_CMP(cmpord, FPU_CMPORD) 6 | 7 | static const int comis_eflags[4] = {CC_C, CC_Z, 0, CC_Z | CC_P | CC_C}; 8 | 9 | +#include "../patches/afl-qemu-common.h" 10 | + 11 | void helper_ucomiss(CPUX86State *env, Reg *d, Reg *s) 12 | { 13 | int ret; 14 | @@ -1004,6 +1006,11 @@ void helper_ucomiss(CPUX86State *env, Reg *d, Reg *s) 15 | 16 | s0 = d->ZMM_S(0); 17 | s1 = s->ZMM_S(0); 18 | + 19 | + if (afl_compcov_level > 2 && env->eip < afl_end_code && 20 | + env->eip >= afl_start_code) 21 | + afl_float_compcov_log_32(env->eip, s0, s1, &env->sse_status); 22 | + 23 | ret = float32_compare_quiet(s0, s1, &env->sse_status); 24 | CC_SRC = comis_eflags[ret + 1]; 25 | } 26 | @@ -1015,6 +1022,11 @@ void helper_comiss(CPUX86State *env, Reg *d, Reg *s) 27 | 28 | s0 = d->ZMM_S(0); 29 | s1 = s->ZMM_S(0); 30 | + 31 | + if (afl_compcov_level > 2 && env->eip < afl_end_code && 32 | + env->eip >= afl_start_code) 33 | + afl_float_compcov_log_32(env->eip, s0, s1, &env->sse_status); 34 | + 35 | ret = float32_compare(s0, s1, &env->sse_status); 36 | CC_SRC = comis_eflags[ret + 1]; 37 | } 38 | @@ -1026,6 +1038,11 @@ void helper_ucomisd(CPUX86State *env, Reg *d, Reg *s) 39 | 40 | d0 = d->ZMM_D(0); 41 | d1 = s->ZMM_D(0); 42 | + 43 | + if (afl_compcov_level > 2 && env->eip < afl_end_code && 44 | + env->eip >= afl_start_code) 45 | + afl_float_compcov_log_64(env->eip, d0, d1, &env->sse_status); 46 | + 47 | ret = float64_compare_quiet(d0, d1, &env->sse_status); 48 | CC_SRC = comis_eflags[ret + 1]; 49 | } 50 | @@ -1037,6 +1054,11 @@ void helper_comisd(CPUX86State *env, Reg *d, Reg *s) 51 | 52 | d0 = d->ZMM_D(0); 53 | d1 = s->ZMM_D(0); 54 | + 55 | + if (afl_compcov_level > 2 && env->eip < afl_end_code && 56 | + env->eip >= afl_start_code) 57 | + afl_float_compcov_log_64(env->eip, d0, d1, &env->sse_status); 58 | + 59 | ret = float64_compare(d0, d1, &env->sse_status); 60 | CC_SRC = comis_eflags[ret + 1]; 61 | } 62 | -------------------------------------------------------------------------------- /qbdi_mode/build.sh: -------------------------------------------------------------------------------- 1 | 2 | if [ -z ${STANDALONE_TOOLCHAIN_PATH} ]; then 3 | echo "please set the android-standalone-toolchain path in STANDALONE_TOOLCHAIN_PATH environmental variable" 4 | echo "for example: " 5 | echo " export STANDALONE_TOOLCHAIN_PATH=/home/android-standalone-toolchain-21/" 6 | exit 7 | fi 8 | 9 | if [ -z ${QBDI_SDK_PATH} ]; then 10 | echo "please set the qbdi sdk path in QBDI_SDK_PATH environmental variable" 11 | echo "for example: " 12 | echo " export QBDI_SDK_PATH=/home/QBDI-Android/" 13 | exit 14 | fi 15 | 16 | 17 | 18 | if [ "$1" = "x86" ]; then 19 | echo "build x86 qbdi" 20 | compiler_prefix="${STANDALONE_TOOLCHAIN_PATH}/bin/" 21 | if [ -z ${CC} ]; then 22 | export CC=i686-linux-android-gcc 23 | fi 24 | if [ -z ${CXX} ]; then 25 | export CXX=i686-linux-android-g++ 26 | fi 27 | elif [ "$1" = "x86_64" ]; then 28 | echo "build x86_64 qbdi" 29 | compiler_prefix="${STANDALONE_TOOLCHAIN_PATH}/bin/" 30 | if [ -z ${CC} ]; then 31 | export CC=x86_64-linux-android-gcc 32 | fi 33 | if [ -z ${CXX} ]; then 34 | export CXX=x86_64-linux-android-g++ 35 | fi 36 | else 37 | echo "usage: ./build.sh arch[x86, x86_64]" 38 | exit 39 | fi 40 | 41 | 42 | CFLAGS="-I${QBDI_SDK_PATH}/usr/local/include/ -L${QBDI_SDK_PATH}/usr/local/lib/" 43 | 44 | echo "[+] Building the QBDI template" 45 | # build the qbdi template 46 | ${compiler_prefix}${CXX} -o loader template.cpp -lQBDI -ldl -w -g ${CFLAGS} 47 | 48 | echo "[+] Building the demo library" 49 | # build the demo share library 50 | ${compiler_prefix}${CC} -shared -o libdemo.so demo-so.c -w -g 51 | 52 | echo "[+] Building afl-fuzz for Android" 53 | # build afl-fuzz 54 | cd .. 55 | ${compiler_prefix}${CC} -DANDROID_DISABLE_FANCY=1 -O3 -funroll-loops -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign -I include/ -DAFL_PATH=\"/usr/local/lib/afl\" -DBIN_PATH=\"/usr/local/bin\" -DDOC_PATH=\"/usr/local/share/doc/afl\" -Wno-unused-function src/afl-fuzz-misc.c src/afl-fuzz-extras.c src/afl-fuzz-queue.c src/afl-fuzz-one.c src/afl-fuzz-python.c src/afl-fuzz-stats.c src/afl-fuzz-init.c src/afl-fuzz.c src/afl-fuzz-bitmap.c src/afl-fuzz-run.c src/afl-fuzz-globals.c src/afl-common.c src/afl-sharedmem.c src/afl-forkserver.c -o qbdi_mode/afl-fuzz -ldl -w 56 | 57 | echo "[+] All done. Enjoy!" 58 | -------------------------------------------------------------------------------- /docs/README.MOpt: -------------------------------------------------------------------------------- 1 | # MOpt(imized) AFL by 2 | 3 | ### 1. Description 4 | MOpt-AFL is a AFL-based fuzzer that utilizes a customized Particle Swarm 5 | Optimization (PSO) algorithm to find the optimal selection probability 6 | distribution of operators with respect to fuzzing effectiveness. 7 | More details can be found in the technical report. 8 | 9 | ### 2. Cite Information 10 | Chenyang Lyu, Shouling Ji, Chao Zhang, Yuwei Li, Wei-Han Lee, Yu Song and 11 | Raheem Beyah, MOPT: Optimized Mutation Scheduling for Fuzzers, 12 | USENIX Security 2019. 13 | 14 | ### 3. Seed Sets 15 | We open source all the seed sets used in the paper 16 | "MOPT: Optimized Mutation Scheduling for Fuzzers". 17 | 18 | ### 4. Experiment Results 19 | The experiment results can be found in 20 | https://drive.google.com/drive/folders/184GOzkZGls1H2NuLuUfSp9gfqp1E2-lL?usp=sharing. 21 | We only open source the crash files since the space is limited. 22 | 23 | ### 5. Technical Report 24 | MOpt_TechReport.pdf is the technical report of the paper 25 | "MOPT: Optimized Mutation Scheduling for Fuzzers", which contains more deatails. 26 | 27 | ### 6. Parameter Introduction 28 | Most important, you must add the parameter `-L` (e.g., `-L 0`) to launch the 29 | MOpt scheme. 30 | 31 | Option '-L' controls the time to move on to the pacemaker fuzzing mode. 32 | '-L t': when MOpt-AFL finishes the mutation of one input, if it has not 33 | discovered any new unique crash or path for more than t minutes, MOpt-AFL will 34 | enter the pacemaker fuzzing mode. 35 | 36 | Setting 0 will enter the pacemaker fuzzing mode at first, which is 37 | recommended in a short time-scale evaluation. 38 | 39 | Other important parameters can be found in afl-fuzz.c, for instance, 40 | 41 | 'swarm_num': the number of the PSO swarms used in the fuzzing process. 42 | 'period_pilot': how many times MOpt-AFL will execute the target program 43 | in the pilot fuzzing module, then it will enter the core fuzzing module. 44 | 'period_core': how many times MOpt-AFL will execute the target program in the 45 | core fuzzing module, then it will enter the PSO updating module. 46 | 'limit_time_bound': control how many interesting test cases need to be found 47 | before MOpt-AFL quits the pacemaker fuzzing mode and reuses the deterministic stage. 48 | 0 < 'limit_time_bound' < 1, MOpt-AFL-tmp. 49 | 'limit_time_bound' >= 1, MOpt-AFL-ever. 50 | 51 | Have fun with MOpt in AFL! 52 | -------------------------------------------------------------------------------- /unicorn_mode/patches/afl-unicorn-tcg-op-inl.h: -------------------------------------------------------------------------------- 1 | /* 2 | american fuzzy lop++ - unicorn instrumentation 3 | ---------------------------------------------- 4 | 5 | Originally written by Andrew Griffiths and 6 | Michal Zalewski 7 | 8 | Adapted for afl-unicorn by Dominik Maier 9 | 10 | CompareCoverage and NeverZero counters by Andrea Fioraldi 11 | 12 | 13 | Copyright 2015, 2016, 2017 Google Inc. All rights reserved. 14 | Copyright 2019 AFLplusplus Project. All rights reserved. 15 | 16 | Licensed under the Apache License, Version 2.0 (the "License"); 17 | you may not use this file except in compliance with the License. 18 | You may obtain a copy of the License at: 19 | 20 | http://www.apache.org/licenses/LICENSE-2.0 21 | 22 | This code is a shim patched into the separately-distributed source 23 | code of Unicorn 1.0.1. It leverages the built-in QEMU tracing functionality 24 | to implement AFL-style instrumentation and to take care of the remaining 25 | parts of the AFL fork server logic. 26 | 27 | The resulting libunicorn binary is essentially a standalone instrumentation 28 | tool; for an example of how to leverage it for other purposes, you can 29 | have a look at afl-showmap.c. 30 | 31 | */ 32 | 33 | static inline void gen_afl_compcov_log_16(TCGContext *tcg_ctx, uint64_t cur_loc, 34 | TCGv_i64 arg1, TCGv_i64 arg2) { 35 | 36 | TCGv_ptr tuc = tcg_const_ptr(tcg_ctx, tcg_ctx->uc); 37 | TCGv_i64 tcur_loc = tcg_const_i64(tcg_ctx, cur_loc); 38 | gen_helper_afl_compcov_log_16(tcg_ctx, tuc, tcur_loc, arg1, arg2); 39 | 40 | } 41 | 42 | static inline void gen_afl_compcov_log_32(TCGContext *tcg_ctx, uint64_t cur_loc, 43 | TCGv_i64 arg1, TCGv_i64 arg2) { 44 | 45 | TCGv_ptr tuc = tcg_const_ptr(tcg_ctx, tcg_ctx->uc); 46 | TCGv_i64 tcur_loc = tcg_const_i64(tcg_ctx, cur_loc); 47 | gen_helper_afl_compcov_log_32(tcg_ctx, tuc, tcur_loc, arg1, arg2); 48 | 49 | } 50 | 51 | static inline void gen_afl_compcov_log_64(TCGContext *tcg_ctx, uint64_t cur_loc, 52 | TCGv_i64 arg1, TCGv_i64 arg2) { 53 | 54 | TCGv_ptr tuc = tcg_const_ptr(tcg_ctx, tcg_ctx->uc); 55 | TCGv_i64 tcur_loc = tcg_const_i64(tcg_ctx, cur_loc); 56 | gen_helper_afl_compcov_log_64(tcg_ctx, tuc, tcur_loc, arg1, arg2); 57 | 58 | } 59 | 60 | -------------------------------------------------------------------------------- /experimental/socket_fuzzing/socketfuzz.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This is desock_dup.c from the amazing preeny project 3 | * https://github.com/zardus/preeny 4 | * 5 | * It is packaged in afl++ to have it at hand if needed 6 | * 7 | */ 8 | 9 | #define _GNU_SOURCE 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include // 16 | #include // 17 | #include // 18 | #include // 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | //#include "logging.h" // switche from preeny_info() to fprintf(stderr, "Info: " 27 | 28 | // 29 | // originals 30 | // 31 | int (*original_close)(int); 32 | int (*original_dup2)(int, int); 33 | __attribute__((constructor)) void preeny_desock_dup_orig() { 34 | 35 | original_close = dlsym(RTLD_NEXT, "close"); 36 | original_dup2 = dlsym(RTLD_NEXT, "dup2"); 37 | 38 | } 39 | 40 | int close(int sockfd) { 41 | 42 | if (sockfd <= 2) { 43 | 44 | fprintf(stderr, "Info: Disabling close on %d\n", sockfd); 45 | return 0; 46 | 47 | } else { 48 | 49 | return original_close(sockfd); 50 | 51 | } 52 | 53 | } 54 | 55 | int dup2(int old, int new) { 56 | 57 | if (new <= 2) { 58 | 59 | fprintf(stderr, "Info: Disabling dup from %d to %d\n", old, new); 60 | return 0; 61 | 62 | } else { 63 | 64 | return original_dup2(old, new); 65 | 66 | } 67 | 68 | } 69 | 70 | int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) { 71 | 72 | (void)sockfd; 73 | (void)addr; 74 | (void)addrlen; 75 | fprintf(stderr, "Info: Emulating accept on %d\n", sockfd); 76 | return 0; 77 | 78 | } 79 | 80 | int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { 81 | 82 | (void)sockfd; 83 | (void)addr; 84 | (void)addrlen; 85 | fprintf(stderr, "Info: Emulating bind on port %d\n", 86 | ntohs(((struct sockaddr_in *)addr)->sin_port)); 87 | return 0; 88 | 89 | } 90 | 91 | int listen(int sockfd, int backlog) { 92 | 93 | (void)sockfd; 94 | (void)backlog; 95 | return 0; 96 | 97 | } 98 | 99 | int setsockopt(int sockfd, int level, int optid, const void *optdata, 100 | socklen_t optdatalen) { 101 | 102 | (void)sockfd; 103 | (void)level; 104 | (void)optid; 105 | (void)optdata; 106 | (void)optdatalen; 107 | return 0; 108 | 109 | } 110 | 111 | -------------------------------------------------------------------------------- /experimental/argv_fuzzing/argv-fuzz-inl.h: -------------------------------------------------------------------------------- 1 | /* 2 | american fuzzy lop - sample argv fuzzing wrapper 3 | ------------------------------------------------ 4 | 5 | Written by Michal Zalewski 6 | 7 | Copyright 2015 Google Inc. All rights reserved. 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at: 12 | 13 | http://www.apache.org/licenses/LICENSE-2.0 14 | 15 | This file shows a simple way to fuzz command-line parameters with stock 16 | afl-fuzz. To use, add: 17 | 18 | #include "/path/to/argv-fuzz-inl.h" 19 | 20 | ...to the file containing main(), ideally placing it after all the 21 | standard includes. Next, put AFL_INIT_ARGV(); near the very beginning of 22 | main(). 23 | 24 | This will cause the program to read NUL-delimited input from stdin and 25 | put it in argv[]. Two subsequent NULs terminate the array. Empty 26 | params are encoded as a lone 0x02. Lone 0x02 can't be generated, but 27 | that shouldn't matter in real life. 28 | 29 | If you would like to always preserve argv[0], use this instead: 30 | AFL_INIT_SET0("prog_name"); 31 | 32 | */ 33 | 34 | #ifndef _HAVE_ARGV_FUZZ_INL 35 | #define _HAVE_ARGV_FUZZ_INL 36 | 37 | #include 38 | 39 | #define AFL_INIT_ARGV() \ 40 | do { \ 41 | \ 42 | argv = afl_init_argv(&argc); \ 43 | \ 44 | } while (0) 45 | 46 | #define AFL_INIT_SET0(_p) \ 47 | do { \ 48 | \ 49 | argv = afl_init_argv(&argc); \ 50 | argv[0] = (_p); \ 51 | if (!argc) argc = 1; \ 52 | \ 53 | } while (0) 54 | 55 | #define MAX_CMDLINE_LEN 100000 56 | #define MAX_CMDLINE_PAR 1000 57 | 58 | static char** afl_init_argv(int* argc) { 59 | 60 | static char in_buf[MAX_CMDLINE_LEN]; 61 | static char* ret[MAX_CMDLINE_PAR]; 62 | 63 | char* ptr = in_buf; 64 | int rc = 0; 65 | 66 | if (read(0, in_buf, MAX_CMDLINE_LEN - 2) < 0) {} 67 | 68 | while (*ptr) { 69 | 70 | ret[rc] = ptr; 71 | if (ret[rc][0] == 0x02 && !ret[rc][1]) ret[rc]++; 72 | rc++; 73 | 74 | while (*ptr) 75 | ptr++; 76 | ptr++; 77 | 78 | } 79 | 80 | *argc = rc; 81 | 82 | return ret; 83 | 84 | } 85 | 86 | #undef MAX_CMDLINE_LEN 87 | #undef MAX_CMDLINE_PAR 88 | 89 | #endif /* !_HAVE_ARGV_FUZZ_INL */ 90 | 91 | -------------------------------------------------------------------------------- /docs/QuickStartGuide.txt: -------------------------------------------------------------------------------- 1 | ===================== 2 | AFL quick start guide 3 | ===================== 4 | 5 | You should read docs/README.md - it's pretty short. If you really can't, here's 6 | how to hit the ground running: 7 | 8 | 1) Compile AFL with 'make'. If build fails, see docs/INSTALL for tips. 9 | 10 | 2) Find or write a reasonably fast and simple program that takes data from 11 | a file or stdin, processes it in a test-worthy way, then exits cleanly. 12 | If testing a network service, modify it to run in the foreground and read 13 | from stdin. When fuzzing a format that uses checksums, comment out the 14 | checksum verification code, too. 15 | If this is not possible (e.g. in -Q(emu) mode) then use AFL_POST_LIBRARY 16 | to calculate the values with your own library. 17 | 18 | The program must crash properly when a fault is encountered. Watch out for 19 | custom SIGSEGV or SIGABRT handlers and background processes. For tips on 20 | detecting non-crashing flaws, see section 11 in docs/README.md . 21 | 22 | 3) Compile the program / library to be fuzzed using afl-gcc. A common way to 23 | do this would be: 24 | 25 | CC=/path/to/afl-gcc CXX=/path/to/afl-g++ ./configure --disable-shared 26 | make clean all 27 | 28 | If program build fails, ping . 29 | 30 | 4) Get a small but valid input file that makes sense to the program. When 31 | fuzzing verbose syntax (SQL, HTTP, etc), create a dictionary as described in 32 | dictionaries/README.dictionaries, too. 33 | 34 | 5) If the program reads from stdin, run 'afl-fuzz' like so: 35 | 36 | ./afl-fuzz -i testcase_dir -o findings_dir -- \ 37 | /path/to/tested/program [...program's cmdline...] 38 | 39 | If the program takes input from a file, you can put @@ in the program's 40 | command line; AFL will put an auto-generated file name in there for you. 41 | 42 | 6) Investigate anything shown in red in the fuzzer UI by promptly consulting 43 | docs/status_screen.txt. 44 | 45 | 7) compile and use llvm_mode (afl-clang-fast/afl-clang-fast++) as it is way 46 | faster and has a few cool features 47 | 48 | 8) There is a basic docker build with 'docker build -t aflplusplus .' 49 | 50 | That's it. Sit back, relax, and - time permitting - try to skim through the 51 | following files: 52 | 53 | - docs/README.md - A general introduction to AFL, 54 | - docs/perf_tips.txt - Simple tips on how to fuzz more quickly, 55 | - docs/status_screen.txt - An explanation of the tidbits shown in the UI, 56 | - docs/parallel_fuzzing.txt - Advice on running AFL on multiple cores. 57 | -------------------------------------------------------------------------------- /include/hash.h: -------------------------------------------------------------------------------- 1 | /* 2 | american fuzzy lop++ - hashing function 3 | --------------------------------------- 4 | 5 | The hash32() function is a variant of MurmurHash3, a good 6 | non-cryptosafe hashing function developed by Austin Appleby. 7 | 8 | For simplicity, this variant does *NOT* accept buffer lengths 9 | that are not divisible by 8 bytes. The 32-bit version is otherwise 10 | similar to the original; the 64-bit one is a custom hack with 11 | mostly-unproven properties. 12 | 13 | Austin's original code is public domain. 14 | 15 | Other code written by Michal Zalewski 16 | 17 | Copyright 2016 Google Inc. All rights reserved. 18 | 19 | Licensed under the Apache License, Version 2.0 (the "License"); 20 | you may not use this file except in compliance with the License. 21 | You may obtain a copy of the License at: 22 | 23 | http://www.apache.org/licenses/LICENSE-2.0 24 | 25 | */ 26 | 27 | #ifndef _HAVE_HASH_H 28 | #define _HAVE_HASH_H 29 | 30 | #include "types.h" 31 | 32 | #ifdef __x86_64__ 33 | 34 | #define ROL64(_x, _r) ((((u64)(_x)) << (_r)) | (((u64)(_x)) >> (64 - (_r)))) 35 | 36 | static inline u32 hash32(const void* key, u32 len, u32 seed) { 37 | 38 | const u64* data = (u64*)key; 39 | u64 h1 = seed ^ len; 40 | 41 | len >>= 3; 42 | 43 | while (len--) { 44 | 45 | u64 k1 = *data++; 46 | 47 | k1 *= 0x87c37b91114253d5ULL; 48 | k1 = ROL64(k1, 31); 49 | k1 *= 0x4cf5ad432745937fULL; 50 | 51 | h1 ^= k1; 52 | h1 = ROL64(h1, 27); 53 | h1 = h1 * 5 + 0x52dce729; 54 | 55 | } 56 | 57 | h1 ^= h1 >> 33; 58 | h1 *= 0xff51afd7ed558ccdULL; 59 | h1 ^= h1 >> 33; 60 | h1 *= 0xc4ceb9fe1a85ec53ULL; 61 | h1 ^= h1 >> 33; 62 | 63 | return h1; 64 | 65 | } 66 | 67 | #else 68 | 69 | #define ROL32(_x, _r) ((((u32)(_x)) << (_r)) | (((u32)(_x)) >> (32 - (_r)))) 70 | 71 | static inline u32 hash32(const void* key, u32 len, u32 seed) { 72 | 73 | const u32* data = (u32*)key; 74 | u32 h1 = seed ^ len; 75 | 76 | len >>= 2; 77 | 78 | while (len--) { 79 | 80 | u32 k1 = *data++; 81 | 82 | k1 *= 0xcc9e2d51; 83 | k1 = ROL32(k1, 15); 84 | k1 *= 0x1b873593; 85 | 86 | h1 ^= k1; 87 | h1 = ROL32(h1, 13); 88 | h1 = h1 * 5 + 0xe6546b64; 89 | 90 | } 91 | 92 | h1 ^= h1 >> 16; 93 | h1 *= 0x85ebca6b; 94 | h1 ^= h1 >> 13; 95 | h1 *= 0xc2b2ae35; 96 | h1 ^= h1 >> 16; 97 | 98 | return h1; 99 | 100 | } 101 | 102 | #endif /* ^__x86_64__ */ 103 | 104 | #endif /* !_HAVE_HASH_H */ 105 | 106 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /experimental/distributed_fuzzing/sync_script.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # american fuzzy lop - fuzzer synchronization tool 4 | # ------------------------------------------------ 5 | # 6 | # Written by Michal Zalewski 7 | # 8 | # Copyright 2014 Google Inc. All rights reserved. 9 | # 10 | # Licensed under the Apache License, Version 2.0 (the "License"); 11 | # you may not use this file except in compliance with the License. 12 | # You may obtain a copy of the License at: 13 | # 14 | # http://www.apache.org/licenses/LICENSE-2.0 15 | # 16 | # To make this script work: 17 | # 18 | # - Edit FUZZ_HOSTS, FUZZ_DOMAIN, FUZZ_USER, and SYNC_DIR to reflect your 19 | # environment. 20 | # 21 | # - Make sure that the system you are running this on can log into FUZZ_HOSTS 22 | # without a password (authorized_keys or otherwise). 23 | # 24 | # - Make sure that every fuzzer is running with -o pointing to SYNC_DIR and -S 25 | # that consists of its local host name, followed by an underscore, and then 26 | # by some host-local fuzzer ID. 27 | # 28 | 29 | # Hosts to synchronize the data across. 30 | FUZZ_HOSTS='host1 host2 host3 host4' 31 | 32 | # Domain for all hosts 33 | FUZZ_DOMAIN='example.com' 34 | 35 | # Remote user for SSH 36 | FUZZ_USER=bob 37 | 38 | # Directory to synchronize 39 | SYNC_DIR='/home/bob/sync_dir' 40 | 41 | # Interval (seconds) between sync attempts 42 | SYNC_INTERVAL=$((30 * 60)) 43 | 44 | if [ "$AFL_ALLOW_TMP" = "" ]; then 45 | 46 | if [ "$PWD" = "/tmp" -o "$PWD" = "/var/tmp" ]; then 47 | echo "[-] Error: do not use shared /tmp or /var/tmp directories with this script." 1>&2 48 | exit 1 49 | fi 50 | 51 | fi 52 | 53 | rm -rf .sync_tmp 2>/dev/null 54 | mkdir .sync_tmp || exit 1 55 | 56 | while :; do 57 | 58 | # Pull data in... 59 | 60 | for host in $FUZZ_HOSTS; do 61 | 62 | echo "[*] Retrieving data from ${host}.${FUZZ_DOMAIN}..." 63 | 64 | ssh -o 'passwordauthentication no' ${FUZZ_USER}@${host}.$FUZZ_DOMAIN \ 65 | "cd '$SYNC_DIR' && tar -czf - ${host}_*/[qf]*" >".sync_tmp/${host}.tgz" 66 | 67 | done 68 | 69 | # Distribute data. For large fleets, see tips in the docs/ directory. 70 | 71 | for dst_host in $FUZZ_HOSTS; do 72 | 73 | echo "[*] Distributing data to ${dst_host}.${FUZZ_DOMAIN}..." 74 | 75 | for src_host in $FUZZ_HOSTS; do 76 | 77 | test "$src_host" = "$dst_host" && continue 78 | 79 | echo " Sending fuzzer data from ${src_host}.${FUZZ_DOMAIN}..." 80 | 81 | ssh -o 'passwordauthentication no' ${FUZZ_USER}@$dst_host \ 82 | "cd '$SYNC_DIR' && tar -xkzf -" <".sync_tmp/${src_host}.tgz" 83 | 84 | done 85 | 86 | done 87 | 88 | echo "[+] Done. Sleeping for $SYNC_INTERVAL seconds (Ctrl-C to quit)." 89 | 90 | sleep $SYNC_INTERVAL 91 | 92 | done 93 | 94 | -------------------------------------------------------------------------------- /qemu_mode/patches/afl-qemu-translate-inl.h: -------------------------------------------------------------------------------- 1 | /* 2 | american fuzzy lop++ - high-performance binary-only instrumentation 3 | ------------------------------------------------------------------- 4 | 5 | Originally written by Andrew Griffiths and 6 | Michal Zalewski 7 | 8 | TCG instrumentation and block chaining support by Andrea Biondo 9 | 10 | 11 | QEMU 3.1.1 port, TCG thread-safety, CompareCoverage and NeverZero 12 | counters by Andrea Fioraldi 13 | 14 | Copyright 2015, 2016, 2017 Google Inc. All rights reserved. 15 | Copyright 2019 AFLplusplus Project. All rights reserved. 16 | 17 | Licensed under the Apache License, Version 2.0 (the "License"); 18 | you may not use this file except in compliance with the License. 19 | You may obtain a copy of the License at: 20 | 21 | http://www.apache.org/licenses/LICENSE-2.0 22 | 23 | This code is a shim patched into the separately-distributed source 24 | code of QEMU 3.1.0. It leverages the built-in QEMU tracing functionality 25 | to implement AFL-style instrumentation and to take care of the remaining 26 | parts of the AFL fork server logic. 27 | 28 | The resulting QEMU binary is essentially a standalone instrumentation 29 | tool; for an example of how to leverage it for other purposes, you can 30 | have a look at afl-showmap.c. 31 | 32 | */ 33 | 34 | #include "afl-qemu-common.h" 35 | #include "tcg-op.h" 36 | 37 | void afl_maybe_log(target_ulong cur_loc) { 38 | 39 | register uintptr_t afl_idx = cur_loc ^ afl_prev_loc; 40 | 41 | INC_AFL_AREA(afl_idx); 42 | 43 | afl_prev_loc = cur_loc >> 1; 44 | 45 | } 46 | 47 | /* Generates TCG code for AFL's tracing instrumentation. */ 48 | static void afl_gen_trace(target_ulong cur_loc) { 49 | 50 | /* Optimize for cur_loc > afl_end_code, which is the most likely case on 51 | Linux systems. */ 52 | 53 | if (cur_loc > afl_end_code || 54 | cur_loc < afl_start_code /*|| !afl_area_ptr*/) // not needed because of 55 | // static dummy buffer 56 | return; 57 | 58 | /* Looks like QEMU always maps to fixed locations, so ASLR is not a 59 | concern. Phew. But instruction addresses may be aligned. Let's mangle 60 | the value to get something quasi-uniform. */ 61 | 62 | cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); 63 | cur_loc &= MAP_SIZE - 1; 64 | 65 | /* Implement probabilistic instrumentation by looking at scrambled block 66 | address. This keeps the instrumented locations stable across runs. */ 67 | 68 | if (cur_loc >= afl_inst_rms) return; 69 | 70 | tcg_gen_afl_maybe_log_call(cur_loc); 71 | 72 | } 73 | 74 | -------------------------------------------------------------------------------- /gcc_plugin/README.whitelist.md: -------------------------------------------------------------------------------- 1 | ======================================== 2 | Using afl++ with partial instrumentation 3 | ======================================== 4 | 5 | This file describes how you can selectively instrument only the source files 6 | that are interesting to you using the gcc instrumentation provided by 7 | afl++. 8 | 9 | Plugin by hexcoder-. 10 | 11 | 12 | ## 1) Description and purpose 13 | 14 | When building and testing complex programs where only a part of the program is 15 | the fuzzing target, it often helps to only instrument the necessary parts of 16 | the program, leaving the rest uninstrumented. This helps to focus the fuzzer 17 | on the important parts of the program, avoiding undesired noise and 18 | disturbance by uninteresting code being exercised. 19 | 20 | For this purpose, I have added a "partial instrumentation" support to the gcc 21 | plugin of AFLFuzz that allows you to specify on a source file level which files 22 | should be compiled with or without instrumentation. 23 | 24 | 25 | ## 2) Building the gcc plugin 26 | 27 | The new code is part of the existing afl++ gcc plugin in the gcc_plugin/ 28 | subdirectory. There is nothing specifically to do :) 29 | 30 | 31 | ## 3) How to use the partial instrumentation mode 32 | 33 | In order to build with partial instrumentation, you need to build with 34 | afl-gcc-fast and afl-g++-fast respectively. The only required change is 35 | that you need to set the environment variable AFL_GCC_WHITELIST when calling 36 | the compiler. 37 | 38 | The environment variable must point to a file containing all the filenames 39 | that should be instrumented. For matching, the filename that is being compiled 40 | must end in the filename entry contained in this whitelist (to avoid breaking 41 | the matching when absolute paths are used during compilation). 42 | 43 | For example if your source tree looks like this: 44 | 45 | ``` 46 | project/ 47 | project/feature_a/a1.cpp 48 | project/feature_a/a2.cpp 49 | project/feature_b/b1.cpp 50 | project/feature_b/b2.cpp 51 | ``` 52 | 53 | and you only want to test feature_a, then create a whitelist file containing: 54 | 55 | ``` 56 | feature_a/a1.cpp 57 | feature_a/a2.cpp 58 | ``` 59 | 60 | However if the whitelist file contains only this, it works as well: 61 | 62 | ``` 63 | a1.cpp 64 | a2.cpp 65 | ``` 66 | 67 | but it might lead to files being unwantedly instrumented if the same filename 68 | exists somewhere else in the project directories. 69 | 70 | The created whitelist file is then set to AFL_GCC_WHITELIST when you compile 71 | your program. For each file that didn't match the whitelist, the compiler will 72 | issue a warning at the end stating that no blocks were instrumented. If you 73 | didn't intend to instrument that file, then you can safely ignore that warning. 74 | -------------------------------------------------------------------------------- /dictionaries/js.dict: -------------------------------------------------------------------------------- 1 | # 2 | # AFL dictionary for JavaScript 3 | # ----------------------------- 4 | # 5 | # Contains basic reserved keywords and syntax building blocks. 6 | # 7 | # Created by Michal Zalewski 8 | # 9 | 10 | keyword_arguments="arguments" 11 | keyword_break="break" 12 | keyword_case="case" 13 | keyword_catch="catch" 14 | keyword_const="const" 15 | keyword_continue="continue" 16 | keyword_debugger="debugger" 17 | keyword_decodeURI="decodeURI" 18 | keyword_default="default" 19 | keyword_delete="delete" 20 | keyword_do="do" 21 | keyword_else="else" 22 | keyword_escape="escape" 23 | keyword_eval="eval" 24 | keyword_export="export" 25 | keyword_finally="finally" 26 | keyword_for="for (a=0;a<2;a++)" 27 | keyword_function="function" 28 | keyword_if="if" 29 | keyword_in="in" 30 | keyword_instanceof="instanceof" 31 | keyword_isNaN="isNaN" 32 | keyword_let="let" 33 | keyword_new="new" 34 | keyword_parseInt="parseInt" 35 | keyword_return="return" 36 | keyword_switch="switch" 37 | keyword_this="this" 38 | keyword_throw="throw" 39 | keyword_try="try" 40 | keyword_typeof="typeof" 41 | keyword_var="var" 42 | keyword_void="void" 43 | keyword_while="while" 44 | keyword_with="with" 45 | 46 | misc_1=" 1" 47 | misc_a="a" 48 | misc_array=" [1]" 49 | misc_assign=" a=1" 50 | misc_code_block=" {1}" 51 | misc_colon_num=" 1:" 52 | misc_colon_string=" 'a':" 53 | misc_comma=" ," 54 | misc_comment_block=" /* */" 55 | misc_comment_line=" //" 56 | misc_cond=" 1?2:3" 57 | misc_dec=" --" 58 | misc_div=" /" 59 | misc_equals=" =" 60 | misc_fn=" a()" 61 | misc_identical=" ===" 62 | misc_inc=" ++" 63 | misc_minus=" -" 64 | misc_modulo=" %" 65 | misc_parentheses=" ()" 66 | misc_parentheses_1=" (1)" 67 | misc_parentheses_1x4=" (1,1,1,1)" 68 | misc_parentheses_a=" (a)" 69 | misc_period="." 70 | misc_plus=" +" 71 | misc_plus_assign=" +=" 72 | misc_regex=" /a/g" 73 | misc_rol=" <<<" 74 | misc_semicolon=" ;" 75 | misc_serialized_object=" {'a': 1}" 76 | misc_string=" 'a'" 77 | misc_unicode=" '\\u0001'" 78 | 79 | object_Array=" Array" 80 | object_Boolean=" Boolean" 81 | object_Date=" Date" 82 | object_Function=" Function" 83 | object_Infinity=" Infinity" 84 | object_Int8Array=" Int8Array" 85 | object_Math=" Math" 86 | object_NaN=" NaN" 87 | object_Number=" Number" 88 | object_Object=" Object" 89 | object_RegExp=" RegExp" 90 | object_String=" String" 91 | object_Symbol=" Symbol" 92 | object_false=" false" 93 | object_null=" null" 94 | object_true=" true" 95 | 96 | prop_charAt=".charAt" 97 | prop_concat=".concat" 98 | prop_constructor=".constructor" 99 | prop_destructor=".destructor" 100 | prop_length=".length" 101 | prop_match=".match" 102 | prop_proto=".__proto__" 103 | prop_prototype=".prototype" 104 | prop_slice=".slice" 105 | prop_toCode=".toCode" 106 | prop_toString=".toString" 107 | prop_valueOf=".valueOf" 108 | -------------------------------------------------------------------------------- /qemu_mode/patches/elfload.diff: -------------------------------------------------------------------------------- 1 | diff --git a/linux-user/elfload.c b/linux-user/elfload.c 2 | index 5bccd2e2..fd7460b3 100644 3 | --- a/linux-user/elfload.c 4 | +++ b/linux-user/elfload.c 5 | @@ -20,6 +20,8 @@ 6 | 7 | #define ELF_OSABI ELFOSABI_SYSV 8 | 9 | +extern abi_ulong afl_entry_point, afl_start_code, afl_end_code; 10 | + 11 | /* from personality.h */ 12 | 13 | /* 14 | @@ -2301,6 +2303,21 @@ static void load_elf_image(const char *image_name, int image_fd, 15 | info->brk = 0; 16 | info->elf_flags = ehdr->e_flags; 17 | 18 | + if (!afl_entry_point) { 19 | + char *ptr; 20 | + if ((ptr = getenv("AFL_ENTRYPOINT")) != NULL) { 21 | + afl_entry_point = strtoul(ptr, NULL, 16); 22 | + } else { 23 | + afl_entry_point = info->entry; 24 | + } 25 | +#ifdef TARGET_ARM 26 | + /* The least significant bit indicates Thumb mode. */ 27 | + afl_entry_point = afl_entry_point & ~(target_ulong)1; 28 | +#endif 29 | + } 30 | + if (getenv("AFL_DEBUG") != NULL) 31 | + fprintf(stderr, "AFL forkserver entrypoint: %p\n", (void*)afl_entry_point); 32 | + 33 | for (i = 0; i < ehdr->e_phnum; i++) { 34 | struct elf_phdr *eppnt = phdr + i; 35 | if (eppnt->p_type == PT_LOAD) { 36 | @@ -2335,9 +2352,11 @@ static void load_elf_image(const char *image_name, int image_fd, 37 | if (elf_prot & PROT_EXEC) { 38 | if (vaddr < info->start_code) { 39 | info->start_code = vaddr; 40 | + if (!afl_start_code) afl_start_code = vaddr; 41 | } 42 | if (vaddr_ef > info->end_code) { 43 | info->end_code = vaddr_ef; 44 | + if (!afl_end_code) afl_end_code = vaddr_ef; 45 | } 46 | } 47 | if (elf_prot & PROT_WRITE) { 48 | @@ -2662,6 +2681,22 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info) 49 | change some of these later */ 50 | bprm->p = setup_arg_pages(bprm, info); 51 | 52 | + // On PowerPC64 the entry point is the _function descriptor_ 53 | + // of the entry function. For AFL to properly initialize, 54 | + // afl_entry_point needs to be set to the actual first instruction 55 | + // as opposed executed by the target program. This as opposed to 56 | + // where the function's descriptor sits in memory. 57 | + // copied from PPC init_thread 58 | +#if defined(TARGET_PPC64) && !defined(TARGET_ABI32) 59 | + if (get_ppc64_abi(infop) < 2) { 60 | + uint64_t val; 61 | + get_user_u64(val, infop->entry + 8); 62 | + _regs->gpr[2] = val + infop->load_bias; 63 | + get_user_u64(val, infop->entry); 64 | + infop->entry = val + infop->load_bias; 65 | + } 66 | +#endif 67 | + 68 | scratch = g_new0(char, TARGET_PAGE_SIZE); 69 | if (STACK_GROWS_DOWN) { 70 | bprm->p = copy_elf_strings(1, &bprm->filename, scratch, 71 | -------------------------------------------------------------------------------- /include/android-ashmem.h: -------------------------------------------------------------------------------- 1 | /* 2 | american fuzzy lop++ - android shared memory compatibility layer 3 | ---------------------------------------------------------------- 4 | 5 | Originally written by Michal Zalewski 6 | 7 | Now maintained by by Marc Heuse , 8 | Heiko Eißfeldt and 9 | Andrea Fioraldi 10 | 11 | Copyright 2016, 2017 Google Inc. All rights reserved. 12 | Copyright 2019 AFLplusplus Project. All rights reserved. 13 | 14 | Licensed under the Apache License, Version 2.0 (the "License"); 15 | you may not use this file except in compliance with the License. 16 | You may obtain a copy of the License at: 17 | 18 | http://www.apache.org/licenses/LICENSE-2.0 19 | 20 | This header re-defines the shared memory routines used by AFL++ 21 | using the Andoid API. 22 | 23 | */ 24 | 25 | #ifndef _ANDROID_ASHMEM_H 26 | #define _ANDROID_ASHMEM_H 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #if __ANDROID_API__ >= 26 35 | #define shmat bionic_shmat 36 | #define shmctl bionic_shmctl 37 | #define shmdt bionic_shmdt 38 | #define shmget bionic_shmget 39 | #endif 40 | #include 41 | #undef shmat 42 | #undef shmctl 43 | #undef shmdt 44 | #undef shmget 45 | #include 46 | 47 | #define ASHMEM_DEVICE "/dev/ashmem" 48 | 49 | static inline int shmctl(int __shmid, int __cmd, struct shmid_ds *__buf) { 50 | 51 | int ret = 0; 52 | if (__cmd == IPC_RMID) { 53 | 54 | int length = ioctl(__shmid, ASHMEM_GET_SIZE, NULL); 55 | struct ashmem_pin pin = {0, (unsigned int)length}; 56 | ret = ioctl(__shmid, ASHMEM_UNPIN, &pin); 57 | close(__shmid); 58 | 59 | } 60 | 61 | return ret; 62 | 63 | } 64 | 65 | static inline int shmget(key_t __key, size_t __size, int __shmflg) { 66 | 67 | (void)__shmflg; 68 | int fd, ret; 69 | char ourkey[11]; 70 | 71 | fd = open(ASHMEM_DEVICE, O_RDWR); 72 | if (fd < 0) return fd; 73 | 74 | sprintf(ourkey, "%d", __key); 75 | ret = ioctl(fd, ASHMEM_SET_NAME, ourkey); 76 | if (ret < 0) goto error; 77 | 78 | ret = ioctl(fd, ASHMEM_SET_SIZE, __size); 79 | if (ret < 0) goto error; 80 | 81 | return fd; 82 | 83 | error: 84 | close(fd); 85 | return ret; 86 | 87 | } 88 | 89 | static inline void *shmat(int __shmid, const void *__shmaddr, int __shmflg) { 90 | 91 | (void)__shmflg; 92 | int size; 93 | void *ptr; 94 | 95 | size = ioctl(__shmid, ASHMEM_GET_SIZE, NULL); 96 | if (size < 0) { return NULL; } 97 | 98 | ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, __shmid, 0); 99 | if (ptr == MAP_FAILED) { return NULL; } 100 | 101 | return ptr; 102 | 103 | } 104 | 105 | #endif 106 | 107 | -------------------------------------------------------------------------------- /libdislocator/README.dislocator.md: -------------------------------------------------------------------------------- 1 | # libdislocator, an abusive allocator 2 | 3 | (See ../docs/README for the general instruction manual.) 4 | 5 | This is a companion library that can be used as a drop-in replacement for the 6 | libc allocator in the fuzzed binaries. It improves the odds of bumping into 7 | heap-related security bugs in several ways: 8 | 9 | - It allocates all buffers so that they are immediately adjacent to a 10 | subsequent PROT_NONE page, causing most off-by-one reads and writes to 11 | immediately segfault, 12 | 13 | - It adds a canary immediately below the allocated buffer, to catch writes 14 | to negative offsets (won't catch reads, though), 15 | 16 | - It sets the memory returned by malloc() to garbage values, improving the 17 | odds of crashing when the target accesses uninitialized data, 18 | 19 | - It sets freed memory to PROT_NONE and does not actually reuse it, causing 20 | most use-after-free bugs to segfault right away, 21 | 22 | - It forces all realloc() calls to return a new address - and sets 23 | PROT_NONE on the original block. This catches use-after-realloc bugs, 24 | 25 | - It checks for calloc() overflows and can cause soft or hard failures 26 | of alloc requests past a configurable memory limit (AFL_LD_LIMIT_MB, 27 | AFL_LD_HARD_FAIL). 28 | - Optionally, in platforms supporting it, huge pages can be used by passing 29 | USEHUGEPAGE=1 to make. 30 | 31 | Basically, it is inspired by some of the non-default options available for the 32 | OpenBSD allocator - see malloc.conf(5) on that platform for reference. It is 33 | also somewhat similar to several other debugging libraries, such as gmalloc 34 | and DUMA - but is simple, plug-and-play, and designed specifically for fuzzing 35 | jobs. 36 | 37 | Note that it does nothing for stack-based memory handling errors. The 38 | -fstack-protector-all setting for GCC / clang, enabled when using AFL_HARDEN, 39 | can catch some subset of that. 40 | 41 | The allocator is slow and memory-intensive (even the tiniest allocation uses up 42 | 4 kB of physical memory and 8 kB of virtual mem), making it completely unsuitable 43 | for "production" uses; but it can be faster and more hassle-free than ASAN / MSAN 44 | when fuzzing small, self-contained binaries. 45 | 46 | To use this library, run AFL like so: 47 | 48 | ``` 49 | AFL_PRELOAD=/path/to/libdislocator.so ./afl-fuzz [...other params...] 50 | ``` 51 | 52 | You *have* to specify path, even if it's just ./libdislocator.so or 53 | $PWD/libdislocator.so. 54 | 55 | Similarly to afl-tmin, the library is not "proprietary" and can be used with 56 | other fuzzers or testing tools without the need for any code tweaks. It does not 57 | require AFL-instrumented binaries to work. 58 | 59 | Note that the AFL_PRELOAD approach (which AFL internally maps to LD_PRELOAD or 60 | DYLD_INSERT_LIBRARIES, depending on the OS) works only if the target binary is 61 | dynamically linked. Otherwise, attempting to use the library will have no 62 | effect. 63 | -------------------------------------------------------------------------------- /llvm_mode/README.whitelist.md: -------------------------------------------------------------------------------- 1 | # Using afl++ with partial instrumentation 2 | 3 | This file describes how you can selectively instrument only the source files 4 | that are interesting to you using the LLVM instrumentation provided by 5 | afl++ 6 | 7 | Originally developed by Christian Holler (:decoder) . 8 | 9 | ## 1) Description and purpose 10 | 11 | When building and testing complex programs where only a part of the program is 12 | the fuzzing target, it often helps to only instrument the necessary parts of 13 | the program, leaving the rest uninstrumented. This helps to focus the fuzzer 14 | on the important parts of the program, avoiding undesired noise and 15 | disturbance by uninteresting code being exercised. 16 | 17 | For this purpose, I have added a "partial instrumentation" support to the LLVM 18 | mode of AFLFuzz that allows you to specify on a source file level which files 19 | should be compiled with or without instrumentation. 20 | 21 | 22 | ## 2) Building the LLVM module 23 | 24 | The new code is part of the existing afl++ LLVM module in the llvm_mode/ 25 | subdirectory. There is nothing specifically to do :) 26 | 27 | 28 | ## 3) How to use the partial instrumentation mode 29 | 30 | In order to build with partial instrumentation, you need to build with 31 | afl-clang-fast and afl-clang-fast++ respectively. The only required change is 32 | that you need to set the environment variable AFL_LLVM_WHITELIST when calling 33 | the compiler. 34 | 35 | The environment variable must point to a file containing all the filenames 36 | that should be instrumented. For matching, the filename that is being compiled 37 | must end in the filename entry contained in this whitelist (to avoid breaking 38 | the matching when absolute paths are used during compilation). 39 | 40 | For example if your source tree looks like this: 41 | 42 | ``` 43 | project/ 44 | project/feature_a/a1.cpp 45 | project/feature_a/a2.cpp 46 | project/feature_b/b1.cpp 47 | project/feature_b/b2.cpp 48 | ``` 49 | 50 | and you only want to test feature_a, then create a whitelist file containing: 51 | 52 | ``` 53 | feature_a/a1.cpp 54 | feature_a/a2.cpp 55 | ``` 56 | 57 | However if the whitelist file contains only this, it works as well: 58 | 59 | ``` 60 | a1.cpp 61 | a2.cpp 62 | ``` 63 | 64 | but it might lead to files being unwantedly instrumented if the same filename 65 | exists somewhere else in the project directories. 66 | 67 | The created whitelist file is then set to AFL_LLVM_WHITELIST when you compile 68 | your program. For each file that didn't match the whitelist, the compiler will 69 | issue a warning at the end stating that no blocks were instrumented. If you 70 | didn't intend to instrument that file, then you can safely ignore that warning. 71 | 72 | For old LLVM versions this feature might require to be compiled with debug 73 | information (-g), however at least from llvm version 6.0 onwards this is not 74 | required anymore (and might hurt performance and crash detection, so better not 75 | use -g). 76 | -------------------------------------------------------------------------------- /qemu_mode/patches/syscall.diff: -------------------------------------------------------------------------------- 1 | diff --git a/linux-user/syscall.c b/linux-user/syscall.c 2 | index b13a170e..5678c006 100644 3 | --- a/linux-user/syscall.c 4 | +++ b/linux-user/syscall.c 5 | @@ -111,6 +111,9 @@ 6 | 7 | #include "qemu.h" 8 | #include "fd-trans.h" 9 | +#include 10 | + 11 | +extern unsigned int afl_forksrv_pid; 12 | 13 | #ifndef CLONE_IO 14 | #define CLONE_IO 0x80000000 /* Clone io context */ 15 | @@ -250,7 +253,8 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \ 16 | #endif 17 | 18 | #ifdef __NR_gettid 19 | -_syscall0(int, gettid) 20 | +#define __NR_sys_gettid __NR_gettid 21 | +_syscall0(int, sys_gettid) 22 | #else 23 | /* This is a replacement for the host gettid() and must return a host 24 | errno. */ 25 | @@ -5384,7 +5388,7 @@ static void *clone_func(void *arg) 26 | cpu = ENV_GET_CPU(env); 27 | thread_cpu = cpu; 28 | ts = (TaskState *)cpu->opaque; 29 | - info->tid = gettid(); 30 | + info->tid = sys_gettid(); 31 | task_settid(ts); 32 | if (info->child_tidptr) 33 | put_user_u32(info->tid, info->child_tidptr); 34 | @@ -5529,9 +5533,9 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp, 35 | mapping. We can't repeat the spinlock hack used above because 36 | the child process gets its own copy of the lock. */ 37 | if (flags & CLONE_CHILD_SETTID) 38 | - put_user_u32(gettid(), child_tidptr); 39 | + put_user_u32(sys_gettid(), child_tidptr); 40 | if (flags & CLONE_PARENT_SETTID) 41 | - put_user_u32(gettid(), parent_tidptr); 42 | + put_user_u32(sys_gettid(), parent_tidptr); 43 | ts = (TaskState *)cpu->opaque; 44 | if (flags & CLONE_SETTLS) 45 | cpu_set_tls (env, newtls); 46 | @@ -10529,7 +10533,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, 47 | return TARGET_PAGE_SIZE; 48 | #endif 49 | case TARGET_NR_gettid: 50 | - return get_errno(gettid()); 51 | + return get_errno(sys_gettid()); 52 | #ifdef TARGET_NR_readahead 53 | case TARGET_NR_readahead: 54 | #if TARGET_ABI_BITS == 32 55 | @@ -10813,8 +10817,19 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, 56 | return get_errno(safe_tkill((int)arg1, target_to_host_signal(arg2))); 57 | 58 | case TARGET_NR_tgkill: 59 | - return get_errno(safe_tgkill((int)arg1, (int)arg2, 60 | - target_to_host_signal(arg3))); 61 | + { 62 | + int pid = (int)arg1, 63 | + tgid = (int)arg2, 64 | + sig = (int)arg3; 65 | + 66 | + /* Not entirely sure if the below is correct for all architectures. */ 67 | + 68 | + if(afl_forksrv_pid && afl_forksrv_pid == pid && sig == SIGABRT) 69 | + pid = tgid = getpid(); 70 | + 71 | + ret = get_errno(safe_tgkill(pid, tgid, target_to_host_signal(sig))); 72 | + 73 | + } 74 | 75 | #ifdef TARGET_NR_set_robust_list 76 | case TARGET_NR_set_robust_list: 77 | -------------------------------------------------------------------------------- /python_mutators/example.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | ''' 4 | Example Python Module for AFLFuzz 5 | 6 | @author: Christian Holler (:decoder) 7 | 8 | @license: 9 | 10 | This Source Code Form is subject to the terms of the Mozilla Public 11 | License, v. 2.0. If a copy of the MPL was not distributed with this 12 | file, You can obtain one at http://mozilla.org/MPL/2.0/. 13 | 14 | @contact: choller@mozilla.com 15 | ''' 16 | 17 | import random 18 | 19 | def init(seed): 20 | ''' 21 | Called once when AFLFuzz starts up. Used to seed our RNG. 22 | 23 | @type seed: int 24 | @param seed: A 32-bit random value 25 | ''' 26 | random.seed(seed) 27 | return 0 28 | 29 | def fuzz(buf, add_buf): 30 | ''' 31 | Called per fuzzing iteration. 32 | 33 | @type buf: bytearray 34 | @param buf: The buffer that should be mutated. 35 | 36 | @type add_buf: bytearray 37 | @param add_buf: A second buffer that can be used as mutation source. 38 | 39 | @rtype: bytearray 40 | @return: A new bytearray containing the mutated data 41 | ''' 42 | ret = bytearray(buf) 43 | # Do something interesting with ret 44 | 45 | return ret 46 | 47 | # Uncomment and implement the following methods if you want to use a custom 48 | # trimming algorithm. See also the documentation for a better API description. 49 | 50 | # def init_trim(buf): 51 | # ''' 52 | # Called per trimming iteration. 53 | # 54 | # @type buf: bytearray 55 | # @param buf: The buffer that should be trimmed. 56 | # 57 | # @rtype: int 58 | # @return: The maximum number of trimming steps. 59 | # ''' 60 | # global ... 61 | # 62 | # # Initialize global variables 63 | # 64 | # # Figure out how many trimming steps are possible. 65 | # # If this is not possible for your trimming, you can 66 | # # return 1 instead and always return 0 in post_trim 67 | # # until you are done (then you return 1). 68 | # 69 | # return steps 70 | # 71 | # def trim(): 72 | # ''' 73 | # Called per trimming iteration. 74 | # 75 | # @rtype: bytearray 76 | # @return: A new bytearray containing the trimmed data. 77 | # ''' 78 | # global ... 79 | # 80 | # # Implement the actual trimming here 81 | # 82 | # return bytearray(...) 83 | # 84 | # def post_trim(success): 85 | # ''' 86 | # Called after each trimming operation. 87 | # 88 | # @type success: bool 89 | # @param success: Indicates if the last trim operation was successful. 90 | # 91 | # @rtype: int 92 | # @return: The next trim index (0 to max number of steps) where max 93 | # number of steps indicates the trimming is done. 94 | # ''' 95 | # global ... 96 | # 97 | # if not success: 98 | # # Restore last known successful input, determine next index 99 | # else: 100 | # # Just determine the next index, based on what was successfully 101 | # # removed in the last step 102 | # 103 | # return next_index 104 | -------------------------------------------------------------------------------- /libtokencap/README.tokencap.md: -------------------------------------------------------------------------------- 1 | # strcmp() / memcmp() token capture library 2 | 3 | (See ../docs/README for the general instruction manual.) 4 | 5 | This companion library allows you to instrument `strcmp()`, `memcmp()`, 6 | and related functions to automatically extract syntax tokens passed to any of 7 | these libcalls. The resulting list of tokens may be then given as a starting 8 | dictionary to afl-fuzz (the -x option) to improve coverage on subsequent 9 | fuzzing runs. 10 | 11 | This may help improving coverage in some targets, and do precisely nothing in 12 | others. In some cases, it may even make things worse: if libtokencap picks up 13 | syntax tokens that are not used to process the input data, but that are a part 14 | of - say - parsing a config file... well, you're going to end up wasting a lot 15 | of CPU time on trying them out in the input stream. In other words, use this 16 | feature with care. Manually screening the resulting dictionary is almost 17 | always a necessity. 18 | 19 | As for the actual operation: the library stores tokens, without any deduping, 20 | by appending them to a file specified via AFL_TOKEN_FILE. If the variable is not 21 | set, the tool uses stderr (which is probably not what you want). 22 | 23 | Similarly to afl-tmin, the library is not "proprietary" and can be used with 24 | other fuzzers or testing tools without the need for any code tweaks. It does not 25 | require AFL-instrumented binaries to work. 26 | 27 | To use the library, you *need* to make sure that your fuzzing target is compiled 28 | with -fno-builtin and is linked dynamically. If you wish to automate the first 29 | part without mucking with CFLAGS in Makefiles, you can set AFL_NO_BUILTIN=1 30 | when using afl-gcc. This setting specifically adds the following flags: 31 | 32 | ``` 33 | -fno-builtin-strcmp -fno-builtin-strncmp -fno-builtin-strcasecmp 34 | -fno-builtin-strcasencmp -fno-builtin-memcmp -fno-builtin-strstr 35 | -fno-builtin-strcasestr 36 | ``` 37 | 38 | The next step is simply loading this library via LD_PRELOAD. The optimal usage 39 | pattern is to allow afl-fuzz to fuzz normally for a while and build up a corpus, 40 | and then fire off the target binary, with libtokencap.so loaded, on every file 41 | found by AFL in that earlier run. This demonstrates the basic principle: 42 | 43 | ``` 44 | export AFL_TOKEN_FILE=$PWD/temp_output.txt 45 | 46 | for i in /queue/id*; do 47 | LD_PRELOAD=/path/to/libtokencap.so \ 48 | /path/to/target/program [...params, including $i...] 49 | done 50 | 51 | sort -u temp_output.txt >afl_dictionary.txt 52 | ``` 53 | 54 | If you don't get any results, the target library is probably not using strcmp() 55 | and memcmp() to parse input; or you haven't compiled it with -fno-builtin; or 56 | the whole thing isn't dynamically linked, and LD_PRELOAD is having no effect. 57 | 58 | Portability hints: There is probably no particularly portable and non-invasive 59 | way to distinguish between read-only and read-write memory mappings. 60 | The `__tokencap_load_mappings()` function is the only thing that would 61 | need to be changed for other OSes. 62 | 63 | Current supported OSes are: Linux, Darwin, FreeBSD (thanks to @devnexen) 64 | 65 | -------------------------------------------------------------------------------- /experimental/crash_triage/triage_crashes.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # american fuzzy lop - crash triage utility 4 | # ----------------------------------------- 5 | # 6 | # Written by Michal Zalewski 7 | # 8 | # Copyright 2013, 2014, 2017 Google Inc. All rights reserved. 9 | # 10 | # Licensed under the Apache License, Version 2.0 (the "License"); 11 | # you may not use this file except in compliance with the License. 12 | # You may obtain a copy of the License at: 13 | # 14 | # http://www.apache.org/licenses/LICENSE-2.0 15 | # 16 | # Note that this assumes that the targeted application reads from stdin 17 | # and requires no other cmdline parameters. Modify as needed if this is 18 | # not the case. 19 | # 20 | # Note that on OpenBSD, you may need to install a newer version of gdb 21 | # (e.g., from ports). You can set GDB=/some/path to point to it if 22 | # necessary. 23 | # 24 | 25 | echo "crash triage utility for afl-fuzz by Michal Zalewski" 26 | echo 27 | 28 | ulimit -v 100000 2>/dev/null 29 | ulimit -d 100000 2>/dev/null 30 | 31 | if [ "$#" -lt "2" ]; then 32 | echo "Usage: $0 /path/to/afl_output_dir /path/to/tested_binary [...target params...]" 1>&2 33 | echo 1>&2 34 | exit 1 35 | fi 36 | 37 | DIR="$1" 38 | BIN="$2" 39 | shift 40 | shift 41 | 42 | if [ "$AFL_ALLOW_TMP" = "" ]; then 43 | 44 | echo "$DIR" | grep -qE '^(/var)?/tmp/' 45 | T1="$?" 46 | 47 | echo "$BIN" | grep -qE '^(/var)?/tmp/' 48 | T2="$?" 49 | 50 | if [ "$T1" = "0" -o "$T2" = "0" ]; then 51 | echo "[-] Error: do not use shared /tmp or /var/tmp directories with this script." 1>&2 52 | exit 1 53 | fi 54 | 55 | fi 56 | 57 | if 58 | [ "$GDB" = "" ]; then 59 | GDB=gdb 60 | fi 61 | 62 | if [ ! -f "$BIN" -o ! -x "$BIN" ]; then 63 | echo "[-] Error: binary '$2' not found or is not executable." 1>&2 64 | exit 1 65 | fi 66 | 67 | if [ ! -d "$DIR/queue" ]; then 68 | echo "[-] Error: directory '$1' not found or not created by afl-fuzz." 1>&2 69 | exit 1 70 | fi 71 | 72 | CCOUNT=$((`ls -- "$DIR/crashes" 2>/dev/null | wc -l`)) 73 | 74 | if [ "$CCOUNT" = "0" ]; then 75 | echo "No crashes recorded in the target directory - nothing to be done." 76 | exit 0 77 | fi 78 | 79 | echo 80 | 81 | for crash in $DIR/crashes/id:*; do 82 | 83 | id=`basename -- "$crash" | cut -d, -f1 | cut -d: -f2` 84 | sig=`basename -- "$crash" | cut -d, -f2 | cut -d: -f2` 85 | 86 | # Grab the args, converting @@ to $crash 87 | 88 | use_args="" 89 | use_stdio=1 90 | 91 | for a in $@; do 92 | 93 | if [ "$a" = "@@" ] ; then 94 | args="$use_args $crash" 95 | unset use_stdio 96 | else 97 | args="$use_args $a" 98 | fi 99 | 100 | done 101 | 102 | # Strip the trailing space 103 | use_args="${use_args# }" 104 | 105 | echo "+++ ID $id, SIGNAL $sig +++" 106 | echo 107 | 108 | if [ "$use_stdio" = "1" ]; then 109 | $GDB --batch -q --ex "r $use_args <$crash" --ex 'back' --ex 'disass $pc, $pc+16' --ex 'info reg' --ex 'quit' "$BIN" 0 /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 | -------------------------------------------------------------------------------- /experimental/persistent_demo/persistent_demo.c: -------------------------------------------------------------------------------- 1 | /* 2 | american fuzzy lop - persistent mode example 3 | -------------------------------------------- 4 | 5 | Written by Michal Zalewski 6 | 7 | Copyright 2015 Google Inc. All rights reserved. 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at: 12 | 13 | http://www.apache.org/licenses/LICENSE-2.0 14 | 15 | This file demonstrates the high-performance "persistent mode" that may be 16 | suitable for fuzzing certain fast and well-behaved libraries, provided that 17 | they are stateless or that their internal state can be easily reset 18 | across runs. 19 | 20 | To make this work, the library and this shim need to be compiled in LLVM 21 | mode using afl-clang-fast (other compiler wrappers will *not* work). 22 | 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | /* Main entry point. */ 32 | 33 | int main(int argc, char** argv) { 34 | 35 | ssize_t len; /* how much input did we read? */ 36 | char buf[100]; /* Example-only buffer, you'd replace it with other global or 37 | local variables appropriate for your use case. */ 38 | 39 | /* The number passed to __AFL_LOOP() controls the maximum number of 40 | iterations before the loop exits and the program is allowed to 41 | terminate normally. This limits the impact of accidental memory leaks 42 | and similar hiccups. */ 43 | 44 | while (__AFL_LOOP(1000)) { 45 | 46 | /*** PLACEHOLDER CODE ***/ 47 | 48 | /* STEP 1: Fully re-initialize all critical variables. In our example, this 49 | involves zeroing buf[], our input buffer. */ 50 | 51 | memset(buf, 0, 100); 52 | 53 | /* STEP 2: Read input data. When reading from stdin, no special preparation 54 | is required. When reading from a named file, you need to close 55 | the old descriptor and reopen the file first! 56 | 57 | Beware of reading from buffered FILE* objects such as stdin. Use 58 | raw file descriptors or call fopen() / fdopen() in every pass. */ 59 | 60 | len = read(0, buf, 100); 61 | 62 | /* STEP 3: This is where we'd call the tested library on the read data. 63 | We just have some trivial inline code that faults on 'foo!'. */ 64 | 65 | /* do we have enough data? */ 66 | if (len < 4) return 0; 67 | 68 | if (buf[0] == 'f') { 69 | 70 | printf("one\n"); 71 | if (buf[1] == 'o') { 72 | 73 | printf("two\n"); 74 | if (buf[2] == 'o') { 75 | 76 | printf("three\n"); 77 | if (buf[3] == '!') { 78 | 79 | printf("four\n"); 80 | abort(); 81 | 82 | } 83 | 84 | } 85 | 86 | } 87 | 88 | } 89 | 90 | /*** END PLACEHOLDER CODE ***/ 91 | 92 | } 93 | 94 | /* Once the loop is exited, terminate normally - AFL will restart the process 95 | when this happens, with a clean slate when it comes to allocated memory, 96 | leftover file descriptors, etc. */ 97 | 98 | return 0; 99 | 100 | } 101 | 102 | -------------------------------------------------------------------------------- /experimental/post_library/post_library_png.so.c: -------------------------------------------------------------------------------- 1 | /* 2 | american fuzzy lop - postprocessor for PNG 3 | ------------------------------------------ 4 | 5 | Written by Michal Zalewski 6 | 7 | Copyright 2015 Google Inc. All rights reserved. 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at: 12 | 13 | http://www.apache.org/licenses/LICENSE-2.0 14 | 15 | See post_library.so.c for a general discussion of how to implement 16 | postprocessors. This specific postprocessor attempts to fix up PNG 17 | checksums, providing a slightly more complicated example than found 18 | in post_library.so.c. 19 | 20 | Compile with: 21 | 22 | gcc -shared -Wall -O3 post_library_png.so.c -o post_library_png.so -lz 23 | 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #include 33 | 34 | /* A macro to round an integer up to 4 kB. */ 35 | 36 | #define UP4K(_i) ((((_i) >> 12) + 1) << 12) 37 | 38 | const unsigned char* afl_postprocess(const unsigned char* in_buf, 39 | unsigned int* len) { 40 | 41 | static unsigned char* saved_buf; 42 | static unsigned int saved_len; 43 | 44 | unsigned char* new_buf = (unsigned char*)in_buf; 45 | unsigned int pos = 8; 46 | 47 | /* Don't do anything if there's not enough room for the PNG header 48 | (8 bytes). */ 49 | 50 | if (*len < 8) return in_buf; 51 | 52 | /* Minimum size of a zero-length PNG chunk is 12 bytes; if we 53 | don't have that, we can bail out. */ 54 | 55 | while (pos + 12 <= *len) { 56 | 57 | unsigned int chunk_len, real_cksum, file_cksum; 58 | 59 | /* Chunk length is the first big-endian dword in the chunk. */ 60 | 61 | chunk_len = ntohl(*(uint32_t*)(in_buf + pos)); 62 | 63 | /* Bail out if chunk size is too big or goes past EOF. */ 64 | 65 | if (chunk_len > 1024 * 1024 || pos + 12 + chunk_len > *len) break; 66 | 67 | /* Chunk checksum is calculated for chunk ID (dword) and the actual 68 | payload. */ 69 | 70 | real_cksum = htonl(crc32(0, in_buf + pos + 4, chunk_len + 4)); 71 | 72 | /* The in-file checksum is the last dword past the chunk data. */ 73 | 74 | file_cksum = *(uint32_t*)(in_buf + pos + 8 + chunk_len); 75 | 76 | /* If the checksums do not match, we need to fix the file. */ 77 | 78 | if (real_cksum != file_cksum) { 79 | 80 | /* First modification? Make a copy of the input buffer. Round size 81 | up to 4 kB to minimize the number of reallocs needed. */ 82 | 83 | if (new_buf == in_buf) { 84 | 85 | if (*len <= saved_len) { 86 | 87 | new_buf = saved_buf; 88 | 89 | } else { 90 | 91 | new_buf = realloc(saved_buf, UP4K(*len)); 92 | if (!new_buf) return in_buf; 93 | saved_buf = new_buf; 94 | saved_len = UP4K(*len); 95 | memcpy(new_buf, in_buf, *len); 96 | 97 | } 98 | 99 | } 100 | 101 | *(uint32_t*)(new_buf + pos + 8 + chunk_len) = real_cksum; 102 | 103 | } 104 | 105 | /* Skip the entire chunk and move to the next one. */ 106 | 107 | pos += 12 + chunk_len; 108 | 109 | } 110 | 111 | return new_buf; 112 | 113 | } 114 | 115 | -------------------------------------------------------------------------------- /python_mutators/wrapper_afl_min.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from XmlMutatorMin import XmlMutatorMin 4 | 5 | # Default settings (production mode) 6 | 7 | __mutator__ = None 8 | __seed__ = "RANDOM" 9 | __log__ = False 10 | __log_file__ = "wrapper.log" 11 | 12 | # AFL functions 13 | 14 | def log(text): 15 | """ 16 | Logger 17 | """ 18 | 19 | global __seed__ 20 | global __log__ 21 | global __log_file__ 22 | 23 | if __log__: 24 | with open(__log_file__, "a") as logf: 25 | logf.write("[%s] %s\n" % (__seed__, text)) 26 | 27 | def init(seed): 28 | """ 29 | Called once when AFL starts up. Seed is used to identify the AFL instance in log files 30 | """ 31 | 32 | global __mutator__ 33 | global __seed__ 34 | 35 | # Get the seed 36 | __seed__ = seed 37 | 38 | # Create a global mutation class 39 | try: 40 | __mutator__ = XmlMutatorMin(__seed__, verbose=__log__) 41 | log("init(): Mutator created") 42 | except RuntimeError as e: 43 | log("init(): Can't create mutator: %s" % e.message) 44 | 45 | def fuzz(buf, add_buf): 46 | """ 47 | Called for each fuzzing iteration. 48 | """ 49 | 50 | global __mutator__ 51 | 52 | # Do we have a working mutator object? 53 | if __mutator__ is None: 54 | log("fuzz(): Can't fuzz, no mutator available") 55 | return buf 56 | 57 | # Try to use the AFL buffer 58 | via_buffer = True 59 | 60 | # Interpret the AFL buffer (an array of bytes) as a string 61 | if via_buffer: 62 | try: 63 | buf_str = str(buf) 64 | log("fuzz(): AFL buffer converted to a string") 65 | except: 66 | via_buffer = False 67 | log("fuzz(): Can't convert AFL buffer to a string") 68 | 69 | # Load XML from the AFL string 70 | if via_buffer: 71 | try: 72 | __mutator__.init_from_string(buf_str) 73 | log("fuzz(): Mutator successfully initialized with AFL buffer (%d bytes)" % len(buf_str)) 74 | except: 75 | via_buffer = False 76 | log("fuzz(): Can't initialize mutator with AFL buffer") 77 | 78 | # If init from AFL buffer wasn't succesful 79 | if not via_buffer: 80 | log("fuzz(): Returning unmodified AFL buffer") 81 | return buf 82 | 83 | # Sucessful initialization -> mutate 84 | try: 85 | __mutator__.mutate(max=5) 86 | log("fuzz(): Input mutated") 87 | except: 88 | log("fuzz(): Can't mutate input => returning buf") 89 | return buf 90 | 91 | # Convert mutated data to a array of bytes 92 | try: 93 | data = bytearray(__mutator__.save_to_string()) 94 | log("fuzz(): Mutated data converted as bytes") 95 | except: 96 | log("fuzz(): Can't convert mutated data to bytes => returning buf") 97 | return buf 98 | 99 | # Everything went fine, returning mutated content 100 | log("fuzz(): Returning %d bytes" % len(data)) 101 | return data 102 | 103 | # Main (for debug) 104 | 105 | if __name__ == '__main__': 106 | 107 | __log__ = True 108 | __log_file__ = "/dev/stdout" 109 | __seed__ = "RANDOM" 110 | 111 | init(__seed__) 112 | 113 | in_1 = bytearray("ffffzzzzzzzzzzzz") 114 | in_2 = bytearray("") 115 | out = fuzz(in_1, in_2) 116 | print(out) 117 | 118 | -------------------------------------------------------------------------------- /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="