• Stars
    star
    295
  • Rank 140,902 (Top 3 %)
  • Language
    C++
  • License
    Apache License 2.0
  • Created about 5 years ago
  • Updated over 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

FuzzGen: Automatic Fuzzer Generation

Kyriakos Ispoglou - [email protected]


      ___        ___           ___           ___           ___           ___           ___
     /\__\      /\  \         /\__\         /\__\         /\__\         /\__\         /\  \
    /:/ _/_     \:\  \       /::|  |       /::|  |       /:/ _/_       /:/ _/_        \:\  \
   /:/ /\__\     \:\  \     /:/:|  |      /:/:|  |      /:/ /\  \     /:/ /\__\        \:\  \
  /:/ /:/  / ___  \:\  \   /:/|:|  |__   /:/|:|  |__   /:/ /::\  \   /:/ /:/ _/_   _____\:\  \
 /:/_/:/  / /\  \  \:\__\ /:/ |:| /\__\ /:/ |:| /\__\ /:/__\/\:\__\ /:/_/:/ /\__\ /::::::::\__\
 \:\/:/  /  \:\  \ /:/  / \/__|:|/:/  / \/__|:|/:/  / \:\  \ /:/  / \:\/:/ /:/  / \:\~~\~~\/__/
  \::/__/    \:\  /:/  /      |:/:/  /      |:/:/  /   \:\  /:/  /   \::/_/:/  /   \:\  \
   \:\  \     \:\/:/  /       |::/  /       |::/  /     \:\/:/  /     \:\/:/  /     \:\  \
    \:\__\     \::/  /        |:/  /        |:/  /       \::/  /       \::/  /       \:\__\
     \/__/      \/__/         |/__/         |/__/         \/__/         \/__/         \/__/

                            FuzzGen - Automatic Fuzzer Generation

Introduction

FuzzGen, is a tool for automatically synthesizing fuzzers for complex libraries in a given environment. FuzzGen leverages a whole system analysis to infer the library’s interface and synthesizes fuzzers specifically for that library.

FuzzGen is fully automatic and can be applied to a wide range of libraries. The generated fuzzers leverage LibFuzzer to achieve better code coverage and expose bugs that reside deep in the library.

For more details please refer to our USENIX Security'20 paper.

Build Instructions

FuzzGen depends on Boost library, which could be installed by command sudo apt-get install libboost-all-dev or compiling from source.

To build FuzzGen, follow the classic cmake - make process:

# OPTIONAL: If you want to use a specific LLVM version
export LLVM_DIR=/path/to/llvm/build

cd $FUZZGEN_HOME_DIR
mkdir build
cd build
cmake ..
make -j$(nproc)

Note that we originally used LLVM 6 to compile the code, while it may work with other versions of LLVM, some code changes will be necessary.

Also don't forget to adjust the following MACROs in src/compose.h according to your needs:

#define ANDROID_TARGET_DEV  "aosp_walleye-userdebug"
#define ANDROID_FUZZ_DIR    "/tools/fuzzers/fuzzgen_files"
#define ANDROID_MAKE_JOBS   16

The preprocessor is a clang plugin, so building it requires more effort. First, copy the preprocessor directory under $LLVM_SRC/tools/clang/tools and change the directory name to fuzzgen, add the following line in $LLVM_SRC/tools/clang/tools/CMakeLists.txt:

add_clang_subdirectory(fuzzgen)

Then, build the LLVM again. The preprocessor plugin will show up under $BUILD_LLVM_DIR/bin directory.

Running the PreProcessor

The first step to run FuzzGen, is to generate the metadata file. To do this, run the preprocessor as follows:

    $BUILD_LLVM_DIR/bin/fuzzgen-preprocessor       \
        -outfile=$LIBNAME.meta                     \
        -library-root=/path/to/Android/home/       \ 
        $(find /path/to/all/library/source/files/) \

WARNING: In this approach we simply pass all source files in our plugin. However, it is possible for clang to fail (even if running with -fsyntax-only option) to resolve MACROs and header file names and therefore AST generation may be incomplete. That is, it is possible for some nodes in the AST to be NULL, since clang cannot properly resolve them. This in turn, will result in incomplete information in the metadata file, which is possible to cause FuzzGen to miss information during fuzzer generation. To address this issue, you can use compile_commands.json file to get the exact set of flags used to build the library, so clang will generate complete ASTs.

Obtaining the LTO for the library

The second step is to obtain the Link Time Optimization (LTO) for the target library. That is, to link all individual LLVM-IR files into a single one, so FuzzGen can analyze the whole library at once.

To do that, add the following flags to the Android.bp to emit the LLVM IR:

    cflags: [
      "-save-temps",
      "-S -emit-llvm",
      "-m64"                // for 64 bit data layouts
    ],

This will produce multiple bitcode (*.bc) files under Android's root directory. To coalesce all these bitcode files into a single one (LTO) use the llvm-link tool. This will result in a single bitcode file, but it will not be in readable format. To get the human-readable disassembled LLVM-IR (*.ll) use llvm-dis. Note that FuzzGen requires the *.ll file as input.

Obtaining the IR for the whole Android source tree

As mentioned earlier, FuzzGen performs a whole system analysis. For the Android case, it requires access to every source file in Android. To obtain all LLVM-IR files for the whole Android, first build AOSP using showcommands to get the exact path to clang/clang++ python executables. Then do the following changes to the clang and clang++ files (at function invoke_compiler()):

clang:

6,7c6
< import subprocess
<
---
>
87,98d85
<
<     print 'ARGV0', self.argv0
<     print 'EXECARG', self.execargs
<
<     try:
<       subprocess.check_call(self.execargs + ["-save-temps", "-S", "-m64", "-emit-llvm"])
<     except subprocess.CalledProcessError:
<       print 'FAILURE BUT WHO CARES?'
<     except OSError:
<       print 'OS FAILURE BUT WHO CARES?'
<

clang++:

< import subprocess
<
< print uniform(1, 10)
89,100d85
<
<     print 'ARGV0++', self.argv0
<     print 'EXECARG++', self.execargs
<
<     try:
<       subprocess.check_call(self.execargs + ["-save-temps", "-S", "-m64", -emit-llvm"])
<     except subprocess.CalledProcessError:
<       print 'FAILURE BUT WHO CARES?'
<     except OSError:
<       print 'OS FAILURE BUT WHO CARES?'
<
<

Please note that we need to invoke subprocess.check_call which spawns a new process (i.e., actual compiler) and waits till returns. When we dump the bitcode files, no executable is generated, so after this step, we need to execute os.execv(self.argv0, self.execargs) without the extra arguments as well.

NOTE: If you operate on 32-bits do not add the -m64 option.

Running FuzzGen

The best way to understand how to run FuzzGen is to go through its command line help:

OVERVIEW: FuzzGen - Automatic Fuzzer Generation

FuzzGen supports 4 modes of operation. You can choose mode with the '-mode' option.


A) Dump Functions (-mode=dump_functions):

   In this mode, FuzzGen dumps all functions declared in the library to a file and exits.
   Example:

        ./fuzzgen -mode=dump_functions <library.ll>


B) Dump API (-mode=dump_api):

   In this mode, FuzzGen, dumps inferred API from the library to a file and exits.
   To do this it requires: i) the consumer directory, ii) the metadata file, iii) the 
   library's root directory and -for Android libs only- iv) the library path inside AOSP.
   Example:

        ./fuzzgen -mode=dump_api -consumer-dir=libopus/consumers -meta=libopus.meta \
                  -lib-root=consumers/AOSP -path=external/libopus libopus/libopus_lto64.ll


C) Generate Fuzzers for Android (-mode=android):

    In this mode, FuzzGen synthesizes fuzzers for Android libraries.
    Example:
    
        ./fuzzgen -mode=android -analysis=deep -arch=x64 -no-progressive -lib-name=libhevc \
                  -meta=libhevc.meta -consumer-dir=libhevc/ext -lib-root=consumers/AOSP \
                  -path=/external/libhevc -outdir=fuzzers/libhevc -static-libs='libhevcdec' \
                  libhevc/libhevc_lto64.ll


D) Generage Fuzzers for Debian (-mode=debian):
    #TODO


USAGE: fuzzgen [options] <library.ll>

OPTIONS:

Fuzzer Generation Options:

  -analysis                 - Type of analysis to be performed
    =dumb                   -   DEPRECATED. Dumb fuzzing of all arguments
    =basic                  -   DataFlow analysis for each argument (not recommended)
    =deep                   -   DataFlow analysis with deep inspection for each argument (Default)
  -arch                     - Processor architecture of the fuzzed device
    =x86                    -   32-bit processor
    =x64                    -   64-bit processor (Default)
  -consumer-dir=<dir>       - Root directory where the LLVM IR of all consumers reside
  -lib-name=<name>          - Library name
  -max-buflen=<size>        - Maximum buffer size
  -max-depth=<depth>        - Maximum recursion depth (for internal analysis)
  -meta=<library.meta>      - Library metadata file
  -min-buflen=<size>        - Minimum buffer size
  -no-coalesce              - Disable AADG coalescing
  -no-failure               - Do not apply failure heuristic
  -no-permute               - Disable function permutations on-the-fly
  -outdir=<directory>       - Directory name to place the generated fuzzers
  -seed=<uint>              - Use a specific random seeds, to de-randomize variable names (Debug only)
  -visualize                - Visualize the Abstract API Dependence Graph
  -yes                      - Set default answer to 'yes' every time FuzzzGen prompts permission to continue

Fuzzer Generation Options for Android:

  -aux-lib=<lib-path>       - Auxiliary library's LLVM IR (with LTO)
  -aux-path=<aux-path>      - Auxiliary library's path inside Android source tree
  -lib-root=<root-dir>      - Root directory of the library (or AOSP directory for Android)
  -no-progressive           - Disable progressive fuzzer generation
  -path=<dir>               - Library path inside AOSP
  -shared-libs=<shared-lib> - Library's static module name
  -static-libs=<static-lib> - Library's static module name

General Options:

  -mode                     - FuzzGen operation mode
    =android                -   Generate fuzzers for Android (Default)
    =debian                 -   Generate fuzzers for Debian
    =dump_functions         -   Dump all library functions and exit
    =dump_api               -   Dump library API and exit
  Verbosity level:
    -v0                     - Display minimum status information
    -v1                     - Display basic status information (Default)
    -v2                     - Display detailed status information (Recommended)
    -v3                     - Display all status information (Not recommended)

Generic Options:

  -help                     - Display available options (-help-hidden for more)
  -help-list                - Display list of available options (-help-list-hidden for more)
  -version                  - Display the version of this program

Running Scripts

FuzzGen comes with a lot of useful scripts to assist data collection and visualization under aux/ directory. Feel free to experiment with them.

As an example, to aggregate line coverage reports and plot the plot code coverage use the plot_libfuzzer_coverage.py script as follows:

aux/plot_libfuzzer_coverage.py     \
    --fuzzgen_dir $FUZZGEN_RESULTS \
    --ispo_dir $MANUAL_RESULTS     \
    --fuzzer_name $FUZZERNAME

More Repositories

1

retrowrite

RetroWrite -- Retrofitting compiler passes through binary rewriting
Python
669
star
2

printbf

Brainfuck interpreter inside printf
Brainfuck
609
star
3

magma

A ground-truth fuzzing benchmark suite based on real programs with real bugs.
HTML
287
star
4

T-Fuzz

Python
248
star
5

BOPC

Block Oriented Programming -- Compiler
Python
180
star
6

thesis_template

Template for EPFL (BSc, MSc, or doctoral) theses and semester projects
TeX
123
star
7

FuZZan

FuZZan: Efficient Sanitizer Metadata Design for Fuzzing
C++
119
star
8

malWASH

C++
112
star
9

datAFLow

A data-flow-guided fuzzer
Faust
111
star
10

USBFuzz

A Framework for fuzzing USB Drivers by Device Emulation
C
109
star
11

HexType

HexType: Efficient Detection of Type Confusion Errors for C++
C++
100
star
12

FishFuzz

AFL/AFL++ version FishFuzz
C
86
star
13

FirmFuzz

Automated IoT firmware fuzzing framework.
C
76
star
14

SMoTherSpectre

Proof-of-concept code for the SMoTherSpectre exploit.
C
73
star
15

Igor

C
70
star
16

Gramatron

Coverage-guided grammar aware fuzzer that uses grammar automatons
C
63
star
17

libdetox

Fast and efficient binary translator
C
58
star
18

Evocatio

C
55
star
19

memTrace

memTrace, a framework for lightweight memory tracing
C
54
star
20

fuzzing-seed-selection

"Seed Selection for Successful Fuzzing" artifact (at ISSTA 2021)
C++
41
star
21

HexPADS

HexPADS, a host-based, Performance-counter-based Attack Detection System
C
39
star
22

ShadowStack

LLVM Implementation of different ShadowStack schemes for x86_64
C++
37
star
23

RetroWrite-Tutorial

C
37
star
24

GLeeFuzz

LLVM
35
star
25

EPOXY

Root Repo for the EPOXY tool that applies Privilege Overlays on bare-metal systems
C
32
star
26

OSTEP-slides

Makefile
31
star
27

ViDeZZo

ViDeZZo source code.
C
30
star
28

scudo-exploitation

Python
29
star
29

CFIXX

C++
27
star
30

SieveFuzz

Optimizing Directed Fuzzing via Target-tailored Program State Restriction
C
27
star
31

pubstats

Python
26
star
32

teezz-fuzzer

22
star
33

mitiGate

Benchmark to test different stop the exploit mitigations
C
18
star
34

HyperPill

C++
18
star
35

datashield

C++
17
star
36

HexVASAN

C++
16
star
37

AutoBib

AutoBib: create beautiful bib files and html publication pages automagically
Python
14
star
38

Tango

Tango: Extracting Higher-Order Feedback through State Inference
Python
13
star
39

GlobalConfusion

TrustZone Trusted Application 0-Days by Design
C
12
star
40

specrop

Code repository for experiments in SpecROP paper
C
11
star
41

WarpAttack

JavaScript
11
star
42

hexhive.github.io

HexHive homepage
HTML
10
star
43

nesCheck

C++
9
star
44

SyzRisk

Official repository of SyzRisk [ASIA CCS'24]
Go
9
star
45

Crystallizer

A hybrid analysis framework to aid in uncovering deserialization vulnerabilities
Java
9
star
46

retrowrite-dev

Retrowrite Development (Internal) Repository
7
star
47

SURGEON

Performant, flexible, and accurate re-hosting via transplantation
C
7
star
48

EL3XIR

Fuzzing Secure Monitor Implementations
C
6
star
49

EPOXY-llvm

Fork of LLVM for used to create EPOXY
C++
6
star
50

dis-cover

Disassemble binaries and recover as much info as possible
Python
6
star
51

specrop-public

Code repository for experiments in SpecROP paper
C
6
star
52

midas

Systematic Kernel TOCTTOU Protection
C
6
star
53

IOVFI

An accurate and resilient semantic function identifier
Python
6
star
54

simple_attacks

A set of simple buggy programs with corresponding exploits and simple shellcode
C
6
star
55

spill_the_tea

Python
5
star
56

halucinator-tutorial

Tutorial for HALucinator
C
5
star
57

teezz-ca-driver

C
5
star
58

CUP

5
star
59

teezz-caid

TEEzz's Client Application Identification
Python
4
star
60

EPOXY-clang

Fork of Clang used to create EPOXY
C++
4
star
61

adaptSTM

adaptSTM, a competitive, word-based STM library that is based on a global clock and an array of combined global versions (timestamps) and locks.
C
4
star
62

GAENScan

Java
3
star
63

dis-cover-packages-analysis

Debian C++ packages analysis with the dis-cover tool
Jupyter Notebook
3
star
64

teezz-fuzzing-engine

Python
3
star
65

BLURtooth

2
star
66

WOOT21

HTML
2
star
67

teezz-introspection

C++
2
star
68

seccell-seL4

The seL4 microkernel
C
2
star
69

se-valgrind

C
2
star
70

dimva24

HTML
2
star
71

dibartolomeo-msthesis

Luca Di Bartolomeo's master thesis
TeX
1
star
72

security-group.epfl.ch

HTML
1
star
73

teezz-adb

Python adb wrapper.
Python
1
star
74

seccell-riscv-binutils-gdb

C
1
star
75

seccell-riscv-gnu-toolchain

GNU toolchain for RISC-V, including GCC
C
1
star
76

Ancile

C++
1
star
77

securecells

SecureCells website repository
1
star
78

Igor-evaluations

1
star
79

seccell-seL4_libseccells

Userspace library for SecCells-specific functionality
C
1
star
80

seccell-opensbi

C
1
star
81

seccell-sel4-playground

A project based on the seL4 microkernel to implement and test new functionality based on the SecCells architecture
C
1
star
82

seccell-qemu

C
1
star
83

seccell-memcache

In-memory cache
C
1
star
84

virtfuzz-bugs

C
1
star
85

seccell-browser

C
1
star
86

JournalBot

Python
1
star
87

seccell-archtests

Testing basic architectural functionality for SecureCells
C
1
star