比特币现金漏洞追踪始末:我为什么匿名帮助对手找bug?
2018年4月25日,我以匿名的方式私下披露了比特币现金(BCH)的一个关键漏洞。比特币现金是世界上最有价值的加密货币之一,与比特币(BTC)不同。如果有黑客成功地利用这个安全漏洞,可能会造成极大的破坏,导致比特币现金的交易不再可能安全进行下去,最终会完全破坏该货币本身的使用以及价值。事实情况是,这一漏洞在没有发生事故的情况下得到了很好的修复,并于2018年5月7日向公众披露了这起事件。
首先要对比特币现金做一个简单的说明。比特币现金是一种不同于比特币、而且与比特币不兼容的加密货币。之所以这样命名,是因为它源自比特币。下文描述的已经修复好的漏洞只对比特币现金产生了影响;比特币现金与比特币唯一相关的就是它们的名字很相似。
至于我为什么要这么做?我的动机是什么?我在麻省理工学院媒体实验室的数字货币项目工作,顾名思义,这是一个负责研究和开发加密货币的团队。具体来说,我帮助开发和维护比特币核心钱包以及比特币的主要软件实现。由于承担这项工作,我经常在会议和研讨会上被问到这样一个问题:你认为未来比特币面临的最大挑战是什么?而我的回答总是一样的:比特币未来一定要注意避免灾难性的软件漏洞。
通过研究这个有可能带来灾难性后果的漏洞,我确信软件漏洞的威胁在加密货币世界中被严重低估了。我对这一事件提供了一个详细的报告,这不是小题大做,而是希望以这个真实世界的例子让人们了解到,要达到加密货币所需的复杂工程水平还有很多工作仍然要做,同时也给那些还没有为这种情况做好充分准备的公司敲响了警钟。
简而言之,一部分交易签名验证代码被重写,但新代码省略了对签名类型中特定位(bit)的关键检性查。我在本文中将这个位称为SIGHASH_BUG。这种省略行为将使一个特制的交易把比特币现金区块链分叉成两条不兼容的链。下一节我将描述这种分叉的重要性。有关漏洞和修复的详细信息,请参阅公开的文本。
区块链分叉漏洞有何特别之处?
大多数加密货币,包括比特币和比特币现金,通过向所有参与者分发所有交易的分类帐来运行。为了能够进行消费,货币持有者必须首先创建一个交易,这个交易要遵守系统的所有规则。这些规则大多数都很明显,很直接,例如“你的花费不能超出你所拥有的数量”,但其他规则则更加微妙,技术性更强,尤其是那些描述数字签名应该如何格式化的规则。但是,如果加密货币是不允许使用的,那么谁来设置这些所谓的验证规则呢?
每个人都参与设置验证规则
系统的规则是由每个人来决定的,而执行这些规则是软件的工作。如果一个参与者试图欺骗并创建一个交易,在这笔交易中,他花费的不是自己的货币,那么其他参与者的软件会简单地拒绝这笔交易。因此,为了确保交易被普遍接受,它必须遵守所有的规则,哪怕规则迂腐至极。
负责执行验证规则的软件需要不断地改进。为了提高性能、增加特性、提高安全性等,需要不断进行更改。但是,从一个版本到另一个版本执行规则的方式必须保持完全相同,这一点非常重要。
那么,如果新版本软件中的一个意外编程漏洞导致交易被认为是有效的,而之前的所有版本都将其视为无效时,会发生什么情况呢?其结果就是“区块链分裂”,这意味着只有升级了该软件的参与者子集才会接受上述交易。由于交易和区块是链接在一起的,因此这两个子集在接下来的每笔交易上都不一致。如果没有开发人员的快速行动,没有让所有参与者团结统一到一起,这两个参与者阵营将永远无法达成一致。到那时,这种货币实际上已经分裂为两种不兼容的货币,像以前那样交易将不再可能。
在权衡诸如此类的漏洞的潜在影响时,时机起着至关重要的作用。如果区块链被分割成两块,99%的参与者在一边,而只有1%的参与者站在另一边,那么显然与多数人站在一起就是前进的道路。然而,如果大约有50%的人已经升级到新版本,那么就没有简单的选择了。
我在比特币现金最受欢迎的一个软件新版本中发现了这种分链漏洞,但这是在将近一半的网络升级到它之后才发现的。
发现漏洞
由于比特币现金是免费的开源软件,它经常被用作新兴加密货币的起点。除了受益于多年的改进之外,共享代码还意味着,其他不相关的加密货币可以从彼此的改进中获益。比特币现金的主要软件被称为比特币ABC(Bitcoin ABC),是基于比特币核心钱包的软件之一。
由于大量的通用代码,这些派生项目通常会有类似的漏洞,因此也会有类似的漏洞修复。但是,期望一种货币的开发人员积极主动地与其他货币的开发人员分享他们的改进是不现实的,因为单单要跟上一个项目就是足够困难了。出于这个原因,我养成了一个习惯,每隔几个月就会对这些项目进行一些修改,以查找可能与比特币核心钱包相关的漏洞修复。
在今年早些时候查看比特币ABC的变更日志时,我注意到交易验证中一个关键部分已经被重构。这些变更立即吸引了我的注意力,因为这些变更似乎是没有必要的。出于对这些变更的好奇,我看了一下公众对这些变更的评论。除了“封装”之外,没有任何理由能解释。这个变更只有两个审核人,审核持续一周后代码就被接受了。
大型重构是非常常见的,通常是特定软件开发中的良好实践。但是,修改加密货币的验证代码是极具风险的,极有可能会在无意中引入了一个链分叉错误。
在看到评论很少而变更很大后,我认为一个漏洞很有可能已经产生,所以我就去查看了一下。找到SIGHASH_BUG花了不到10分钟。
匿名披露
我在上面提到我的披露是匿名的。我想解释一下这个原因,因为匿名在这个过程中扮演了重要的角色。
在确认该漏洞可被人利用后,我开始通知比特币ABC(比特币现金协议的全节点实施)开发人员,但很快意识到我遇到了一个大问题。这是公开可用的开源软件中的一个漏洞,可能已经有人发现了这个漏洞。在完全部署修复程序之前,没有什么可以阻止其他人发现并利用这个漏洞。
那么在最糟糕的情况下,会怎么样呢?假设我以我的名义以非公开的形式披露了这个漏洞,而其他人也找到了这个漏洞并在第二天匿名利用了这个漏洞。因为我使用我的名字进行披露,所以会有足够的证据证明我有攻击比特币现金网络的知识和手段,而我无法证明我不是攻击者。然而,如果漏洞被利用,可能会造成数十亿美元的损失,代价远比杀害这些人要高得多。所以匿名是非常重要的,我认为这对我的安全是必要的。
在试图弄清楚是否可以完全匿名披露时,我开始怀疑它是否值得我花费这么多精力。毕竟,我没有义务报告任何事情。但是,如果有人在比特币核心钱包中发现了一个同样严重的漏洞,我会很希望这个人以尽可能谨慎和安全的方式引起我们的注意。所以我决定这样做:创建我想要阅读的报告,按照我想要的标准来写这个报告。
第一步很明显,我需要追踪比特币ABC的责任信息披露政策。如今,处理此类问题的策略很常见,并且对于任何安全关键项目来说都是必备的。遗憾的是,我在比特币ABC网站或代码库中找不到这样的策略。在我提交一个漏洞到他们的GitHub问题跟踪器时,我找到了最接近的一个策略。
然而这没有帮助。然后,我开始试图找到公开发布的比特币ABC开发人员的加密密钥。我向他们加密一条消息,确保没有其他人可以查看它,这样我就不用担心如何传递消息了。我无法实际验证密钥持有者的身份,但这种方法仍然是相当安全的,而且比根本没有加密要好得多。
但是,我又遇到了障碍。公共PGP密钥服务器上没有列出任何主要开发人员的密钥,而这些密钥通常都是在公共PGP密钥服务器上找到的,而且它们的代码存储库中也没有。当时,我别无选择,只能通过不同的在线渠道匿名请求密钥,使用Tor尽可能掩盖我的身份。
4月25日,我首先创建了一个一次性的Github账户,并在那里向一些比特币ABC开发人员发送了请求。
值得庆幸的是,这个方法奏效了!大约5个小时后,我收到了一把密钥,然后迅速用它对问题进行了加密的详细披露。然而,当我第二天回来查看回复时,Github标记了我的一次性账户,大概是因为我使用了Tor。所以我无法在Github继续进行进一步的接触,我只得假设没有人接收到了我的披露。
现在我有了加密密钥,我决定尝试最后一种方式:向比特币ABC的漏洞追踪器提交了一条加密消息,同样是使用Tor和一个一次性账户。6个小时后,在没有收到任何回复后,我在他们的追踪器上做了最后一次请求。
4月27日,在等待了大约48个小时后,比特币ABC发出了pull request,秘密解决了这个问题。显然他们收到了我的信息。成功!
我的思考
我发现的比特币现金漏洞已成功披露,且目前已经得到修补,最终没有对比特币现金造成明显影响。但是,如果整个加密货币生态系统没有从对这种漏洞的分析中得到一些经验和教训,那将是一种遗憾。作为加密货币开发者,有必要现在后退一步,重新评估我们可以使用的工具,以及我们实施的政策和程序。我们可能无法消除这些漏洞带来的威胁,但我们可以从中学习并做好准备,以便将来处理它们。
AD: 8月30日,猎云网2018年度“智慧+新服务”企业服务峰会落地上海!携手众多行业先锋领袖,共同探讨企业服务行业新风向。