Full Disclosure mailing list archives

By Date By Thread Fun with Bitcoin, or how an exploit can hide in plain sight From: Aidan Thornton <makosoft () googlemail com>

Date: Wed, 1 Feb 2012 15:05:04 +0000

So most people on here have probably heard of Bitcoin from somewhere, and most of you have probably got tired of it - but bear with me because this is kind of entertaining. For those of you that have been stuck in a darkened room with a disassembler and no internet access for the past few months, Bitcoin's a clever digital currency that manages to solve the problem of someone spending the same money twice without needing any kind of central trusted authority. It does this by using a variant of hash-cash to make rewriting the history of past transactions expensive. Now this means that someone with more than half the total compute power can launch certain attacks - they're listed on the Bitcoin wiki at https://en.bitcoin.it/wiki/Weaknesses#Attacker_has_a_lot_of_computing_power - but even they aren't meant to have total control. In particular, they're not meant to be able to spend other people's money because doing so requires a signature from their private key: "The attacker can't: Send coins that never belonged to him" For several months that claim has been *false* as a result of this commit by the lead Bitcoin developer: https://github.com/bitcoin/bitcoin/commit/b14bd4df58171454c2aa580ffad94982943483f5 Now, while obviously that commit is doing something slightly risky, there's a nice reassuring comment from him in the code explaining exactly why it's not actually a security risk: // Skip ECDSA signature verification when connecting blocks (fBlock=true) during initial download // (before the last blockchain checkpoint). This is safe because block merkle hashes are // still computed and checked, and any change will be caught at the next checkpoint. It's a very convincing explanation to anyone that understands Bitcoin. You can only really add a blockchain checkpoint if all the nodes agree that the chain up to that point is valid - otherwise things will break in a fairly spectacular and obvious way - so a whole bunch of other Bitcoin nodes run by many independent people will already have verified the ECDSA signatures. There's even a good justification for making the change. Initial blockchain downloads are far too slow which discourages new users, and ECDSA signature verification is one of the slowest parts. Unfortunately the comment is fatally wrong. Even more scarily, there's no reason at all to suspect this from the commit diff, which is probably why no-one noticed anything was amiss when it was committed. If you take a look at the actual definition of IsInitialBlockDownload there's actually *two* situations which it considers part of the initial download. One of them is indeed being before the last blockchain checkpoint: if (pindexBest == NULL || nBestHeight < Checkpoints::GetTotalBlocksEstimate()) return true; The other involves the timestamp included within the last block and how recently it was received: return (GetTime() - nLastUpdate < 10 && pindexBest->GetBlockTime() < GetTime() - 24 * 60 * 60); So, if we receive a block less than 10 seconds after the previous one and the previous block had a timestamp more than 24 hours in the past, we don't bother to verify any of the ECDSA signatures in it and will allow it to include transactions that spend random people's Bitcoins! A powerful attacker could definitely exploit this; timestamps in the future are rejected and Bitcoin won't generally accept a version of history in which time goes backwards, but otherwise a 51% attacker can choose whatever timestamps they like and can delay releasing their version of the chain to meet the "less than 10 seconds" requirement. It's a very expensive attack but far from impossible. By full-disclosure standards this is actually old news; I disclosed it semi-publicly to the Bitcoin developers about a month ago and they committed a fix back then, and there's even been a Bitcoin release 0.5.2 since then which includes the fix (though only because one of the other developers stubbornly insisted on creating a bugfix release for other reasons - the head developer was strongly against it). All previous 0.5.x releases were vulnerable and 0.6 hasn't been released yet. I only just got around to looking into how the vulnerability got in originally though and it doesn't appear anyone's really talked about it. This isn't a formal advisory either, more an example of how a vulnerability can easily be introduced by a seemingly innocuous commit and why the Bitcoin code needs more scrutiny. _______________________________________________ Full-Disclosure - We believe in it. Charter: http://lists.grok.org.uk/full-disclosure-charter.html Hosted and sponsored by Secunia - http://secunia.com/ By Date By Thread Current thread: Fun with Bitcoin, or how an exploit can hide in plain sight Aidan Thornton (Feb 01) Re: Fun with Bitcoin, or how an exploit can hide in plain sight Dan Kaminsky (Feb 01) Re: Fun with Bitcoin, or how an exploit can hide in plain sight Aidan Thornton (Feb 02)

Aidan Thornton (Feb 01)