Targeted DoS by CPU exhaustion using alerts
Private Release Date: 23-AGO-2012
Public Release Date: 01-MAR-2013
- Satoshi Bitcoin Client (Bitcoin-Qt, bitcoind)
- All Bitcoin clients that mimic the behavior related to the alert system of Satoshi client versions prior 0.6.3
- Bitcoin version 0.6.3 released 2012-06-25
- Bitcoin version 0.6.2 released 2012-05-08
- Bitcoin version 0.6.1 released 2012-05-04
- Bitcoin version 0.6.0 released 2012-03-30
- Bitcoin version 0.5.3.1 released 2012-03-16
- Bitcoin version 0.5.3 released 2012-03-14
- Bitcoin version 0.5.2 released 2012-01-09
- Bitcoin version 0.5.1 released 2011-12-15
- Bitcoin version 0.5.0 released 2011-11-21
- Bitcoin version 0.4.0 released 2011-09-23
- Bitcoin version 0.3.24 released 2011-07-08
- Bitcoin version 0.3.23 released 2011-06-14
- Bitcoin version 0.3.22 released 2011-06-05
- Bitcoin version 0.3.21 released 2011-04-27
Fixed in version
- Bitcoin version 0.7.0 released 2012-09-17
Bitcoin protocol has an alert system to spread important news regarding the digital currency. Alerts are signed with a private ECDA key, so only the development team can issue new alerts. Alerts signatures are checked for every alert that is received. Each check takes some time, usually between 1 and 4 msecs. The verification time does not depend on the correctness of the signature. Therefore an attacker may flood a node with invalid alerts generated on-the-fly at no cost, and exhaust the victim's node CPU.
The Satoshi client prior version 0.7.0 does not define an alert signature verification failure as a DoS attack (using return DoS(...); ).
A malicious client app can start sending invalid alerts at a rate of almost 3000 alerts/second for a 64 Kbytes/sec link. The victim's computer will reach 100% CPU utilization for the core associated with the ThreadMessageHandler2() thread. Although that thread has priority THREAD_PRIORITY_BELOW_NORMAL, the computer will suffer a noticeable slowdown. The attack works even with a 3 Kbytes/sec bandwidth usage, so even a slow network link can be used for the attack.
Alerts can be as short as 10 bytes. Here is a complete alert (without network message headers) that has an incorrect signature:
[0, 8, 48, 6, 2, 1, 10, 2, 1, 10]
It has zero length payload and (r,s) = (10,10)
The problem is still present even if you send the attacker sends correct alerts, previously received, since CheckSignature() is called before the signature is checked against mapAlerts. It was verified that, in an average computer, sending a 188-bytes correct alert continuously on a 64 Kbytes/sec link still rises the victim's CPU usage to 100%.
Possible Attack Scenarios
- An attacker has a direct connection to the victim's node.
- An attacker has a direct connections to a set of nodes that, if put off-line, could cut the network in two unconnected components. The attacker may try then to double-spend in each of the components. Since the attack requires very few resources for the attacker, he may try to attack all those nodes at once from a single computer.
Suggested Solutions for the 0.7.0 version
- Disconnect from any node that sends a bad alert (return DoS(...))
- Check that an alert is not verified more than once by checking the existence of the alert in mapAlerts before doing a CheckSignature()
Both solutions were adopted in version 0.7.0, although a lower penalty is given to nodes for sending single incorrect alerts.
2012-08-23 - Vulnerability reported to Gavin Andressen and other core devs.
2012-08-23 - Gavin Andressen acknowledges report and asserts that version 0.7 will be patched against these problems.
2012-09-17 - Bitcoin version 0.7.0 released
2013-03-01 - Patched Bitcoin version reach 80% of the network nodes upgraded.
2013-03-01 - Vulnerability disclosure
This vulnerability was discovered by Sergio Demian Lerner, from Certimix.com. This report was written by SDL.