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" 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. Each module's README.md contains the module-specific build commands, dependencies, and notes.
| 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 |
| 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 |
| Module | CXXFLAGS define | Instructions |
|---|---|---|
| Rustreexo | RUSTREEXO |
modules/rustreexo/README.md |
| Utreexo | UTREEXO |
modules/utreexo/README.md |
Once the modules are compiled, you can compile bitcoinfuzz and execute it:
make
FUZZ=target_name ./bitcoinfuzzBy 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.
Set the MODULES environment variable to a comma-separated list of module names:
MODULES="BITCOIN_CORE,RUST_BITCOIN" FUZZ=target_name ./bitcoinfuzzLoad only Bitcoin Core and rust-bitcoin for comparison:
MODULES="BITCOIN_CORE,RUST_BITCOIN" FUZZ=bip32_master_keygen ./bitcoinfuzzLoad Lightning implementations only:
MODULES="LDK,LND,CLIGHTNING" FUZZ=deserialize_invoice ./bitcoinfuzzLoad all compiled modules (default behavior):
FUZZ=target_name ./bitcoinfuzz- If
MODULESis 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)
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- 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: denmeh/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
- libwally-core: https://github.com/ElementsProject/libwally-core/commit/a3fd0aa8ba78d37819ea3b03d22c77028e958cf5
- libwally-core: https://github.com/ElementsProject/libwally-core/commit/a1de7372913092cc664ceb98e7b96dd57fec44e7
- NBitcoin: MetacoSA/NBitcoin#1297
- btcd: btcsuite/btcd#2485
- rust-bitcoin: rust-bitcoin/rust-bitcoin#5617
- rust-bitcoin: rust-bitcoin/rust-bitcoin#5697
- LND: lightningnetwork/lnd#10597
- gocoin: https://github.com/piotrnar/gocoin/commit/3234dfcf5433718a5aa521db618e40f7c89c3690
- rust-lightning: lightningdevkit/rust-lightning#4442
- rust-bitcoin: rust-bitcoin/rust-bitcoin#5730
- utreexo: utreexo/utreexo#190
- libwally-core: ElementsProject/libwally-core#521
- pycoin: richardkiss/pycoin#437
- embit: diybitcoinhardware/embit#113
- btcd: btcsuite/btcd#2525
- libbitcoin-system: libbitcoin/libbitcoin-system#1829
- libbitcoin-system: libbitcoin/libbitcoin-system#1836
- libwally-core: ElementsProject/libwally-core#528
- Bitcoin Core: bitcoin/bitcoin#35308
- embit: diybitcoinhardware/embit#127
- Bitcoin-S: bitcoin-s/bitcoin-s#6350
- NBitcoin: MetacoSA/NBitcoin#1301
- pycoin: richardkiss/pycoin#438
- rust-bitcoin: rust-bitcoin/rust-bitcoin#6199
- bitcoinj: bitcoinj/bitcoinj#4210
- libbitcoin-system: libbitcoin/libbitcoin-system#1837
- libbitcoin-system: libbitcoin/libbitcoin-system#1840
- libbitcoin-system: libbitcoin/libbitcoin-system#1860
- libbitcoin-system: libbitcoin/libbitcoin-system#1871