Differential Fuzzing of Bitcoin implementations and libraries. Note this project is a WIP and might be not stable.
bitcoinfuzz is developed and supported on Linux only.
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.
-
To support the flags used in some modules
-fsanitize=address,fuzzer -std=c++20the 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"
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.
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/ -- ./bitcoinfuzzRead the afl++ documentation for more information.
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.
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.
-
Automatic Build:
- To automatically build the modules, define the flags in
CXXFLAGSand run the script:This will automatically build theCXXFLAGS="-DLDK -DLND" ./auto_build.pyLDKandLNDmodules.
- To automatically build the modules, define the flags in
-
Automatic Clean:
- The script supports three cleaning modes before building:
- Full Clean: Cleans all modules before building the selected ones.
CLEAN_BUILD="FULL" 6880 span> 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 ofCXXFLAGS.In this case, the script will runCLEAN_BUILD="-DLDK -DBTCD" CXXFLAGS="-DLDK -DLND" ./auto_build.py
make cleanforLDKandBTCD, but will only build the modules defined inCXXFLAGS(LDKandLND).
- Full Clean: Cleans all modules before building the selected ones.
- The script supports three cleaning modes before building:
See RUNNING.md for more information.
If you prefer, you can still build the modules manually. Below are the steps for each module:
-
cd modules/rustbitcoin make export CXXFLAGS="$CXXFLAGS -DRUST_BITCOIN"
-
cd modules/tinyminiscript make export CXXFLAGS="$CXXFLAGS -DTINY_MINISCRIPT"
-
cd modules/rustminiscript make export CXXFLAGS="$CXXFLAGS -DRUST_MINISCRIPT"
-
cd modules/btcd make export CXXFLAGS="$CXXFLAGS -DBTCD"
-
gocoin is a full Bitcoin node implementation written in Go.
cd modules/gocoin make export CXXFLAGS="$CXXFLAGS -DGOCOIN"
Note: gocoin cannot be used together with btcd in the same build due to cgo symbol conflicts (both embed the Go runtime).
-
cd modules/nbitcoin make export CXXFLAGS="$CXXFLAGS -DNBITCOIN"
-
To run the fuzzer with
embitmodule, you need to install theembitlibrary.To install the
embitlibrary, you can use the following command:cd modules/embit pip install -r ./requirements.txtcd modules/embit make export CXXFLAGS="$CXXFLAGS -DEMBIT"
-
cd modules/rustbitcoinkernel make export CXXFLAGS="$CXXFLAGS -DRUSTBITCOINKERNEL"
-
To run the fuzzer with
py-bitcoinkernelmodule, you need to install thepy-bitcoinkernellibrary.To install the
py-bitcoinkernellibrary, you can use the following command:cd modules/pybitcoinkernel pip install -r ./requirements.txtcd modules/pybitcoinkernel make export CXXFLAGS="$CXXFLAGS -DPYBITCOINKERNEL"
-
cd modules/bitcoin make export CXXFLAGS="$CXXFLAGS -DBITCOIN_CORE"
-
cd modules/bitcoinj make export CXXFLAGS="$CXXFLAGS -DBITCOINJ"
-
cd modules/ldk make export CXXFLAGS="$CXXFLAGS -DLDK"
-
cd modules/lnd make export CXXFLAGS="$CXXFLAGS -DLND"
-
cd modules/nlightning make export CXXFLAGS="$CXXFLAGS -DNLIGHTNING"
-
pip install mako git submodule update --init --recursive external/lightning cd modules/clightning make export CXXFLAGS="$CXXFLAGS -DCLIGHTNING"
-
git submodule update --init --recursive external/eclair cd modules/eclair make export CXXFLAGS="$CXXFLAGS -DECLAIR"
-
cd modules/lightningkmp make export CXXFLAGS="$CXXFLAGS -DLIGHTNING_KMP"
-
cd modules/decredsecp256k1 make export CXXFLAGS="$CXXFLAGS -DDECRED_SECP256K1"
-
git submodule update --init --recursive external/secp256k1 cd modules/secp256k1 make export CXXFLAGS="$CXXFLAGS -DSECP256K1"
-
cd modules/nbitcoinsecp256k1 make export CXXFLAGS="$CXXFLAGS -DNBITCOIN_SECP256K1"
-
cd modules/rustk256 make export CXXFLAGS="$CXXFLAGS -DRUST_K256"
Once the modules are compiled, you can compile bitcoinfuzz an execute it:
-
FUZZ=target_name ./bitcoinfuzz
-
make FUZZ=target_name ./bitcoinfuzz
- sipa/miniscript: sipa/miniscript#140
- rust-miniscript: rust-bitcoin/rust-miniscript#633
- rust-bitcoin: rust-bitcoin/rust-bitcoin#2681
- btcd: btcsuite/btcd#2195 (API mismatch with Bitcoin Core)
- Bitcoin Core: #34
- rust-miniscript: rust-bitcoin/rust-miniscript#696 (not found but reproductive)
- rust-miniscript: #39
- rust-bitcoin: rust-bitcoin/rust-bitcoin#2891
- rust-bitcoin: rust-bitcoin/rust-bitcoin#2879
- btcd: btcsuite/btcd#2199
- rust-bitcoin: #57
- rust-miniscript: CVE-2024-44073
- rust-miniscript: rust-bitcoin/rust-miniscript#785
- rust-miniscript: rust-bitcoin/rust-miniscript#788
- LND: lightningnetwork/lnd#9591
- Embit: diybitcoinhardware/embit#70
- btcd: btcsuite/btcd#2351
- Core Lightning: ElementsProject/lightning#8219
- LND: lightningnetwork/lnd#9808
- Core Lightning: ElementsProject/lightning#8282
- btcd: btcsuite/btcd#2372
- bolts: lightning/bolts#1264
- rust-lightning: lightningdevkit/rust-lightning#3814
- LND: lightningnetwork/lnd#9904
- LND: lightningnetwork/lnd#9915
- Eclair: ACINQ/eclair#3104
- rust-bitcoin: rust-bitcoin/rust-bitcoin#4617
- NBitcoin: MetacoSA/NBitcoin#1278
- lightning-kmp: ACINQ/lightning-kmp#799
- lightning-kmp: ACINQ/lightning-kmp#801
- bitcoin-kmp: ACINQ/bitcoin-kmp#157
- secp256k1: bitcoin-core/secp256k1#1718
- lightning-kmp: ACINQ/lightning-kmp#802
- rust-lightning: lightningdevkit/rust-lightning#3998
- bolts: lightning/bolts#1279
- rust-lightning: lightningdevkit/rust-lightning#4018
- btcd: btcsuite/btcd#2402
- btcd: btcsuite/btcd#2424
- rust-lightning: lightningdevkit/rust-lightning#4090
- btcd: btcsuite/btcd#2431
- LND: lightningnetwork/lnd#10249
- NBitcoin: MetacoSA/NBitcoin#1283
- tinyminiscript: unldenis/tinyminiscript#54
- NBitcoin: MetacoSA/NBitcoin#1288
- bolts: lightning/bolts#1303
- lightning-onion: lightningnetwork/lightning-onion#74
- NBitcoin: MetacoSA/NBitcoin#1294
- Floresta: #383 / getfloresta/Floresta#781
- gocoin: https://github.com/piotrnar/gocoin/commit/42763e1efb5f09ab563aa95a288b1dbe92b90cce
- bitcoinj: bitcoinj/bitcoinj#4054