Skip to content

bitcoinfuzz/bitcoinfuzz

Repository files navigation

bitcoinfuzz

Differential Fuzzing of Bitcoin implementations and libraries. Note this project is a WIP and might be not stable.

Installation

Platform Support

bitcoinfuzz is developed and supported on Linux only.

MacOS or Windows Users:

We recommend using Docker to run bitcoinfuzz if you're on macOS or Windows. This provides the most reliable fuzzing experience with full toolchain support.

Dependencies

llvm toolset (clang and libfuzzer)

  • To support the flags used in some modules -fsanitize=address,fuzzer -std=c++20 the minimum clang version required is 10.0

  • For ubuntu/debian it can be installed using the package manager:

    sudo apt install clang lld llvm-dev
    
  • To install it from source check clang_get_started. You must build it with this cmake option: -DLLVM_ENABLE_PROJECTS="clang;lld;compiler-rt"

Running

The fuzzer has a lot of dependencies from the number of projects (and their runtime/lang) it supports and for that reason we provide a docker workflow to ease the burden of setting up and building the project.

See RUNNING.md to understand better the options and their configurations.

If you ended up luckily finding more bugs report them responsibly (see the respective SECURITY.md file on the project repo). You can merge your fuzzing corpus with our public corpora.

Fuzzing with AFL++

To quickly get started fuzzing using afl++:

$ git clone https://github.com/AFLplusplus/AFLplusplus
$ make -C AFLplusplus/ source-only
# To choose/use any other afl compiler, see
# https://github.com/AFLplusplus/AFLplusplus/blob/stable/docs/fuzzing_in_depth.md#a-selecting-the-best-afl-compiler-for-instrumenting-the-target
$ CC="AFLplusplus/afl-clang-fast" CXX="AFLplusplus/afl-clang-fast++" make
$ mkdir -p inputs/ outputs/
$ echo A > inputs/thin-air-input
$ FUZZ=addrv2 ./AFLplusplus/afl-fuzz -i inputs/ -o outputs/ -- ./bitcoinfuzz

Read the afl++ documentation for more information.

Build Options

You can build the modules in two ways: manual or automatic. The automatic method is provided by the auto_build.py script, which simplifies the build and clean processes. Additionally, you can use Docker or Docker Compose to run the application without installing dependencies directly on your machine.

Automatic Method: auto_build.py

The auto_build.py script allows you to automatically build the modules based on the flags defined in CXXFLAGS. It also provides options to clean the builds before compiling.

How to use:

  1. Automatic Build:

    • To automatically build the modules, define the flags in CXXFLAGS and run the script:
      CXXFLAGS="-DLDK -DLND" ./auto_build.py
      This will automatically build the LDK and LND modules.
  2. Automatic Clean:

    • The script supports three cleaning modes before building:
      • Full Clean: Cleans all modules before building the selected ones.
        CLEAN_BUILD="FULL" CXXFLAGS="-DLDK -DLND" ./auto_build.py
      • Clean: Cleans only the modules that will be built based on CXXFLAGS.
        CLEAN_BUILD="CLEAN" CXXFLAGS="-DLDK -DLND" ./auto_build.py
      • Select Clean: Cleans specific modules defined in CLEAN_BUILD, regardless of CXXFLAGS.
        CLEAN_BUILD="-DLDK -DBTCD" CXXFLAGS="-DLDK -DLND" ./auto_build.py
        In this case, the script will run make clean for LDK and BTCD, but will only build the modules defined in CXXFLAGS (LDK and LND).

Docker

See RUNNING.md for more information.

Manual Method

If you prefer, you can still build the modules manually. Each module's README.md contains the module-specific build commands, dependencies, and notes.

Bitcoin modules:

Module CXXFLAGS define Instructions
Bitcoin Core BITCOIN_CORE modules/bitcoin/README.md
bitcoinerlab miniscript BITCOINERLAB_MINISCRIPT modules/bitcoinerlabminiscript/README.md
bitcoinj BITCOINJ modules/bitcoinj/README.md
bitcoinkernel BITCOINKERNEL modules/bitcoinkernel/README.md
bitcoinkernel-variant BITCOINKERNEL_VARIANT modules/bitcoinkernelvariant/README.md
bitcoin-s BITCOINS modules/bitcoins/README.md
btcd BTCD modules/btcd/README.md
embit EMBIT modules/embit/README.md
gocoin GOCOIN modules/gocoin/README.md
libbitcoin-system LIBBITCOIN_SYSTEM modules/libbitcoinsystem/README.md
libwally-core LIBWALLY_CORE modules/libwallycore/README.md
NBitcoin NBITCOIN modules/nbitcoin/README.md
py-bitcoinkernel PYBITCOINKERNEL modules/pybitcoinkernel/README.md
pycoin PYCOIN modules/pycoin/README.md
rust-bitcoin RUST_BITCOIN modules/rustbitcoin/README.md
rust-bitcoinkernel RUSTBITCOINKERNEL modules/rustbitcoinkernel/README.md
rust-miniscript RUST_MINISCRIPT modules/rustminiscript/README.md
rust-psbt RUST_PSBT modules/rustpsbt/README.md
tinyminiscript TINY_MINISCRIPT modules/tinyminiscript/README.md

Lightning modules:

Module CXXFLAGS define Instructions
C-lightning CLIGHTNING modules/clightning/README.md
Eclair ECLAIR modules/eclair/README.md
LDK LDK modules/ldk/README.md
lightning-kmp LIGHTNING_KMP modules/lightningkmp/README.md
LND LND modules/lnd/README.md
NLightning NLIGHTNING modules/nlightning/README.md

Cryptography modules:

Module CXXFLAGS define Instructions
Decred-Secp256k1 DECRED_SECP256K1 modules/decredsecp256k1/README.md
K256 RUST_K256 modules/rustk256/README.md
Libsecp256k1 SECP256K1 modules/secp256k1/README.md
NBitcoin-Secp256k1 NBITCOIN_SECP256K1 modules/nbitcoinsecp256k1/README.md
rust-musig2 RUST_MUSIG2 modules/rustmusig2/README.md

Utreexo Modules

Module CXXFLAGS define Instructions
Rustreexo RUSTREEXO modules/rustreexo/README.md
Utreexo UTREEXO modules/utreexo/README.md

Final Build and Execution

Once the modules are compiled, you can compile bitcoinfuzz and execute it:

make
FUZZ=target_name ./bitcoinfuzz

Selective Module Loading

By default, all compiled modules are loaded when running the fuzzer. You can use the MODULES environment variable to load only specific modules at runtime, without needing to recompile.

Usage

Set the MODULES environment variable to a comma-separated list of module names:

MODULES="BITCOIN_CORE,RUST_BITCOIN" FUZZ=target_name ./bitcoinfuzz

Examples

Load only Bitcoin Core and rust-bitcoin for comparison:

MODULES="BITCOIN_CORE,RUST_BITCOIN" FUZZ=bip32_master_keygen ./bitcoinfuzz

Load Lightning implementations only:

MODULES="LDK,LND,CLIGHTNING" FUZZ=deserialize_invoice ./bitcoinfuzz

Load all compiled modules (default behavior):

FUZZ=target_name ./bitcoinfuzz

Notes

  • If MODULES is unset or empty, all compiled modules are loaded (existing behavior)
  • The fuzzer will abort with an error if you request a module that was not compiled
  • Whitespace around module names is trimmed (e.g., "BTCD, LND" works)

Logging Module Outputs

Set LOG_OUTPUTS=1 to print every accepted module response in the form:

Module: <module_name>
Result: <response>

This is independent of mismatch reporting (which always runs) and is useful for debugging or manually inspecting what each module returns for a given input. Expect very noisy output during fuzzing.

LOG_OUTPUTS=1 FUZZ=address_parse ./bitcoinfuzz crash-xxxx

Bugs/inconsistences/mismatches found by Bitcoinfuzz

About

Differential Fuzzing of Bitcoin protocol implementations and libraries

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Contributors