Some people assume that Bitcoin is inherently secure due to its’ decentralization, however, having something centralized or decentralized does not affirm whether it’s secure.
In this post I want to explain how security researchers can easily get started with auditing the P2P network. I may write future blog posts and articles on this issue if time allows. For updates, follow me on Twitter at https://twitter.com/Kleissner.
Here I also published the link for an experimental software I created called “BitSnail”. It can potentially exhaust inbound TCP connections of Bitcoin clients, and in theory (as part of a scaled up attack), slow down the Bitcoin P2P network. It will be used to test the robustness of Bitcoin clients. BitSnail should only be used in a controlled/ethical manner. The code does not exploit any vulnerability; it is a simple DDoS attempt.
Here’s the link: https://github.com/Kleissner/BitSnail
.----. ₿ ₿ / .-"-.`. \v/ | | '\ \ \_/ ) ,-\ `-.' /.' / '---`----'----'
So, is the Bitcoin network secure? There’s only one way to find out.
– Peter Kleissner
What does it mean, “secure”?
For the purposes of this post, secure simply means to be “protected against a variety of attacks”. Types of attacks that other researchers may consider invalid, I will consider both valid and successful, as long as they are effective. A prime example is DDoS attacks: they are not typically a result of a vulnerability.
For us to figure out now in the case of the Bitcoin network is whether there are design flaws in the P2P (peer-to-peer) code.
There is a good list here with known potential attacks (and some mitigations): https://en.bitcoin.it/wiki/Weaknesses
- Theft of local wallet
- Sybil attack (flood the network with nodes you control for further attacks)
- Denial of Service attacks
- Illegal content on the blockchain
- Exploiting client vulnerabilities
- Other potential attacks such as finding flaws in the cryptographic algorithms
- Spam transactions
A list of past Bitcoin client vulnerabilities is published here: https://en.bitcoin.it/wiki/Common_Vulnerabilities_and_Exposures
Levels of launching an attack
There are multiple levels of where and how you can launch attacks.
- Bitcoin client software level. Example: exploiting a vulnerability in the software such as Denial of Service or Remote Code Execution; not very likely to find.
- Bitcoin client (individual peer node) network level. Example: flooding (DDoSing) the inbound and/or outbound connections to essentially “take offline” the Bitcoin peer node that is attacked; very likely to succeed.
- Global Bitcoin P2P network. Example: trying to split the network and flood with fake (or non-fake) self-controlled peers, thus causing outages and disruption; medium likely.
Distributed Denial of Service attacks against Bitcoin full nodes (miners) aren’t new
There have been previous attempts at DDoSing Bitcoin clients.
Specifically for Bitcoin, the DDoS attacks we mitigated could also have been attempts to manipulate the price of bitcoin and other cryptocurrency, something we know offenders have tried in the past.Computer Weekly: https://www.computerweekly.com/news/450431318/Bitcoin-industry-enters-top-10-DDoS-targets:
Real-world P2P botnets and attacks against them
I was involved in research on a few botnets that use a P2P algorithm for sending commands/and or updates. These include:
- ZeuS Gameover (multiple networks)
- Sality (networks 3 and 4)
- ZeroAccess 1 and 2
Types of attacks
- Isolation attack: Isolating a peer from all its others, typically by flooding its peer list with fake peers (or own controlled peers)
- Replay attacks: Sending (sometimes signed) messages again to get a certain behavior; i.e., sending an old update of the program that is vulnerable
- Amplification attacks:Forging the sender and abusing a protocol, thus amplifying the impact of attacks
- DDoS: Typical denial-of-service. Trying to exhaust one resource or another (such as open sockets, ports, database connections)
- Flooding: Sending garbage down the pipe. Expensive and not very reliable (your bad traffic will “compete” with legitimate traffic) to cause long-lasting damage
- Taking control via BGP hijacking: If there are master nodes that control a network (in case of Bitcoin there are not), then BGP hijacking could be used (together with another attack, like the replay attack, or exploiting a vulnerability) to gain control
There are ways to secure against the above attacks. Against isolation attacks, help by using counters of valid peers, limiting peers per CIDR, using hard-coded list, using trusted sources for bootstrapping (Bitcoin clients are doing that actually). Using timestamps, version numbers, and cryptographic signatures can prevent replay attacks.
Where to get started
To get started, you need to study the Bitcoin P2P protocol and understand how it works. It is published here: https://bitcoin.org/en/developer-reference#protocol-versions
Second, you need to look at the Bitcoin clients. There are multiple independent implementations of the P2P protocol. This site https://coin.dance/nodes gives an overview of the popularity of Bitcoin clients.
As you can see, at 97%, Bitcoin Core has by far the biggest share.
Bitcoin Core’s code is hosted here https://github.com/bitcoin/bitcoin/. It is developed in C and fairly simple to read.
Evil ₿ Client
One option for launching attacks is creating an “Evil ₿ Client” by forking a legitimate client and modifying the code. This would make detection of the client more difficult, since it would respond, for example, normally to certain peer messages.
A good Bitcoin client to fork is “btcd”. It is developed in Go and published here: https://github.com/btcsuite/btcd
Finding potential weaknesses in Bitcoin clients
To find potential weaknesses in Bitcoin clients, you have to study their code. If you want to mess with the Bitcoin core client (which has 97% market share) you may want to start in the
net.cpp file https://github.com/bitcoin/bitcoin/blob/master/src/net.cpp#L889 in the function “AcceptConnection”. It handles incoming peer connections.
An attacker may want the function AcceptConnection to stop accepting incoming connections, to make the peer unreachable, and effectively slow down the P2P network. One way to reach that goal is simply exhausting all incoming connections. According to the
net.h file, there’s a maximum of 125 peer connections maintained – this is not really a lot.
/** The maximum number of peer connections to maintain. */ static const unsigned int DEFAULT_MAX_PEER_CONNECTIONS = 125;
In order to make the peer unreachable, only 125 peers need to be connected at a given time. Those could also be 125 fake peers artificially created by an attacker.
It is important to note that this will only make the peer unreachable from the outside (like if it was behind a firewall); however, the peer itself can still reach out to other peers that it knows.
As mentioned in the beginning, this is not exploiting a security vulnerability. It is merely trying to exhaust connections and cause a (temporary, as long as the attack is active) denial of service.
In the Bitcoin Core client, there are countermeasures, however. The function
AttemptToEvictConnection will try to evict existing connections. An attacker would have to be able create “high-quality” fake peers with high-quality defined by the characteristics checked in the function, some which actually may be out of control of the attacker.
For performing the research, I have decided to create a new software called BitSnail. I wanted to see whether my assumptions with exhausting the peer connections is feasible or not. The code is developed in Go and can be compiled on both Linux and Windows.
It is hosted here: https://github.com/Kleissner/BitSnail
Where to go from here
BitSnail is an initial version that allow security researchers to test the robustness of Bitcoin clients. It allows to create and spread fake peers. More research and testing is required to determine the real-world impact, as there are countermeasures deployed both in Bitcoin clients, but also on a network level (rate-limiting/DDoS protections) by some miners.