# REQUIREMENTS # * A POSIX compliant operating system, MacOSX, [Android](https://github.com/google/honggfuzz/blob/master/docs/Android.md) or Windows (CygWin) * GNU/Linux with modern kernel (>= v4.2) for hardware-based code coverage guided fuzzing (intel PT, Intel BTS, instruction/branch counting) * An input corpus: You might be interested in the following for some common file formats: * Image formats: Tavis Ormandy's [Image Testsuite](http://code.google.com/p/imagetestsuite/) has been effective at finding vulnerabilities in various graphics libraries. * PDF: Adobe provides some [test PDF files](http://acroeng.adobe.com/). * _**Note**: With the feedback-driven coverage-based modes, you can start your fuzzing without the input corpus._ ## Compatibility list ## It should work under the following operating systems: | **OS** | **Status** | **Notes** | |:-------|:-----------|:----------| | **GNU/Linux** | Works | ptrace() API (x86, x86-64 disassembly support)| | **FreeBSD** | Works | POSIX signal interface | | **OpenBSD** | Works | POSIX signal interface | | **NetBSD** | Works | ptrace() API (x86, x86-64 disassembly support)| | **Mac OS X** | Works | POSIX signal interface/Mac OS X crash reports (x86-64/x86 disassembly support) | | **Android** | Works | ptrace() API (x86, x86-64 disassembly support) | | **MS Windows** | Works | POSIX signal interface via CygWin | | **Other Unices** | Maybe | POSIX signal interface | # USAGE # ## Non-persistent fuzzing w/o instrumentation (```-x```) ## ### Input as a file (```___FILE___```) ### ```shell honggfuzz -i input_dir -x -- /usr/bin/djpeg ___FILE___ ``` ### Input on FD=0/STDIN (```-s```/```--stdin_input```) #### ```shell honggfuzz -i input_dir -x -s -- /usr/bin/djpeg ``` ## Non-persistent fuzzing with instrumentation ## ### Compile-time instrumentation (```-z```/```--instrument```). _Note: it is enabled by default_ ### ```shell honggfuzz -i input_dir -z -- instrumented.djpeg ___FILE___ ``` ### QEMU-mode (black-box instrumentation) ### ```shell honggfuzz -i input_dir -- /qemu_mode/honggfuzz-qemu/x86_64-linux-user/qemu-x86_64 /usr/bin/djpeg ___FILE___ ``` ### Various hardware-based mechanisms/counters ### ```shell honggfuzz -i input_dir --linux_perf_bts_edge -- /usr/bin/djpeg ___FILE___ honggfuzz -i input_dir --linux_perf_ipt_block -- /usr/bin/djpeg ___FILE___ honggfuzz -i input_dir --linux_perf_instr -- /usr/bin/djpeg ___FILE___ honggfuzz -i input_dir --linux_perf_branch -- /usr/bin/djpeg ___FILE___ ``` ## Persistent-mode (```-P```). _Note: it will be auto-detected_ ## ```shell honggfuzz -i input_dir -z -P -- jpeg_persistent_mode honggfuzz -i input_dir --linux_perf_bts_edge -P -- jpeg_persistent_mode honggfuzz -i input_dir --linux_perf_ipt_block -P -- jpeg_persistent_mode honggfuzz -i input_dir --linux_perf_branch -P -- jpeg_persistent_mode honggfuzz -i input_dir --linux_perf_instr -P -- jpeg_persistent_mode ``` but also a couple of instrumentation mechanisms used together ```shell honggfuzz -i input_dir --linux_perf_bts_edge --linux_perf_instr -P -- jpeg_persistent_mode ``` ## Corpus Minimization (```-M```) ## ### Minimize corpus directly inside the input (```-i```/```--input```) directory ### ```shell honggfuzz -i input_dir -P -M -- jpeg_persistent_mode ``` or ```shell honggfuzz -i input_dir -M -- instrumented.djpeg ___FILE___ ``` ### Save minimized corpus to the output (```--output```) directory ### ```shell honggfuzz -i input_dir --output output_dir -P -M -- jpeg_persistent_mode ``` or ```shell honggfuzz -i input_dir --output output_dir -M -- instrumented.djpeg ___FILE___ ``` # CMDLINE ```--help``` # ```shell Usage: ./honggfuzz [options] -- path_to_command [args] Options: --help|-h Help plz.. --input|-i VALUE Path to a directory containing initial file corpus --output VALUE Output data (new dynamic coverage corpus, or the minimized coverage corpus) is written to this directory (default: input directory is used) --persistent|-P Enable persistent fuzzing (use hfuzz_cc/hfuzz-clang to compile code). This will be auto-detected!!! --instrument|-z *DEFAULT-MODE-BY-DEFAULT* Enable compile-time instrumentation (use hfuzz_cc/hfuzz-clang to compile code) --minimize|-M Minimize the input corpus. It will most likely delete some corpus files (from the --input directory) if no --output is used! --noinst|-x Static mode only, disable any instrumentation (hw/sw) feedback --keep_output|-Q Don't close children's stdin, stdout, stderr; can be noisy --timeout|-t VALUE Timeout in seconds (default: 10) --threads|-n VALUE Number of concurrent fuzzing threads (default: number of CPUs / 2) --stdin_input|-s Provide fuzzing input on STDIN, instead of ___FILE___ --mutations_per_run|-r VALUE Maximal number of mutations per one run (default: 6) --logfile|-l VALUE Log file --verbose|-v Disable ANSI console; use simple log output --verifier|-V Enable crashes verifier --debug|-d Show debug messages (level >= 4) --quiet|-q Show only warnings and more serious messages (level <= 1) --extension|-e VALUE Input file extension (e.g. 'swf'), (default: 'fuzz') --workspace|-W VALUE Workspace directory to save crashes & runtime files (default: '.') --crashdir VALUE Directory where crashes are saved to (default: workspace directory) --covdir_all VALUE ** DEPRECATED ** use --output --covdir_new VALUE New coverage (beyond the dry-run fuzzing phase) is written to this separate directory --dict|-w VALUE Dictionary file. Format:http://llvm.org/docs/LibFuzzer.html#dictionaries --stackhash_bl|-B VALUE Stackhashes blacklist file (one entry per line) --mutate_cmd|-c VALUE External command producing fuzz files (instead of internal mutators) --pprocess_cmd VALUE External command postprocessing files produced by internal mutators --ffmutate_cmd VALUE External command mutating files which have effective coverage feedback --run_time VALUE Number of seconds this fuzzing session will last (default: 0 [no limit]) --iterations|-N VALUE Number of fuzzing iterations (default: 0 [no limit]) --rlimit_as VALUE Per process RLIMIT_AS in MiB (default: 0 [no limit]) --rlimit_rss VALUE Per process RLIMIT_RSS in MiB (default: 0 [no limit]). It will also set *SAN's soft_rss_limit_mb if used --rlimit_data VALUE Per process RLIMIT_DATA in MiB (default: 0 [no limit]) --rlimit_core VALUE Per process RLIMIT_CORE in MiB (default: 0 [no cores are produced]) --report|-R VALUE Write report to this file (default: '/HONGGFUZZ.REPORT.TXT') --max_file_size|-F VALUE Maximal size of files processed by the fuzzer in bytes (default: 1048576 = 1MB) --clear_env Clear all environment variables before executing the binary --env|-E VALUE Pass this environment variable, can be used multiple times --save_all|-u Save all test-cases (not only the unique ones) by appending the current time-stamp to the filenames --save_smaller|-U Save smaller test-cases, renaming first found with .orig suffix --tmout_sigvtalrm|-T Use SIGVTALRM to kill timeouting processes (default: use SIGKILL) --sanitizers|-S Enable sanitizers settings (default: false) --monitor_sigabrt VALUE Monitor SIGABRT (default: false for Android, true for other platforms) --no_fb_timeout VALUE Skip feedback if the process has timeouted (default: false) --exit_upon_crash Exit upon seeing the first crash (default: false) --socket_fuzzer Instrument external fuzzer via socket --netdriver Use netdriver (libhfnetdriver/). In most cases it will be autodetected through a binary signature --only_printable Only generate printable inputs --linux_symbols_bl VALUE Symbols blacklist filter file (one entry per line) --linux_symbols_wl VALUE Symbols whitelist filter file (one entry per line) --linux_addr_low_limit VALUE Address limit (from si.si_addr) below which crashes are not reported, (default: 0) --linux_keep_aslr Don't disable ASLR randomization, might be useful with MSAN --linux_perf_ignore_above VALUE Ignore perf events which report IPs above this address --linux_perf_instr Use PERF_COUNT_HW_INSTRUCTIONS perf --linux_perf_branch Use PERF_COUNT_HW_BRANCH_INSTRUCTIONS perf --linux_perf_bts_edge Use Intel BTS to count unique edges --linux_perf_ipt_block Use Intel Processor Trace to count unique blocks (requires libipt.so) --linux_perf_kernel_only Gather kernel-only coverage with Intel PT and with Intel BTS --linux_ns_net Use Linux NET namespace isolation --linux_ns_pid Use Linux PID namespace isolation --linux_ns_ipc Use Linux IPC namespace isolation Examples: Run the binary over a mutated file chosen from the directory. Disable fuzzing feedback (static mode): honggfuzz -i input_dir -x -- /usr/bin/djpeg ___FILE___ As above, provide input over STDIN: honggfuzz -i input_dir -x -s -- /usr/bin/djpeg Use compile-time instrumentation (-fsanitize-coverage=trace-pc-guard,...): honggfuzz -i input_dir -- /usr/bin/djpeg ___FILE___ Use persistent mode w/o instrumentation: honggfuzz -i input_dir -P -x -- /usr/bin/djpeg_persistent_mode Use persistent mode and compile-time (-fsanitize-coverage=trace-pc-guard,...) instrumentation: honggfuzz -i input_dir -P -- /usr/bin/djpeg_persistent_mode Run the binary with dynamically generate inputs, maximize total no. of instructions: honggfuzz --linux_perf_instr -- /usr/bin/djpeg ___FILE___ As above, maximize total no. of branches: honggfuzz --linux_perf_branch -- /usr/bin/djpeg ___FILE___ As above, maximize unique branches (edges) via Intel BTS: honggfuzz --linux_perf_bts_edge -- /usr/bin/djpeg ___FILE___ As above, maximize unique code blocks via Intel Processor Trace (requires libipt.so): honggfuzz --linux_perf_ipt_block -- /usr/bin/djpeg ___FILE___ ``` # OUTPUT FILES # | **Mode** | **Output file** | |:---------|:----------------| | Linux,NetBSD | **SIGSEGV.PC.4ba1ae.STACK.13599d485.CODE.1.ADDR.0x10.INSTR.mov____0x10(%rbx),%rax.fuzz** | | POSIX signal interface | **SIGSEGV.22758.2010-07-01.17.24.41.tif** | ## Description ## * **SIGSEGV**,**SIGILL**,**SIGBUS**,**SIGABRT**,**SIGFPE** - Description of the signal which terminated the process (when using ptrace() API, it's a signal which was delivered to the process, even if silently discarded) * **PC.0x8056ad7** - Program Counter (PC) value (ptrace() API only), for x86 it's a value of the EIP register (RIP for x86-64) * **STACK.13599d485** - Stack signature (based on stack-tracing) * **ADDR.0x30333037** - Value of the ```_siginfo_t.si_addr_``` (see _man 2 signaction_ for more details) (most likely meaningless for SIGABRT) * **INSTR.mov____0x10(%rbx),%rax** - Disassembled instruction which was found under the last known PC (Program Counter) (x86, x86-64 architectures only, meaningless for SIGABRT) # FAQ # * Q: **Why the name _honggfuzz_**? * A: The term honggfuzz was coined during a major and memorable event in the city of [Zurich](http://en.wikipedia.org/wiki/H%C3%B6ngg), where a Welsh security celebrity tried to reach Höngg in a cab while singing _[Another one bites the dust](https://en.wikipedia.org/wiki/Another_One_Bites_the_Dust)_. * Q: **Why do you prefer the ptrace() API to the POSIX signal interface**? * A: The ptrace() API is more flexible when it comes to analyzing a process' crash. wait3/4() syscalls are only able to determine the type of signal which crashed an application and limited resource usage information (see _man wait4_). * Q: **Why isn't there any support for the ptrace() API when compiling under FreeBSD or Mac OS X operating systems**? * A: These operating systems lack some specific ptrace() operations, including ```PT_GETREGS``` (Mac OS X) and ```PT_GETSIGINFO```, both of which honggfuzz depends on. If you have any ideas on how to get around this limitation, send us an email or patch. # LICENSE # This project is licensed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) # CREDITS # * Thanks to **[taviso@google.com Tavis Ormandy]** for many valuable ideas used in the course of this project's design and implementation phases * Thanks to my 1337 friends for all sorts of support and distraction :) - **LiquidK, lcamtuf, novocainated, asiraP, ScaryBeasts, redpig, jln**