Enochian



Offline



Activity: 327

Merit: 100









Full MemberActivity: 327Merit: 100 New Attack Vector May 15, 2011, 05:00:58 PM #1



Each signature has exactly one DER-encoded ASN.1 octet representation, but openssl doesn't enforce this, and as long as a signature isn't horribly malformed, it will be accepted.



So you can sit on the network, watch for transactions, and echo them with the signatures slightly tweeked, but still valid. These new transactions will have different hashes, and will compete with the original transactions for inclusion in a block. When a cloned transaction beats out the original for block inclusion, it will leave the original in the owners wallet unconfirmable forever, resulting in inconvenience and unspendable coins. Quick echoing and network latency gives this a finite chance of happening.



Of course, you can't create or destroy coins with this, and the money still winds up at the right destination. However, the typical user isn't going to know how to restore an old wallet and rescan the block chain to get his bitcoin client back to working condition.



It might be a good idea to patch this before some enterprising person with excess time on their hands (cough) makes a cloned transaction echobot.



I was surprised to see that Bitcoin passes untrusted signature data received from the outside world to openssl without doing any checking on it. This leaves bitcoin open to the Litttle Bobby Tables ( http://xkcd.com/327/ ) attack.Each signature has exactly one DER-encoded ASN.1 octet representation, but openssl doesn't enforce this, and as long as a signature isn't horribly malformed, it will be accepted.So you can sit on the network, watch for transactions, and echo them with the signatures slightly tweeked, but still valid. These new transactions will have different hashes, and will compete with the original transactions for inclusion in a block. When a cloned transaction beats out the original for block inclusion, it will leave the original in the owners wallet unconfirmable forever, resulting in inconvenience and unspendable coins. Quick echoing and network latency gives this a finite chance of happening.Of course, you can't create or destroy coins with this, and the money still winds up at the right destination. However, the typical user isn't going to know how to restore an old wallet and rescan the block chain to get his bitcoin client back to working condition.It might be a good idea to patch this before some enterprising person with excess time on their hands (cough) makes a cloned transaction echobot.

AWARD-WINNING

CASINO CRYPTO EXCLUSIVE

CLUBHOUSE 1500+

GAMES 2 MIN

CASH-OUTS 24/7

SUPPORT 100s OF

FREE SPINS PLAY NOW rtised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction. Advertised sites are not endorsed by the Bitcoin Forum. Theymay be unsafe, untrustworthy, orillegal in your jurisdiction. Advertise here.

Pieter Wuille





Offline



Activity: 1064

Merit: 1038







LegendaryActivity: 1064Merit: 1038 Re: New Attack Vector May 15, 2011, 05:36:54 PM #2 I believe the attack you describe is possible and real, but the effect is less troublesome. As soon as a modified echo of the transaction is included in a block, both sender and receiver will see this transaction too. The old transaction will linger on however, unconfirmed.

I do Bitcoin stuff.

Gavin Andresen





Offline



Activity: 1652

Merit: 1066





Chief Scientist







LegendaryActivity: 1652Merit: 1066Chief Scientist Re: New Attack Vector May 15, 2011, 06:05:11 PM #3 I think sipa is right-- it will just look like a weird double-spend.



Probably a good idea to reject transactions with non-canonical signatures (reject if encode(decode(tx)) != tx ).



I assume the DER-encoded ASN.1 octet representation is the same between different ECDSA implementations (so if a non-openssl-based implementation creates transactions its transactions would be accepted), is that a good assumption?

How often do you get the chance to work on a potentially world-changing project?

Enochian



Offline



Activity: 327

Merit: 100









Full MemberActivity: 327Merit: 100 Re: New Attack Vector May 16, 2011, 01:41:49 PM #8 Quote from: sipa on May 16, 2011, 09:21:12 AM So let me get this straight: bitcoin's signatures are always in DER encoding, but it will accept any BER-encoded signature?



To encode a positive integer in DER, you convert it to a big endian sequence of octets, using the minimum necessary, and if the sign bit on the leading one is set, you prepend a zero octet so it won't be interpreted as a negative number. You then prepend an "02", which indicates "integer", and an octet count which is a single byte for lengths up to 127, and 0x80 plus an octet count followed by the length octets for lengths greater than 127. This maps every integer onto a unique octet sequence.



A signature is a pair of bignum integers, (r,s), so it consists of 0x30, which indicates a sequence of one or more things, an octet count of what follows, followed by two encoded integers. In addition, bitcoin appends the hashtype, which is always "1", to the end.



Here is a sample bitcoin sig, broken up into the relevant fields.



3046

0221

00c352d3dd993a981beba4a63ad15c209275ca9470abfcd57da93b58e4eb5dce82

0221

00840792bc1f456062819f15d33ee7055cf7b5ee1af1ebcc6028d9cdb1c3af7748

01



openssl doesn't enforce the rule that the leading octet can't be 0x00 or 0xff if it is an extension of the sign bit on the following octet. So you can prepend any number of 0x00 octets to a positive integer, and 0xff octets to a negative integer, and it is still considered legal. Thus you can make an unlimited number of working signatures given one of them.



To encode a positive integer in DER, you convert it to a big endian sequence of octets, using the minimum necessary, and if the sign bit on the leading one is set, you prepend a zero octet so it won't be interpreted as a negative number. You then prepend an "02", which indicates "integer", and an octet count which is a single byte for lengths up to 127, and 0x80 plus an octet count followed by the length octets for lengths greater than 127. This maps every integer onto a unique octet sequence.A signature is a pair of bignum integers, (r,s), so it consists of 0x30, which indicates a sequence of one or more things, an octet count of what follows, followed by two encoded integers. In addition, bitcoin appends the hashtype, which is always "1", to the end.Here is a sample bitcoin sig, broken up into the relevant fields.3046022100c352d3dd993a981beba4a63ad15c209275ca9470abfcd57da93b58e4eb5dce82022100840792bc1f456062819f15d33ee7055cf7b5ee1af1ebcc6028d9cdb1c3af774801openssl doesn't enforce the rule that the leading octet can't be 0x00 or 0xff if it is an extension of the sign bit on the following octet. So you can prepend any number of 0x00 octets to a positive integer, and 0xff octets to a negative integer, and it is still considered legal. Thus you can make an unlimited number of working signatures given one of them.

eamon



Offline



Activity: 10

Merit: 0









NewbieActivity: 10Merit: 0 Re: New Attack Vector May 17, 2011, 05:30:35 PM #9 This actually is quite similar to another "corner case" that I've been wondering about. Consider the following scenario:



User downloads installs bitcoin into a windows virtual machine, the copies the virtual machine to multiple locations.



Each of the virtual machines attempt to engage in transactions (receiving, sending, or even mining and block verification.)



What function is mitigating the collisions between clients, and which client becomes most authorative? While I see how this could result in issues in transaction confirmation, wouldn't confirmations by those cloned entities result in confirmation corruption?

kokjo



Offline



Activity: 1050

Merit: 1000



You are WRONG!







LegendaryActivity: 1050Merit: 1000You are WRONG! Re: New Attack Vector May 17, 2011, 05:44:52 PM #10 Quote from: eamon on May 17, 2011, 05:30:35 PM This actually is quite similar to another "corner case" that I've been wondering about. Consider the following scenario:



User downloads installs bitcoin into a windows virtual machine, the copies the virtual machine to multiple locations.



Each of the virtual machines attempt to engage in transactions (receiving, sending, or even mining and block verification.)



What function is mitigating the collisions between clients, and which client becomes most authorative? While I see how this could result in issues in transaction confirmation, wouldn't confirmations by those cloned entities result in confirmation corruption?

1. none of them.

2. no. 1. none of them.2. no. "The whole problem with the world is that fools and fanatics are always so certain of themselves and wiser people so full of doubts." -Bertrand Russell

Enochian



Offline



Activity: 327

Merit: 100









Full MemberActivity: 327Merit: 100 Re: New Attack Vector May 18, 2011, 04:03:38 PM #11 Quote from: sipa on May 15, 2011, 05:36:54 PM I believe the attack you describe is possible and real, but the effect is less troublesome. As soon as a modified echo of the transaction is included in a block, both sender and receiver will see this transaction too. The old transaction will linger on however, unconfirmed.





You're right.



I got curious and tried it this morning. I created two transactions that did the same thing. The first I let my client see, but didn't let it get broadcast. The second I broadcast, but didn't let my client see. Then I waited to see what would happen when the latter transaction arrived back in a block, double spending the earlier unconfirmable one in the wallet.



It added the second transaction to the wallet quite gracefully, and correctly computed the balance. So this is less of a problem than I originally thought.



I should point out, however, that it used to be possible to segfault the ASN.1 parser in openssl by giving it garbage to decode. The last such known bug was patched a number of revs back, but it not beyond the realm of possibility that another similar bug might be discovered at some time in the future.



So it's probably a good idea not to pass stuff that comes in over the wire to openssl without checking it first, just in case.



You're right.I got curious and tried it this morning. I created two transactions that did the same thing. The first I let my client see, but didn't let it get broadcast. The second I broadcast, but didn't let my client see. Then I waited to see what would happen when the latter transaction arrived back in a block, double spending the earlier unconfirmable one in the wallet.It added the second transaction to the wallet quite gracefully, and correctly computed the balance. So this is less of a problem than I originally thought.I should point out, however, that it used to be possible to segfault the ASN.1 parser in openssl by giving it garbage to decode. The last such known bug was patched a number of revs back, but it not beyond the realm of possibility that another similar bug might be discovered at some time in the future.So it's probably a good idea not to pass stuff that comes in over the wire to openssl without checking it first, just in case.

Pieter Wuille





Offline



Activity: 1064

Merit: 1038







LegendaryActivity: 1064Merit: 1038 Re: New Attack Vector May 18, 2011, 04:09:28 PM Merited by Spendulus (5) #13 I don't like the idea of openssl segfaulting on garbage data.



Is there an easy way for checking (by looking at the bytes ourselves, not by passing it to openssl and request to encode it again) that the input is a valid DER-encoded signature?

I do Bitcoin stuff.

Mike Hearn





Offline



Activity: 1526

Merit: 1008







LegendaryActivity: 1526Merit: 1008 Re: New Attack Vector May 18, 2011, 04:17:27 PM Merited by Spendulus (5) #14 Quote from: eamon on May 17, 2011, 05:30:35 PM What function is mitigating the collisions between clients, and which client becomes most authorative? While I see how this could result in issues in transaction confirmation, wouldn't confirmations by those cloned entities result in confirmation corruption?



It's possible to get a corrupted wallet today by doing that, where by "corrupted" I mean is out of sync with the state of the block chain and so can't reliably create spends.



Sipa is working on patches that can resolve this kind of thing, but until the work is complete it's not safe to do what you are suggesting. Bitcoin assumes that you don't copy your wallet around today.



Note that it doesn't undermine the security of the system though. The block chain will always be consistent. It's possible to get a corrupted wallet today by doing that, where by "corrupted" I mean is out of sync with the state of the block chain and so can't reliably create spends.Sipa is working on patches that can resolve this kind of thing, but until the work is complete it's not safe to do what you are suggesting. Bitcoin assumes that you don't copy your wallet around today.Note that it doesn't undermine the security of the system though. The block chain will always be consistent.

Enochian



Offline



Activity: 327

Merit: 100









Full MemberActivity: 327Merit: 100 Re: New Attack Vector May 18, 2011, 04:30:49 PM #15 Quote from: sipa on May 18, 2011, 04:09:28 PM I don't like the idea of openssl segfaulting on garbage data.



Is there an easy way for checking (by looking at the bytes ourselves, not by passing it to openssl and request to encode it again) that the input is a valid DER-encoded signature?





Well, you know a valid bitcoin signature (r,s) is going to look like



<30><len><02><len><r bytes><02><len><s bytes><01>



where the r and s values are non-negative, and don't exceed 33 bytes including a possible padding zero byte.



One way to check would be to just create a little function



bool IsValidSig(char *sig, int siglen)



Containing an appropriate stack of if statements.



Well, you know a valid bitcoin signature (r,s) is going to look like<30> <02> <02> <01>where the r and s values are non-negative, and don't exceed 33 bytes including a possible padding zero byte.One way to check would be to just create a little functionbool IsValidSig(char *sig, int siglen)Containing an appropriate stack of if statements.

Sergio_Demian_Lerner





Offline



Activity: 549

Merit: 544







Hero MemberActivity: 549Merit: 544 Re: New Attack Vector August 22, 2012, 01:46:33 PM #16 I'm re-investigating this past problem because I think there are some other possibilities for this attack vector.



Did Sipa implemented a patch back on MAY 2011 to check the uniqueness and correctness of signatures?



I don't see a IsValidSig() method in the source code.



Bet regards, Sergio.

Pieter Wuille





Offline



Activity: 1064

Merit: 1038







LegendaryActivity: 1064Merit: 1038 Re: New Attack Vector August 22, 2012, 02:21:31 PM #17 Quote from: Sergio_Demian_Lerner on August 22, 2012, 01:46:33 PM I'm re-investigating this past problem because I think there are some other possibilities for this attack vector.



Did Sipa implemented a patch back on MAY 2011 to check the uniqueness and correctness of signatures?



I don't see a IsValidSig() method in the source code.



Bet regards, Sergio.



No, this was never fixed. Doing it now would at first making transactions which use non-standard but valid encodings non-standard, and then fixing a policy for a transition point after which it becomes illegal. No, this was never fixed. Doing it now would at first making transactions which use non-standard but valid encodings non-standard, and then fixing a policy for a transition point after which it becomes illegal. I do Bitcoin stuff.

Gavin Andresen





Offline



Activity: 1652

Merit: 1066





Chief Scientist







LegendaryActivity: 1652Merit: 1066Chief Scientist Re: New Attack Vector August 22, 2012, 02:22:50 PM #18 Making transactions with non-DER-encoded (aka BER encoded) signatures non-standard has been on my TODO list for over a year now, but has never been the highest priority. That's the first step to making non-DER-encoded signatures completely illegal.



Note that if there is a core-dumping bug in OpenSSL's decoding code then it needs to get fixed in OpenSSL. Writing a BER decoder just for Bitcoin is a bad idea, it is much more likely our new code would have a crashing bug.

How often do you get the chance to work on a potentially world-changing project?