摘要:随着智能合约飞速发展,越来越多的项目基于以太坊发行token,链上资产的类别和规模呈指数级增长,“虚拟世界”中的数字资产也点燃了黑客们的“热情”。以太坊区块链被认为是区块链的2.0时代,各种各样新的数字资产都基于以太坊发行早期代币甚至实现部分功能,虽然国外区块链社区甚至认为以太坊体量变得太大,已经不可轻易战胜,但以太坊也是数字货币历史上产生最多安全问题的币种,从2016年的The DAO事件,到最近的BEC,EDU,SMT的安全漏洞,以太坊的智能合约可以说充满安全漏洞。大多数的代币都在自己主网上线前使用以太坊代币,作为投资者,为了自身资产的安全着想,熟悉智能合约的漏洞概念变得尤为重要。
1
黑客利刃砍出的ETH和ETC
The DAO作为世界上最大的众筹项目,一度被寄予了厚望,所谓“成也萧何,败也萧何”,智能合约一度被捧上了天,但在这次The DAO事件当中,其递归调用(recursive calling)的漏洞却成为了黑客入侵的大门。此后出现“黑客”现身谈攻击合法性的戏幕,更是让人大跌眼镜,这第一次引出了智能合约代码监管的问题。
2016年6月17日发生了在区块链历史上留下沉重一笔的攻击事件。由于其编写的智能合约存在着重大缺陷,区块链业界最大的众筹项目TheDAO(被攻击前拥有1亿美元左右资产)遭到攻击,导致300多万以太币资产被分离出TheDAO 资产池。TheDAO编写的智能合约中有一个splitDAO函数,攻击者通过此函数中的漏洞重复利用自己的DAO资产来不断从TheDAO项目的资产池中分离DAO资产给自己。
攻击者组合了2个漏洞攻击,攻击者利用的第一个漏洞是递归调用splitDAO函数,也就是说splitDAO函数被第一次合法调用后会非法的再次调用自己,然后不断重复这个自己非法调用自己的过程。这样的递归调用可以使得攻击者的DAO资产在被清零之前,数十次的从TheDAO的资产池里重复分离出来理应被清零的攻击者的DAO资产。攻击者利用的第二个漏洞是DAO资产分离后避免从heDAO资产池中销毁。正常情况 下,攻击者的DAO资产被分离后,TheDAO资产池会销毁这部分DAO资产。但是攻击者在递归调用结束前把自己的DAO资产转移到了其他账户,这样就可以避免这部分 DAO资产被销毁。在利用第一个漏洞进行攻击完后把安全转移走的DAO资产再转回原账户。这样攻击者做到了只用2个同样的账户和同样DAO资产进行了200多次攻击。
被攻击后,Vitalik个人支持分叉的提议,也支持软分叉的开发工作,支持矿工升级客户端来进行分叉。然而Vitalik也认识到大家对这个提议有激烈的争论,无论哪一方的观点都有强力的反对。因为分叉不需要回滚交易,不会对用户和交易所造成不便,这更使Vitalik倾向于采取行动的一方。也有许多人,包括在基金会内部,倾向于另外一方反对分叉。Vitalik不会阻止也不会反对另一方在公开场合宣传他们的观点,甚至是游说矿工来抵制这个分叉。在这件事情上Vitalik会坚决的不与任何站在相对他的另一方的人争辩。
简而言之,他们所做的是更改以太坊区块链来修正DAO,但只有当大部分运行以太坊区块链网络的计算机同意,软件才能进行更新,摆脱掉漏洞,就好像攻击从来没有发生过。这一过程被称为硬分叉(hard fork),从此以太坊创造了一个平行世界,现在的以太坊其实是分叉出来的“以太坊”并在一年后狂飙突进的涨到了几百美元,而原来不愿意分叉的包含The DAO漏洞的以太坊则成了以太坊经典(ETC)。这一决定引发了强烈的反应,一年后仍然存在争议,无论是在以太坊社区还是比特币用户都坚持区块链的历史不能被篡改,有些比特币用户认为硬分叉在某些方面违反了最基本的价值观。
2
Binance黑客VIA事件
2018年在 3 月 7 日深夜(北京时间),有不少用户发现自己币安账户中持有的各种各样的代币、数字货币被市价即时币币交易成了 BTC。据网友反馈,被盗的账号不在少数,不少人还以为是币安系统错误导致的,还试图从币安客服那里得到解释。当他们还没有反应过来的时候,黑客已经开始了他们有组织、有预谋的行动。
黑客启动了所有盗窃的账户的买卖引擎,买卖规则就是卖掉所有山寨币,用市场价全仓购买VIA。而恰好黑客手里持有大量VIA,这样就相当于高价购买了黑客手里的VIA。于是,VIA的K线出现了惊人的振幅:2分钟内爆拉了110倍。从交易量和拉升价格来看,有大约1000个BTC的买单,把VIA的价格从0.000225btc拉到0.025,价格上涨大约110倍。
但是黑客的行动触发了币安的预警系统,黑客没能直接提出高价卖出所得的比特币。于是他们转而以超低价格爆砸比特币现货的订单列表,引起其他交易所期货价格的连锁反应。于是黑客预先埋伏的巨量空单获得巨大收益。黑客的攻击,已经去中心化了。
3
数据溢出
2018年4月22日中午(北京时间),BEC美蜜遭遇黑客的毁灭性攻击,天量BEC从两个地址转出,引发了市场抛售潮。当日,BEC的价值几乎归零。
以太坊区块数据显示,黑客利用以太坊 ERC-20 智能合约中数据溢出的漏洞,在攻击中凭空转出了
57,896,044,618,658,100,000,000,000,000,000,000,000,000,000,000,000,000,000,000.792003956564819968 个 BEC。转出数量远远超过了BEC的发行总数70亿枚,市场顿时陷入疯狂抛售,BEC近65亿元人民币的市值也几乎瞬间归零。
而攻击成功的原因,是因为BEC的一段代码忘记使用safeMath方法,导致系统产生了整数溢出漏洞。据PeckShield 团队今日凌晨发布的安全报告,黑客利用 in-the-wild(一种从代码中抓取漏洞的手段)方法,从BEC的程序中抓取到了漏洞,并发动了攻击。利用这个漏洞,黑客可以通过转账的手段生成合约中不存在的代币, 并将这些无中生有的数字货币转入正常账户。这些凭空产生的代币在使用上与真实代币没有差别。
4月25日,SMT爆发了类似的漏洞问题。SMT的智能合约中proxyTransfer函数存在一个经典的整数溢出问题。_fee 和 _value_ 这两个输入参数都能被攻击者控制,如果 _fee + _value 的结果正好为 0(也就是溢出的情况),第206行的检查将会失效。
这意味着攻击者不需要任何Token,就可以向一个地址转入大量的Token(第214行);同时根据第217行的代码,相当数量的手续费也将发送给 msg.sender。
要理解数据溢出的漏洞,首先要理解任何类型的数值都已自己的表达范围,计算机中的整数分为两类:不带符号位的整数(unsigned integer,也称为无符号整数),此类整数一定是正整数;带符号位的整数(signed integer),此类整数可以表示正整数,又可以表示负整数。无符号整数常用于表示地址、索引等正整数,它们可以是8位、16位、32位、64位甚至更多。8个二进制表示的正整数其取值范围是0~255( -1),16位二进制位表示的正整数其取值范围是0~65535( -1),32位二进制位表示的正整数其取值范围是0~ -1。
一个short 型的数值能表示的数值的范围是:-32768~32767,有负数有正数,这种是有符号数的表达范围,无符号数的表达范围是0~65535。你会发现这2种情况下都有65536个数字,这是2的16次方,也就是说short类型的数字是16位比特位表示的。
那么当一种操作,使得操作结果最终超出了类型能够表达的范围,计算机会如何处理呢,如上图所示,65535加1之后变成了0,加2变成了1,这就是所谓的数值反转,所谓的溢出就是超出了数值的表达范围。BEC的数据类型不是无符号的short类型,而是换成了uint256,不管什么类型,但只要是固定长度都有其表达范围,当cnt 与_value的乘法运算超出了uint256的表达范围,那么amount得到值会远远小于预期的值,就像上面的例子中65535这么大的数字加上1结果变成了0.那么当amount的数值很小,但是cnt和_value很大的时候,签名红色箭头表示的检查就会全部通过,但是,最后转账的时候,不是使用的amount,而是使用的_value,于是造成了可以让黑客攻击的数据溢出漏洞。
4
权限漏洞与组合套现
继BEC和SMT代币溢出漏洞被曝光后,EDU和BAI代币也出现重大安全漏洞,不过与之前BEC和SMT的溢出问题不太一样,这一回是权限控制产生的漏洞,攻击者不需要私钥即可转走任意地址上的EDU/BAI资产。
此漏洞为遗漏条件判断的低级漏洞,在 transferFrom 函数中,未校验 allowed[_from][msg.sender] >= _value 并且函数内 allowed[_from][msg.sender] -= _value; 没有使用 SafeMath,导致无法抛出异常并回滚交易。通过这个漏洞,攻击者不需要私钥即可转走指定账户里所有的 EDU,并且由于合约没有 Pause 设计,导致无法止损。漏洞被发现后,产生了大量洗劫行为,攻击者不需要私钥即可转走你账户里所有的 EDU和BAI。智能合约里的 transferFrom 是批准转账流程里的关键函数,这个由于不如 transfer 那么常用,容易被不小心忽略。这个流程最大的问题是权限问题。
这一次的EDU攻击其实也是被迅速发现问题,黑客无法提币的。但是黑客再次上演了拿着无法提币的现货拿来砸穿比特币价格,再去隔壁交易所做空比特币的戏码。黑客花了2个小时,将比特币砸到 7400 美元,爆掉了近3万张期货多单,成功收割期货和现货。黑客的攻击从5月20日开始,当天完成了4笔交易,第一笔交易就是利用Allow函数的漏洞从项目方的地址中偷走了30亿枚EDU Token,随后利用三次交易将Token进行了转手。
黑客的 Token 得手后,开始往交易所进行充值,并交易了约20亿个代币。火币 Pro 交易所发现合约漏洞的问题后,随即暂停了 EDU/BTC 和 EDU/ETH 的交易对,因为全球范围内只有火币 Pro 可以交易 EDU Token,所以 EDU Token 的市场交易在此全面停止。按照上面提到的交易数额 20 亿枚 EDU Token,黑客的账户上已经具备了超过 1000 个以上的比特币,虽然黑客的账户无法进行提币操作,EDU 已经无法进行交易,但是其账户内的比特币依旧可以进行市场交易。于是黑客发功了和3月7日一样的方式进行了本地交易所抛售比特币引发市场波动,同时跨交易所的期货做空交易。
比特币价格在 23 点 30 分开始暴跌,从 7880 跌到 7400 美元,2 小时内跌幅达到 6%。与此同时,OKEx 的期货交易中多单开始爆仓,从 23 日 23 点 36 分开始到 24 日 1 点 49 分结束,期间一共爆掉了 28664 张多单,共计 369 枚比特币。期间 OKEx 期货市场上做空交易额达到了 1.58 亿美元。如果黑客在此期间按照自己砸比特币价格然后做空的思路,在 OKEx 上下了空单,可以赚到近 2000 万人民币离场。
5
EKT的安全设计
由于货币需要一个稳定的系统,智能合约设计的越复杂出错的可能性就越高,所以在早期中本聪认为货币系统是不需要图灵完备的语言的,比特币之所以不支持智能合约也是觉得货币需要极高的稳定性。那么,如何运行区块链里保持货币稳定的同时又可以开发Dapp呢?有一种比较好的解决办法就是把Token链和DApp链分开。
在EKT中Token链是一个并行多链的结构,多链多共识,共享用户基础。作为一个DAPP开发者最关心的肯定是三件事:1. 开发难度 ;2. 用户体验; 3. 社区生态。那么Token链的设计就是针对不想自己重新开发一条公链,但想要发行token和链的开发人员。EKT主要面向的对象是开发者,所以在设计token链的时候最大的想法是设计一个可以吸引大家都来发币的平台(之所以大家过来发币是因为TPS高,手续费低,可以选择发链用自己的Token做交易费,还可以和其他的链共享用户),这样可以让在EKT上开发DAPP的开发者可以获得更多的用户资源。
EKT的中心思想是设计一个社区的机制,让开发者可以轻易的开发一个DAPP,其他的交给EKT来处理,安全问题当然也是EKT在设计之初考虑的重点。即使是早期在以太坊上运行的EKT代币,我们也认真的考虑到了潜在的安全隐患。
比如这次对很多项目发起攻击的“transferFrom”函数,EKT token就在 require(balances[_from] >= _value); 下一行增加了require(allowance[_from][msg.sender] >= _value);判断,确保了合约转账不会出现可供黑客利用的漏洞。
我一直坚持的一个观点就是token不应该是一个智能合约,而应该是一个预先定义好事件的一个“对象”,这个“对象”可以有自己的参数(比如总量、共识机制等等),接受token的地址可以有两种:普通的用户地址和合约地址,合约地址收到token之后可以执行非图灵完备的合约语言,进行简单的状态计算和token转移。EKT把Token链和DApp链分开,将来在很大程度上能避免之前说到的以太坊合约的漏洞问题。
以上就是我对区块链共识机制的一些思考,和一些在设计EKT的多链多共识时的安全考虑,以及Token链和DAPP链分离的解决思路。
【结语】
公链是区块链发展的前提基础,也是区块链行业未来发展的核心保障。而目前区块链的发展现状是,底层公链的性能尚未发展起来,在其上构建的各类DAPP严重受限于性能,各种共识算法都有不完美之处,安全问题也令人堪忧。由于智能合约一旦上传,即公开且不可更改,因此大多“区块链2.0”项目有安全性验证的需求。一些团体也开始致力于应用形式化验证技术,为智能合约和区块链生态提供安全保护。将智能合约转化为数学模型,通过逻辑上的推理演算来验证模型,从而证明智能合约的安全性。
但由于智能合约是“不可变更的”。一旦部署,它们的代码是不能更改的,导致无法修复任何发现的bug。在潜在的未来里,整个组织都由智能合约代码管控,对于适当的安全性需求巨大。过去的黑客如TheDAO或去今年的BEC,SMT,EDU,BAI等漏洞事件提高了开发者们的警惕,可我们还有很长的路要走。
各个公链在可扩展性,应用性,共识哲学以及安全建设上的角逐将持续很长一段时间。我们认为既然没有完美的防止漏洞的方法,把Token链和DApp链分开,让Token这个“对象”尽可能的简洁,是现阶段区块链行业里比较好的解决方案。
参考阅读:
20180306 3月7日这一夜,黑客耍了所有人
20180423 BEC美蜜现重大漏洞价值几乎归零,OKEx暂停BEC提现和交易。
20180423 BEC瞬间归零:黑客转移海量币,黑产大军开始监控币漏洞
20180503 智能合约bug是以太坊的缺陷?不用SafeMath就会溢出?别闹!
20180524 EduCoin(EDU) 智能合约漏洞分析及修复方法
《Ethereum whitepaper》
《EKT whitepaper》
文章转载自:EKT周讯