honggfuzz

repository·master·Indexed 25 days ago

https://github.com/google/honggfuzz

A security-oriented, feedback-driven, evolutionary fuzzer designed to find bugs using software and hardware-based code coverage. It supports multi-process, multi-threaded execution and persistent fuzzing for high-performance testing. The project includes instrumentation wrappers like hfuzz-clang and hfuzz-gcc, and provides examples for fuzzing targets such as Apache 2.4, ISC BIND, libmagic, glibc, libjpeg, OpenSSL, and terminal emulators.

Tokens
9.6K
Snippets
26
Records
53
Agent score
83%

What's inside honggfuzz

  1. Understand the Honggfuzz feedback-driven fuzzing strategy

    master

    Honggfuzz uses a two-phase strategy to improve the input corpus based on code coverage:

    1. Initial Corpus Processing: Honggfuzz iterates through every file in the initial corpus directory (provided via -i). Files that trigger new code coverage are added to a dynamic in-memory corpus.
    2. Dynamic Mutation: Honggfuzz randomly selects files from the in-memory corpus, mutates them, and runs a fuzzing round. If a mutation results in new code coverage, that input is also added to the dynamic corpus for future rounds.
  2. Prepare and build Apache for fuzzing

    master

    Follow these steps to prepare the Apache environment for fuzzing:

    1. Compile honggfuzz.
    2. Download and unpack the required packages: apr, apr-util, nghttp2, and httpd.
    3. Patch Apache: Apply the provided honggfuzz patch to the Apache source directory.
    4. Build Apache: Use the provided script compile_and_install.asan.sh. Note: You must edit this script first to ensure it contains the correct paths and versions for your specific build environment.
    5. Configure Apache: Copy the custom configuration files httpd.conf.h1 and httpd.conf.h2 to your Apache distribution's configuration directory (e.g., /home/$USER/fuzz/apache/apache2/conf/).
    6. Finalize Config: Edit httpd.conf.h1 and httpd.conf.h2 to ensure all internal configuration paths are valid for your system.
  3. Instrument a terminal emulator for fuzzing

    master

    You must instrument the target terminal emulator at compile-time using hfuzz-clang.

    To enable AddressSanitizer (ASAN) for better memory corruption detection, set the HFUZ_CC_ASAN=1 environment variable during the configuration and build process.

    # Standard instrumentation
    $ cd xterm-327
    $ CC=/home/jagger/src/honggfuzz/hfuzz_cc/hfuzz-clang CXX=$CC ./configure
    $ CC=/home/jagger/src/honggfuzz/hfuzz_cc/hfuzz-clang CXX=$CC make -j4
    
    # Instrumentation with ASAN enabled
    $ cd xterm-327
    $ HFUZZ_CC_ASAN=1 CC=/home/jagger/src/honggfuzz/hfuzz_cc/hfuzz-clang CXX=$CC ./configure
    $ HFUZZ_CC_ASAN=1 CC=/home/jagger/src/honggfuzz/hfuzz_cc/hfuzz-clang CXX=$CC make -j4
  4. Instrument a target using hfuzz_cc wrappers

    master

    Before fuzzing, you must compile your target using the provided Honggfuzz compiler wrappers to add the necessary code coverage instrumentation.

    For C code: Use ./hfuzz_cc/hfuzz-clang.

    For C++ code: Use ./hfuzz_cc/hfuzz-clang++.

    # C code
    ./hfuzz_cc/hfuzz-clang -o my_target my_target.c
    
    # C++ code
    ./hfuzz_cc/hfuzz-clang++ -o my_target my_target.cpp
  5. Compile and link the persistent-file fuzzer target

    master

    Once the library is compiled, you can create the fuzzer target (persistent-file.c) by linking it against the instrumented static library (libmagic.a) using the hfuzz-clang wrapper. You must also link against lz if required by the library.

    $ honggfuzz/hfuzz_cc/hfuzz-clang -I ./file-5.37/ honggfuzz/examples/file/persistent-file.c -o persistent-file ./file-5.37/src/.libs/libmagic.a -lz
  6. Run Persistent-mode Fuzzing

    master
    Persistent mode (-P) improves fuzzing efficiency by running the target in a loop within a single process. This mode is automatically detected by Honggfuzz. It is recommended to use persistent mode in conjunction with instrumentation for maximum effectiveness.
  7. Compile a target program for glibc fuzzing

    master

    When fuzzing glibc-based programs, use the hfuzz-gcc wrapper provided in hfuzz_cc/. You must link against the custom-built glibc libraries and the Honggfuzz library (libhfuzz.a).

    Ensure you include the necessary library paths for the custom glibc build (e.g., build, nptl, rt, and resolv) and use flags like -nodefaultlibs and -static to ensure the target uses your instrumented glibc rather than the system glibc.

    ~/src/honggfuzz/hfuzz-cc/hfuzz-gcc -Wl,-z,muldefs -nodefaultlibs -I ~/src/honggfuzz/ ~/src/honggfuzz/examples/glibc/resolver.c -o resolver -L ~/src/glibc-2.26/build -L ~/src/glibc-2.26/build/nptl -L ~/src/glibc-2.26/rt -L ~/src/glibc-2.26/build/resolv ~/src/honggfuzz/libhfuzz/libhfuzz.a -lc -static -lgcc -lpthread -lgcc_eh -lc
  8. Minimize the Input Corpus

    master

    Corpus minimization (-M or --minimize) reduces the input corpus to the smallest set of files that still provide the same coverage.

    • Minimize in-place: If no --output is specified, Honggfuzz will likely delete files from the --input directory to achieve minimization.
    • Save to output directory: Use the --output flag to preserve the original corpus and save the minimized version elsewhere.
  9. Compile and run ASAN-style persistent fuzzing

    master

    To use the ASAN-style persistent fuzzing interface, compile your source code using the hfuzz_cc/hfuzz-clang wrapper and run it with the -P flag in honggfuzz to enable persistent mode.

    # Compilation
    ```shell
    $ hfuzz_cc/hfuzz-clang test.c -o test

    Fuzzing

    $ honggfuzz -P -- ./test
  10. Run Non-persistent Fuzzing with Instrumentation

    master

    Instrumentation provides feedback-driven coverage to guide the fuzzer.

    • Compile-time Instrumentation: Enabled by default using the -z or --instrument flag. This requires the target to be compiled with specific instrumentation (e.g., using hfuzz_cc/hfuzz-clang).
    • QEMU-mode: Used for black-box instrumentation of binaries that cannot be recompiled. You must point to the qemu-x86_64 binary.
    • Hardware-based Mechanisms: On Linux, you can use specific performance counters for coverage:
      • --linux_perf_bts_edge: Intel BTS to count unique edges.
      • --linux_perf_ipt_block: Intel Processor Trace to count unique blocks (requires libipt.so).
      • --linux_perf_instr: Use PERF_COUNT_HW_INSTRUCTIONS.
      • --linux_perf_branch: Use PERF_COUNT_HW_BRANCH_INSTRUCTIONS.
  11. Prepare a custom glibc for fuzzing

    master

    To fuzz programs that rely on glibc, you must build a custom version of glibc instrumented with Honggfuzz wrappers.

    Requirements:

    • gcc-6 or preferably gcc-8 (released after 2017-10) for trace-cmp instrumentation support.
    • A relatively modern glibc (e.g., 2.26).

    Steps:

    1. Compile the Honggfuzz wrappers.
    2. Configure and build glibc using the compiled wrappers via the CC environment variable.

    If using gcc < 8, you must omit -fsanitize-coverage=trace-cmp from your CFLAGS as it is not supported.

  12. Run the Honggfuzz fuzzer

    master

    Run the fuzzer by pointing it to an input corpus directory and your instrumented binary.

    Basic Run Use the -i flag to specify the input directory. If your target requires a filename as an argument, use the ___FILE___ placeholder.

    Persistent Mode Use the -P flag for persistent fuzzing. This tests APIs directly in-process and is significantly faster (up to 1M/sec).

    Arguments:

    • -i <dir>: Input corpus directory (can be empty).
    • -P: Enable persistent mode.
    • --: Separator between fuzzer options and the target command.
    # Basic run
    ./honggfuzz -i input_dir/ -- ./my_target ___FILE___
    
    # Persistent mode (faster)
    ./honggfuzz -P -i input_dir/ -- ./my_target