This issue's vulnerability topic is Bitcoin vulnerability CVE-2010-5141, which can cause attackers to steal anyone's Bitcoin, which is very harmful. Fortunately, the vulnerability has not been exploited and was repaired very quickly. The vulnerability is related to Bitcoin's script engine and has reference significance for public chain developers; from the current public chains on the market, most of them have built-in virtual machines or script engines to create a DApp ecosystem, which is also one of the major trends in blockchain. 1. What is the UTXO model in Bitcoin?Tips: The vulnerability code snippet involves some UTXO-related knowledge and concepts, so you need to understand these knowledge points before conducting a theoretical analysis of the vulnerability. If you already understand them, you can skip them directly. Ⅰ. Account Model and UTXO Model Before we look at the UTXO model, let's talk about the common account model. What is the account model? The data structure of the account model can be simply understood as "account => balance", and each account corresponds to a balance. For example: if account A transfers 200 to account B, in the account model, this transfer operation only requires A-200 and then B+200; currently most software uses the account model, such as the banking system, Ethereum, etc. However, Bitcoin uses the UTXO model developed by itself. There is no data structure like "account=>balance" in UTXO, so how to transfer money? Ⅱ. How to transfer Bitcoin Taking the transfer from A to B as an example, the following operations are required to complete this transfer in UTXO: 1. Find the source of the 200 balance in A's account, which means finding the transaction in which A received 200 2. With transaction x as input and transaction y that transfers 200 to B as output, x and y correspond and the transfer amounts of x and y must be equal 3. Transaction x is marked as spent, and transaction y is marked as unspent The transfer amounts of the two transactions must be equal. Simply put, you can only transfer out as much as you receive, which is actually the case. But what if you have to transfer only part of it to others? The answer is to transfer only part of it to others, and then transfer the rest to another account of your own. III. Quote two pictures and texts from the Internet: Account Model UTXO Model In this article, why Bitcoin adopts the UTXO model is not the focus. We just need to understand the principle of UTXO. 2. Bitcoin's Script EngineBitcoin scripts are not Turing complete. Bitcoin uses a self-defined script for transactions and other operations, which provides limited flexibility for Bitcoin. It can implement simple functions such as multi-signature and freezing funds, but not more. The reason why Bitcoin does this is to sacrifice a certain degree of completeness to ensure security. The principle of Bitcoin script is to first define a bunch of opcodes, and then the script engine executes each opcode one by one based on the stack. The stack is easy to understand. The queue is first-in, last-out, while the stack is just the opposite, first-in, first-out. After an element is pushed into the stack, it will be popped out first. In early versions of Bitcoin, sending a standard transfer (pay-to-pubkey) transaction requires a script signature (scriptSig) and a public key verification script (scriptPubKey). The specific processing flow is as follows: First fill in the script to be executed, then the signature (sig) and public key (pubKey) are pushed into the stack, and then the opcode OP_CHECKSIG will verify the signature, etc. If the verification passes, true will be pushed into the stack, otherwise false will be pushed into the stack. 3. CVE-2010-5141 Vulnerability AnalysisAfter understanding the above knowledge, you can start to analyze the CVE-2010-5141 vulnerability. The author downloaded the vulnerable version 0.3.3, the download address is in the bitcoin repository on github, find release. script.cpp code snippet VerifySignature function: The VerifySignature function is called for each transaction, which is used to execute the script and verify the signature, and then mark whether the transaction has been spent. First, the txFrom parameter is the previous transaction, and txTo is the transaction being processed. If you understand the UTXO model explained in the above chapter, it is not difficult to understand here. Focus on line 1125 of code, which calls the EvalScript function. The first parameter is txin.scriptSig (containing signature information) + separator opcode OP_CODESEPARATOR + txout.scriptPunKey (containing public key information, OP_CHECKSIG instruction). These are the scripts to be executed by the EvalScript function. The following parameters can be ignored for the time being. As long as the EvalScript function returns true, the verification signature is passed. How can the EvalScript function return true? First, the stack cannot be empty, and then the top of the stack must be true after being cast to bool. I simply interpret this as there must be a top of the stack and its value cannot be 0. Then look at the key OP_CHECKSIG opcode (Note: Since there are too many opcodes, this article focuses on the OP_CHECKSIG opcode) The above code is not difficult to understand. The Checksig function is called to verify the signature and then returned to the FSuccess variable. If it is true, a vchTrue (non-0) is pushed onto the stack, otherwise a vchFalse (0) is pushed onto the stack. If the opcode is OP_CHECKSIGVERIFY instead of OP_CHECKSIG, vchTrue is popped from the stack and the subsequent opcode is executed. According to the normal logic of OP_CHECKSIG, if the signature verification fails, there will be a vchFalse left at the top of the stack. Although the stack is not empty, the value at the top of the stack is 0, so false will still be returned. Going back to the previous code, the script executed by the EvalScript function mainly consists of the following variables: 1. txin.scriptSig 2. OP_CODESEPARATOR 3. txout.scriptPubKey The first signature information is controllable, the second one is just a separator and will be deleted, and the third one is uncontrollable because it comes from the previous transaction. The first variable is controllable and is executed as a script, so this variable can be not only signature information, but also opcode. This is easy to handle. Next, we need to reference a magical opcode OP_PUSHDATA4. Let's see how Bitcoin 0.3.3 handles this opcode: First, get the opcode. If the opcode value is less than or equal to the value of OP_PUSHDATA4, push all vchPushValues into the stack and then follow up with the GetOp function. After reading the source code, it is found that the OP_PUSHDATA4 instruction is defined as 78, so when the function encounters OP_PUSHDATA4, the pointer will move to 78+4=82 bits, of which 78 bits of data will be pushed onto the stack. Therefore, as long as an OP_PUSHDATA4 opcode is injected into txin.scriptSig, the subsequent public key information and OP_CHECKSIG instruction will be "eaten" and pushed onto the stack as parameters. When the pointer reaches the end, the final judgment is made: 1. Is the stack empty? No 2. Is the top element of the stack 0? No Therefore, the EvalScript function returns true if the condition is met, and then the VerifySignature function also returns true. Since the signature verification is bypassed, other people's bitcoins can be spent at will. 4. CVE-2010-5141 vulnerability repair solutionThe author downloaded Bitcoin version 0.3.8 and looked directly at the key code The fix is also very clear, execute scriptSig and scriptPubkey separately. No matter what is in your scriptSig, it will not affect the subsequent scriptPubkey execution. In conclusion: Because the Bitcoin vulnerability analysis has been serialized since the first issue of DVP, the current material is from 2010. The current vulnerability analysis mainly has the following difficulties: 1. There is very little information about the vulnerabilities. Most vulnerabilities only have a CVE number and a brief introduction. It is difficult to find them without consulting a large amount of information. 2. The environment is difficult to set up, including compilation, private chain construction (early Bitcoin did not even have the concept of private chain), etc. Many of the dependencies required for early Bitcoin source code compilation are no longer maintained and have been taken offline. Based on these reasons, the author only conducted theoretical research and did not conduct practical verification. Please correct any errors. 5. Reference Linkshttps://bitcoin.stackexchange.com/questions/37403/which-release-fixed-cve-2010-5141-attacker-can-spend-any-coin https://en.bitcoin.it/wiki/Script |
Whether a person's luck is good or not is ine...
According to Tokenview data, on December 24, East...
Recently, the domestic market price of Bitcoin ha...
Pieter Wuille gave a great introductory talk in H...
In ancient China, it was believed that if a woman...
Forehead wrinkles refer to some wrinkles on the f...
Russian President Vladimir Putin stressed the imp...
Author | Hashipi Analysis Team...
For some people, working for others means too slo...
On March 20, the digital currency market experien...
Generally speaking, women who are brave enough to...
Data released by the U.S. Department of Labor sho...
How to know your partner's feelings by lookin...
Everyone's palm lines are different. Differen...
Digital currency exchange ShapeShift was taken of...