会员登录 注册新帐号电脑店行业门户 | U盘启动工具

首页

当前位置: 电脑店主页 > 资讯中心 > IT业界 > 国内 > 一文详解:价值3100万美元以太币“偷天换日案”始末

一文详解:价值3100万美元以太币“偷天换日案”始末

发布时间:2017-07-25 15:10      点击:     关注官方微博:

 编者注:本文作者为Haseeb Qureshi,软件工程师,曾就职于Airbnb。

  近日,一名黑客实施了一次数字货币抢劫,规模之大,史上第二。

  大约在太平洋标准时间12点,一名未知名黑客发现了以太坊网络Parity多重签名钱包的重大漏洞,几分钟之内偷走价值3100万美元的以太币。如果再给他几个小时,恐怕价值超过1.8亿美元的钱包要被细节而空。不过,好在有人阻止了这一切。

  在警报之声敲响后,一群以太坊社区热心的白帽黑客迅速组织起来,对袭击进行了分析,随后认识到,已经偷走的拿不回来了,但还有更多钱包处在危险当中。时间就是一切,于是他们想出了惊人叫绝的,也是唯一的一个办法:在黑客袭击之前,先把剩下的钱包通通击破。

  在发现同一个漏洞之后,这群白帽黑客袭击了所有剩下的钱包,抽空了账户,有效防止了1.5亿美元的损失。

  是的,你没看错。

  为了防止黑客抢劫更多银行,这群白帽黑客编写了一套软件,把全世界剩下的银行都给“打劫”了。在钱财被“安全盗取”之后,他们开始返还各个账户所有人的钱。

  这无疑是一则精彩绝伦的故事,但更重要的是,它对数字货币世界带来了震撼性的影响。

  需要理解的是,上述漏洞并不在以太坊或Parity本身,而存在于智能合约代码中,后者是Parity借以为客户提供多重签名钱包的基础。

  听起来非常复杂,那么我们就把细节都解释一下,好让大家都能理解。本文一共分为三部分:

  1.到底发生了什么?解释以太坊,智能合约和多重签名钱包;

  2.他们是怎么做到的?对袭击的技术解释;

  3.现在怎么办?这次袭击对智能合约未来发展及安全的影响。

  如果你熟悉以太坊和数字货币,可以直接跳到第二部分。

  1.到底发生了什么?

  在这则故事中,存在三个重要“人物”:以太坊,智能合约和数字钱包。

  以太坊是诞生于2013年的数字货币,比比特币小4岁。自诞生以来,它已经成为世界第二大数字货币,价值200亿美元,与此同时比特币价值400亿美元。

  和所有数字货币一样,以太坊也是比特币协议的衍生,是对比特币设计的升级。但不要搞错,尽管它和比特币一样同为数字货币,却拥有更强大的力量。

  比特币使用区块链来完成货币交易的分类账,以太坊则用区块链在巨大的分布式计算机中记录交易活动。以太坊相应的货币——以太币——从本质上来说,用以支撑应用的运行。

  换一个方式讲,以太坊实际上是一个运行于整个世界的计算机。任何在自己的计算机上使用以太坊软件的人都参与了这一世界电脑——以太坊虚拟机(EVM)的运行。由于EVM设计之初即图灵完备,因而制药是计算机程序能够表达的,它几乎都能做到。

  说严重点:这东西太疯狂了。数字货币世界因为以太坊的潜力而激动不已,这也是它过去6个月里价值飞涨的原因。

  在以太坊背后,一个开发者社区已经组建起来,许多人对EVM之上能够开发什么东西感到心奋不已,而说到这里,就不得不提智能合约了。

  智能合约简单来说就是运行于EVM之上的计算机程序。从许多方面来讲,它们和普通合同差不多,除了不需要律师或法官来进行解读。相反,它们被编译成字节码,由EVM负责阐释。通过这些程序,你可以以编程方式,根据合同代码的规则转移数字货币。

  当然,也有很多事情是普通合同能做而智能合约无能为力的,比方说智能合约无法与区块链之外的事情进行沟通。同理,许多事情智能合约可以做到,普通合同却不能,比如完全通过不可破解的密码术来执行一套规则。

  接着,我们就需要了解钱包的概念。在数字货币世界,钱包是你存储资产的方式。你可以通过秘密密码来进入钱包,这一串密码也就是所谓的专用秘钥。

  遵循不同安全属性,钱包也分为许多种类。而其中最受欢迎的就是多重签名钱包。

  在多重签名钱包中,账户持有人可以通过几个专用秘钥来打开,但仅知晓一个秘钥是不行的。举例来说,如果你的多重签名钱包有3个秘钥,那么你可以指定至少拥有2个秘钥才能打开。

  这也就意味着,如果你,你的父亲,你的母亲分别是签名者,那么即便犯罪分子袭击你母亲并偷走了她的秘钥,他还是没办法接触到你的资产。由于拥有更高的安全保证,多重签名实际上是钱包安全方面的标准做法。

  而这种钱包,正是黑客下手的对象。

  到底是哪里出了问题?他们破解了专用秘钥吗?还是他们使用了量子计算机,或者某种尖端的因子分解算法?

  通通答错,所有密码术完好无损。漏洞说出来甚至叫人发笑:他们发现了一个程序员引入的bug,能够重新初始化钱包,就像恢复到出厂设置一样。一旦恢复出厂设置,黑客们就能把自己设为账户所有人,然后揣着钱大摇大摆的离去。

  2.这一切是怎样发生的?

  接下来,我们要从技术角度解释这一事件发生的原因。如果你不是专业程序员,可以跳过这一段。

  以太坊是一种相对特别的编程模式。在以太坊上,你可以通过发布合约来编写代码,并通过调用方法更改其状态以执行交易。

  为了让代码能够运行于以太坊上,你首先应部署合约,这需要花费一些以太币。接着,你需要花更多以太币,调用方法与合约互动。可以想象,这样做能够激励程序员优化自己的代码,一方面简化交易过程,另一方面也可以节省计算成本。

  想要节省成本,还有一种途径就是,使用开发库。你可以将自己的合约建立在共享开发库上,无需重新部署任何共有代码。在以太坊世界,不重复自己的代码可以直接省下很多钱。

  多重签名钱包Parity正是采用了这一方法。它引用了一个包含钱包初始化逻辑的共享外部库,该共享库由开发库契约的公钥引用。

  该开发库通过名为DELEGATECALL的EVM指令在几个地方进行调用,执行以下操作:对于任何调用DELEGATECALL的方法,它将调用与委派合约相同的方法,但使用当前合约的上下文。 本质上来说,它就像一个超级调用,除了没有继承运用。

  下面我们用多重签名钱包举个例子:名为isOwner的方法使用当前合约的状态,委派给了共享开发库的isOwner方法。

  看上去没什么值得注意的。多重签名钱包本身包含所有所需的权限判断,且严格执行了与钱包状态相关的敏感操作授权。

  但他们犯了一个至关重要的错误。

  Solidity允许你定义一个“回退方法”,当没有能够匹配给定方法名称的方法时,回退方法会被调用。

  Parity团队决定,让所有以太发送给合约的未知方法默认存储在发送的以太中。

  但他们多走了一步,这是这一步导致了严重错误。以下是真正遭受攻击的代码。

  简单来说:

  如果方法名在合约中未予确定……

  且交易过程当中没有以太币参与……

  且符合内容中存在一些数据……

  那么只要_walletLibrary中对此有定义,系统就会调用相同的方法。发现这个漏洞之后,黑客调用了名为initWallet()的方法,这个方法在多重签名合约中并不存在,但存在于共享钱包开发库中。

  接着,initMultiowned方法被调用……

  看出来了吗?黑客实际上通过委派开发库方法,对合约进行了重新启动,并重写了原合同的持有人。

  那么,从这起事件中我们应当总结出什么?

  3.这起袭击对以太坊来说意味着什么?

  首先,记住,这不是以太坊的漏洞,也不是智能合约的漏洞。相反,这是特定合约中,程序员所犯的错误。

  那么,是谁写下了这些代码?他们本该提早意识到问题的,对吗?

  事实上,Parity钱包背后的开发人员包括以太坊创始人,Parity核心团队,以及开源社区的成员。这些代码是经过同行的严格审查的,基本代表着以太坊生态系统中编程的最高标准。但这些程序员也是人,会犯错,审查人员同样如此。

  有人在Reddit和HackerNews等平台上斥责:“多明显的错误!他们怎么会忽视这一点的?”

  写下这些评论的人一般都不是专业程序员,如果是一个专业程序员,他的反应会是:糟糕,真是个菜鸟级别的错误。

  在编程工作中,这种错误时有发生。所有程序都因为人工编写,而承受着错误的风险。我们必须抛弃这样一种思维:“如果他们再仔细一点,这件事就不会发生了。”当你的程序到达一定规模,再仔细都是不够的。

  当程序的复杂度已经无法用细微来形容时,你要知道,这个程序很可能是不正确的。无论多少喝茶、测试,可能都无法发现所有潜在bug。

  哪怕是谷歌或NASA等公司或机构,也会犯程序错误,不管他们在编写代码的时候投入了百分之几百的专注力。

  我们可以从谷歌、Airbnb等公司身上借鉴些许。每当出现bug或问题,他们都会进行事件分析,并将分析结果分发给公司所有人。在进行这些分析时,他们有一条规定:不责怪任何人。

  把错误归咎到个别员工身上是没有意义的,因为所有程序员,无论经验多风度,都不可能永远不犯错。而事件分析的目的在于,在开发过程中,是什么导致了错误的出现。

  就以太坊事件而言,问题不在于程序员忘记在钱包开发库中添加internal方法,也不是在不检查的情况下就调用delegateCall方法。问题在于,他们的编程工具链让他们犯了这个错误。

  随着智能合约生态系统不断升级,它必须沿着一个方向——也就是增加犯错难度的方向发展。

  这就要说到我的下一个观点。

  在编程语言世界,能力越强,反而是一种劣势。

  编程语言的表达能力越强,它的代码就会越复杂,而Solidity就是一种非常复杂的语言。

  复杂性是安全的天敌。复杂的程序往往难以推导,也不容易发现极端情况。编程语言限制的动作越少,合约的分析和属性证明就越简单。想要证明一套程序的安全性,唯一的办法就是推翻每一个潜在攻击,比方说,“这个合约不能被重新启动”,“它的资产只有所有人能够接触到。”等等。你需要推翻的潜在攻击越少,证明某一合约安全的难度就越低。

  尽管存在这样那样的问题,但以太坊不会因为它里面有多少钱而存活或失败。它的存亡,取决于正在为它而奋斗的程序员们。

  白帽黑客组织起来,保护脆弱的钱包并非为了钱;他们之所以这么做,是因为他们相信这一生态系统。他们希望以太坊能越来越好,他们想要看到自己梦想中的未来成为现实。在所有的猜测和暴利背后,是这群人,将带领以太坊社区迎来未来。从长远来看,他们将是推动以太坊成功的核心因素;如果以太坊被放弃,那肯定也是他们的选择。

  这次袭击很重要,它让大家清醒,推动整个社区走上漫长的寻求安全解决方案的道路。与此同时,它也将促使程序员在面对智能合约编程时,采纳比现在高得多的标准。

  不过,这次袭击并没有打击到以太坊开发人员的力量。因此从这个角度讲,这一事件只是暂时的阻碍。

  最后要说的一点是,像这样的袭击对于整个社区的成长是有好处的。它们触动了你的神经,迫使你时刻保持警惕。虽然它们伤害力很高,媒体也会大肆渲染悲哀的情绪,但每一个道伤口都会让以太坊社区更加强大,让我们真正深入理解区块链技术——不仅是它的危险,更是无穷的潜力。

★★★ 电脑店行业门户(www.diannaodian.com)独家文章,欢迎大家转载 ★★★