What happened with the Bitcoin Denial Of Service and Inflation Bug CVE-2018-17144

On Mon, 17 Sep 2018, an anonymous encrypted disclosure message was sent to the BitcoinCore team by a user under the pseudonymous of beardnbobies. The message disclosed a Denial Of Service1 bug and a potential inflation bug2.

The Bug Disclosure

The message reads:

Date: Mon, 17 Sep 2018 14:57:46 +0000
To: Pieter Wuille , deadalnix , Andrea Suisani , Gregory Maxwell , "Wladimir J. van der Laan"
From: beardnboobies
Subject: Zero day exploit in Bitcoin ABC and Bitcoin Core


Dear Bitcoiners,

Please find attached an encrypted description of a crashing zero day exploit for Bitcoin Core as well as Bitcoin ABC. This has not been reproduced for Bitcoin Unlimited, though for advisory reasons, I am sending it to one of their members that I could find a PGP key for as well.

Please forward this to any party who might have a valid interest, including Bitcoin miners.

Thank you very much.

Read the full disclosure message sent to the core team here.

Later on, the anonymous person revealed himself to be awemany, one of the developers from Bitcoin Cash and Bitcoin Unlimited fork versions of Bitcoin. He published a blog post under the title 600 microseconds describing his discovery of the bug and the disclosure procedure he followed.

The patch and notice from the Core team

The Bitcoin Core team identified both a Denial Of Service as well as an inflation bug. In the aim to avoid giving the chance to a bad actor to take advantage of the inflation vulnerability, they communicated the patch in 0.16.3 as a fix to the DOS bug “only”. The plan did not work as expected since the information about the inflation bug leaked on forums. Luckily some miners and nodes already upgraded their nodes by that time.

The patch included the following change to the CheckBlock function in validation.cpp:

The change to the boolean flag from false to true enables back using the verification for the duplicate input spend when calling CheckTransaction (defined here) from within CheckBlock here.

The core team published a notice on the bitcoincore.org that urged people to upgrade their nodes to the patched version v0.16.3.

They also published details about the bug disclosure and the timeline of the events.

Technical details

The notice on bug CVE-2018-17144 published by the Core team included the following details:

In Bitcoin Core 0.14, an optimization was added (Bitcoin Core PR #9049) which avoided a costly check during initial pre-relay block validation that multiple inputs within a single transaction did not spend the same input twice which was added in 2012 (PR #443). While the UTXO-updating logic has sufficient knowledge to check that such a condition is not violated in 0.14 it only did so in a sanity check assertion and not with full error handling (it did, however, fully handle this case twice in prior to 0.8).

Thus, in Bitcoin Core 0.14.X, any attempts to double-spend a transaction output within a single transaction inside of a block will result in an assertion failure and a crash, as was originally reported.

In Bitcoin Core 0.15, as a part of a larger redesign to simplify unspent transaction output tracking and correct a resource exhaustion attack the assertion was changed subtly. Instead of asserting that the output being marked spent was previously unspent, it only asserts that it exists.

Thus, in Bitcoin Core 0.15.X, 0.16.0, 0.16.1, and 0.16.2, any attempts to double-spend a transaction output within a single transaction inside of a block where the output being spent was created in the same block, the same assertion failure will occur (as exists in the test case which was included in the 0.16.3 patch). However, if the output being double-spent was created in a previous block, an entry will still remain in the CCoin map with the DIRTY flag set and having been marked as spent, resulting in no such assertion. This could allow a miner to inflate the supply of Bitcoin as they would be then able to claim the value being spent twice.

What went wrong in the code

Answering to the question on StackExchange – “how does the most recently found critical vulnerability cve-2018-17144 work ?”Andrew Chow gave a technical summary for the Denial Of Service and the inflation bug described on the disclosure notice.

A deeper analysis of the bug

On Sep 27, Jimmy Song published an excellent detailed analysis of the bug with highlights from the source code. He explains the problem of the “Double-Spend” then follows through the timeline of the source code to explain the reasons for the bug to appear and its implications.

Read the full analysis here

A block using the inflation bug reproduced on testnet3

Someone used vulnerable bitcoin nodes in the testnet3 network to create and relay a block using the inflation bug. As you can see below, the transaction uses the same input twice, whose block, as of this writing, has 127 confirmations on testnet3.

The user directed the output back to the input address as a way to prove that this is indeed creating coins out of thin air. You can see that the address mypGR6pDS85nidXk3DoHZCNBuYd6WBhzgU originally holds 0.1 BTC which it transfers back to itself while also paying ~0.1 BTC of fees.

A closer look at the two input scripts shows that they are exactly identical:


ScriptSig: <unlocking_script> PUSHDATA(65)[0455fd1c1a6cbfb25b5bba1cf6f850de00d79852be3de51e50c0da683613303c533d079e147dfe07ce4d40df2b776b35184698d14fa107a61e0976b0d9416880c8] 
ScriptSig: <unlocking_script> PUSHDATA(65)[0455fd1c1a6cbfb25b5bba1cf6f850de00d79852be3de51e50c0da683613303c533d079e147dfe07ce4d40df2b776b35184698d14fa107a61e0976b0d9416880c8]

What should be done in the future ?

/u/theymos started a thread on bitcointalk.org titled the duplicate input vulnerability shouldn’t be forgotten.

He considers this bug – while avoiding to finger-point any core developer – to be an undeniably major failure. He encourages the community to start a constructive discussion on the reasons for this failure and the strategy to avoid this kind of critical bugs in the future.

Let us know in the comments if you want to contribute new information on the subject.

Resources


  1. In this bug, the Denial Of Service attack consists of broadcasting a particular invalid block to other nodes. Under certain conditions, if the block contains a transaction that spends from the same input twice, it would cause the node to crash [return]
  2. The inflation bug in CVE-2018-17144 allows a “bad acting” miner to broadcast blocks that contain a transaction using the same input twice, effectively creating coins that did not exist before. Inflation in Bitcoin is controlled by an algorithm which guarantees the amount of bitcoin produced, anything that creates new coins outside the algorithm is considered an inflation bug.

    [return]

Support us and the authors of this article by donating to the following address:

3AC6pGkA7EMScP1BEhKiXLsdyZ386u9BVE

Comments powered by Talkyard.