This is the first of two articles that describe how to use the DefensicsĀ® software development kit (SDK) to fuzz Bitcoin software. Specifically, youāll learn how to model one of the Bitcoin network protocol messages and use the Defensics SDK to perform fuzzing on theāÆbitcoindāÆprocess.
This is an advanced technical tutorial, so youāll need some background knowledge.
This article details how to set up a test bed with the bitcoind binary and Wireshark. The next article describes how to model Bitcoin protocol messages using the Defensics SDK, and ultimately how to perform fuzzing on bitcoind using the Defensics SDK.
Defensics is a generational fuzz testing platform with over 250 test suites for a wide variety of network protocols and file formats.
The Defensics SDK gives you the ability to create your own test suites, which unleashes the full power of Defensics on any protocol or file format. All you need to do is provide a data model. You can then create a full-fledged Defensics test suite and leverage the powerful generational test case engine as well as all the other features provided by the Defensics platform.
Bitcoin is aāÆcryptocurrency, which means itās a currency supported by the mathematics of cryptography. Instead of being centrally managed, as government currencies are, a cryptocurrency is managed by the community, using a peer-to-peer network. Bitcoin and other cryptocurrencies are based on aāÆblockchain, which is a cryptographically protected list of all transactions. All peers in the network have a copy of the blockchain, which is cryptographically protected from tampering. The peers in the network use algorithms to agree on adding new transactions to the blockchain, allowing the entire network to come to a consensus about transactions without having to trust each other.
Cryptocurrencies are relatively new. Bitcoin was the first; it was introduced in 2007. Despite the relatively experimental nature of these currencies, significant value is invested in them. At this writing, theāÆmarket capitalizationāÆof Bitcoin is over $350B.
For the purposes of this article, you donāt need to know too many details about Bitcoin or any other protocol. All you really need to know is that Bitcoin peers run a process calledāÆbitcoind. The peers in the network exchange information using the Bitcoin network protocol.
If you just want to get bitcoind running so you can test it, you donāt need the virtual machine and Docker containers Iāll outline below. You could simply download the Bitcoin package, and then run bitcoind -regtest.
Setting up the test bed described below has some advantages.
The first step in fuzzingāÆbitcoindāÆis to create a test bed, a safe place where you can perform fuzzing without hurting anything. Fuzzing should never be performed on production systems, as itās likely to cause failures or trigger security alarms.
Bitcoin supports the production network (mainnet), a test network (testnet), and a regression test network (regtest). For fuzzing, I used the regtest network, as it allowed me to set up a private, isolated Bitcoin network, perfect for fuzzing.
I began by creating a virtual machine that holds my regtest peers, fleur and viktor. I used Ubuntu 20.04, but any Linux will do. This step is not strictlyāÆnecessaryāyouāÆcould just create the Docker instances directly on your hostāÆOSābut I wanted the extra layer of isolation.
Through the magic of Docker, ports on the virtual machine are mapped to ports on the fleur and viktor containers. When itās all up and running, itāll look like this:
In the next article, Iāll use the Defensics SDK to fuzz one of the bitcoind instances. You can run Defensics on the same virtual machine, on a different virtual machine, or even on your host OS.
Starting with the newly installed Linux machine, I first installed git and docker:
$ sudo apt-get install -y git docker.io
To get the most up-to-date Bitcoin protocol dissector, I installed Wireshark like this:
$ sudo add-apt-repository ppa:wireshark-dev/stable
...
$ sudo apt-get update
...
$ sudo apt-get install -y wireshark
...
After that, you can use my scripts to create and use a Docker container that runs bitcoind. (Thank you to Gerald Kaszuba for providing the inspiration for this approach.)
First clone my repository:
$āÆgit clone https://github.com/jknudsen-synopsys/bitcoinzz-testbed.git
The run build.sh to build the Docker image:
$āÆcd bitcoinzz-testbed
$ ./build.sh
The container image is very simple, little more than a base Ubuntu image plus the Bitcoin binaries. The script downloads the latest version, which is Bitcoin 0.20.1 as of this writing. If you want to change the version, edit bitcoinzz.docker to specify whichever version you like.
Using two separate terminal windows, you can spin up two instances of the container image with run_fleur.sh and run_viktor.sh.
The Bitcoin daemon bitcoind is automatically started in the container, and an alias rt is created for bitcoin-cli -regtest. This means you can use the alias to pass commands to bitcoind and get information:
$ ./run-fleur.sh
Bitcoin Core starting
root@fleur:~# rt -getinfo
{
"version": 200100,
"blocks": 0,
"headers": 0,
"verificationprogress": 1,
"timeoffset": 0,
"connections": 0,
"proxy": "",
"difficulty": 4.656542373906925e-10,
"chain": "regtest",
"balance": 0.00000000,
"keypoolsize": 1000,
"paytxfee": 0.00000000,
"relayfee": 0.00001000,
"warnings": ""
}
root@fleur:~#
You have two running bitcoindāÆinstances, but they donāt know about each other.
If you want to prove that they work together, run Wireshark and listen on theāÆdocker0āÆinterface. Then point one of the bitcoind instances at the other using its IP address.
I found the IP address of fleur usingāÆhostname:
root@fleur:~# hostname -I
172.17.0.3
Then I told viktorāsāÆbitcoindāÆabout fleur, like this:
root@viktor:~# rt addnode 172.17.0.3 onetry
This rewarded me with a flurry of Bitcoin messages exchanged between fleur and viktorāsāÆbitcoindāÆprocesses.
Congratulations! You have your own private Bitcoin network!
Come back next time when weāll build a model for the Bitcoin network protocol, and then use that model in the Defensics SDK to perform fuzzing on bitcoind.