比特币任意盗币漏洞浅析

2019-01-14 13:04 栏目:经验之谈 来源: 查看()
这个漏洞的问题是比特币漏洞CVE-2010-5141,这个漏洞可以导致攻击者窃取任何人的比特币,损害非常严重。幸运的是,该漏洞尚未被利用,而且速度非常快。此漏洞与比特币的脚本引擎有关,对公共连锁开发人员具有参考意义。从当前市场中的公共链的角度来看,大多数都有内置的虚拟机或脚本引擎来创建DApp生态系统。区块链的一大趋势。

1.比特币中的UTXO模型是什么?

提示:有关UTXO的一些知识和概念将涉及漏洞代码段。因此,在理论上分析漏洞之前,您需要了解这些知识点。如果您知道,可以直接跳过它。

我,帐户模型和UTXO模型

在我们查看UTXO模型之前,让我们来谈谈通用帐户模型。什么是帐户模型?帐户模型的数据结构可以理解为“帐户=>余额”,并且每个帐户对应于余额。例如:如果帐户A将200转移到帐户B,则帐户模型中的转帐操作仅需要A-200然后B + 200;大多数软件目前使用帐户模型,例如银行系统,以太坊等。

比特币使用自己开发的UTXO模型。 UTXO没有诸如“account=> balance”之类的数据结构。你如何转账?

II。比特币如何运作转让

以上述A到B传输为例,在UTXO中完成此传输需要以下操作:

1.在A帐户下找到200余额的来源,这意味着您要为交易找到A交易200
2.将x交易作为输入,交易y到B转移200作为输出,x和y,并且x和y的转移金额必须相等
3. x交易标记为已花费,y交易标记为未花费

两笔交易的转账金额必须相等。简单的解释是它只能转出多少收到。事实上,情况确实如此。

但是,如果你必须让某人参与呢?答案是将一部分转移给其他人,然后将其余部分转移到另一个号码。

III。引用网络上的两张图片:

比特币任意盗币漏洞浅析

比特币任意盗币漏洞浅析

在本文中,为什么比特币采用UTXO模型不是重点。我们理解UTXO的原理。

二,比特币脚本引擎
 
比特币脚本是非完整的。比特币使用自定义脚本进行交易和其他操作,为比特币提供有限的灵活性。实施简单的功能,如多个签名,冻结资金等,但更多不起作用。

比特币这样做的原因是牺牲安全性达到一定程度的完整性。比特币脚本的原理是首先定义一堆操作码,然后脚本引擎根据堆栈逐个执行每个操作码。

堆栈很好理解,队列是先进的,堆栈正好相反。它是先进先出,当元素被推入堆栈时,元素首先被弹出。

在较早版本的比特币中发送标准的pay-to-pubkey事务需要脚本签名(scriptSig)和公钥验证脚本(scriptPubKey)。具体处理流程如下:

比特币任意盗币漏洞浅析

首先填写要执行的脚本(脚本),然后将签名(sig)和公钥(pubKey)压入堆栈,然后操作码OP_CHE高仿CKSIG将验证签名等。如果验证通过,则为真将被推入堆栈,否则将是False推送堆栈。

三,CVE-2010-5141漏洞分析
 
了解上述知识后,您可以开始分析CVE-2010-5141漏洞。我下载了易受攻击的版本0.3.3,并在github的比特币存储库中下载了该地址以查找版本。

Script.cpp代码片段VerifySignature函数:

比特币任意盗币漏洞浅析

执行每个事务以调用VerifySignature函数,该函数用于执行脚本并验证签名,然后将事务标记为成本。

首先,txFrom参数是最后一个事务,txTo是正在处理的事务。如果您了解上一节中介绍的UTXO模型,则不难理解。专注于1125行代码,调用EvalScript函数,第一个参数是txin.scriptSig(包括签名信息)+分隔符操作代码OP_CODESEPARATOR + txout.scriptPunKey(包括公钥信息,OP_CHE高仿CKSIG指令),这些是要执行的脚本EvalScript功能。后一个参数可以保持未使用状态,只要EvalScript函数返回true,就会传递验证签名。 EvalScript函数如何返回true?

比特币任意盗币漏洞浅析

首先堆栈不能为空,然后在bool之后堆栈的顶部必须为true。作者只是解释必须有一个堆栈顶部,并且该值不能为零。

然后看一下关键OP_CHE高仿CKSIG操作码

(注意:由于操作码太多,本文适用于OP_CHE高仿CKSIG操作码)

比特币任意盗币漏洞浅析

上面的代码不难理解,调用Checksig函数验证签名,然后返回FSuccess变量,如果是true,按vchTrue(非零)推送,否则按vchFalse(0)推送;如果操作码是OP_CHE高仿CKSIGVERIFY而不是OP_CHE高仿CKSIG,则会弹出vchTrue并开始执行以下操作码。

根据OP_CHE高仿CKSIG的正常逻辑,如果验证签名不成功,则堆栈顶部必须留有vchFalse。虽然堆栈不为空,但堆栈顶部的值为0,否则将返回false。

回到前面的代码,EvalScript函数执行的脚本主要包含以下变量:

1. txin.scriptSig
2. OP_CODESEPARATOR
3. txout.scriptPubKey

第一个签名信息是可控的,第二个签名信息不仅是一个分隔符,它将被删除,第三个签名信息是不可控的,因为它来自前一个事务。

第一个变量是可控的并且作为脚本执行,因此该变量不仅仅是签名信息或操作码,它易于处理。下面你需要引用一个神奇的操作码OP_PUSHDATA4,让我们来看看比特币0.3 .3如何处理这个操作码:

比特币任意盗币漏洞浅析

首先得到操作码。如果操作码的值小于或等于OP_PUSHDATA4的值,则将vchPushValue推入堆栈并按照GetOp函数

比特币任意盗币漏洞浅析

读完源代码后,发现OP_PUSHDATA4指令定义为78,所以当函数遇到OP_PUSHDATA4时,指针将再次移动78 + 4=82位,其中78位将被推入堆栈,所以只需注入它进入txin.scriptSig。 OP_PUSHDATA4操作码,以下公钥信息和OP_CHE高仿CKSIG指令将被“吃掉”并作为参数弹出。当指针到达结尾时,最终决定:

1.堆栈是空的吗?不是
2.堆栈的顶部元素是0吗?不是

因此条件EvalScript函数返回true,然后VerifySignature函数返回true。由于绕过了签名验证,其他人的比特币可以任意使用。

四,CVE-2010-5141漏洞修复程序
 
我下载了比特币版本0.3.8并直接查看了关键部分代码

比特币任意盗币漏洞浅析

修复也很清楚。 ScriptSig和scriptPubkey分别执行。无论您的scriptSig中有什么内容,它都不会影响scriptPubkey的执行。

写在最后:

由于比特币漏洞分析是从第一期DVP漏洞序列化出来的,目前的资料来自2010年。目前,漏洞分析主要有以下困难:

1.漏洞相关信息非常少。大多数漏洞只有一个CVE编号和配置文件。没有咨询大量数据就无法开始。

2.环境难以构建,难以编译,私有链构建(早期比特币甚至私有链的概念)等。比特币的早期源代码编译需要许多依赖关系现在不能维护和离线。

由于这些原因,作者只进行了理论研究,并没有进行实践验证。如果有任何错误,请纠正我。

微信二维码
售前客服二维码

文章均源于网络收集编辑侵删

提示:仅接受技术开发咨询!

郑重申明:资讯文章为网络收集整理,官方公告以外的资讯内容与本站无关!
NFT开发,NFT交易所开发,DAPP开发 Keywords: NFT开发 NFT交易所开发 DAPP开发