美文网首页Nervos Fans
智能合约重入漏洞

智能合约重入漏洞

作者: 526ba0512193 | 来源:发表于2018-07-23 18:24 被阅读9次

写好智能合约还真挺难的。

各种问题

这有什么新鲜的,编程本非易事。

首先,社会上引领技术潮流的,反倒是社媒上一撮精心佯装成程序员的营销高手们,于是乎引发了技术决策一边倒的倾向各种道听途说。然后就是以销售不负责软件为荣批发行业。

反正吧,写个靠谱的代码就那么苦难。

其次,学术上教授们似乎也放弃教授并发性了,改成教学生们“事件驱动”框架。“事件驱动框架”它就是“处理并发”的框架(就是kill并发),抓取互斥锁使代码无法利用并发性,进而避免产生并发错误。

反正吧,写个靠谱的代码就那么困难。

尽管以太坊智能合约不存在并发性这说,但也没躲开重入漏洞的威胁。且重入漏洞各种避之不及的坑,不信问问关注过DAO攻击的人。

那么,今天我们言简意赅的解释下这些坑能有多微妙。

下面是个token合约,31行代码,猛一看是个面向条件编程的榜样。

试试看,能否找出错误。

给个提示

首先,有没注意到此合约执行状态更改操作,根据先前的检查,在外部调用后预测正确性。

问题是:1、合约最后没有执行外部调用;2、也没有防止重入调用的互斥锁。

这个合约其实是个反例

这个反模式正是DAO出问题的地方。

所以,提示#1是这种用法是个红旗。

其次,有没注意到代码中还检查了一个全局不变量,即合约余额(this.balance)不能低于合约认为的数量(totalSupply)。 这叫防守编程,本身没错。虽说模式有问题,但合约看起来是很安全的,因为不变量检查似乎是保护了合约的重要的假设。

但是注意一下函数入口的函数修饰符中执行不变量检查。 意思是说,这种特殊的模式中,本该始终保持的全局不变量,倒像是个后置条件。 所以,提示#2,不变量视为后置条件总是安全的?

最后,注意更改第7行时引入的漏洞

if (this.balance != totalSupply) throw;

改成

if (this.balance < totalSupply) throw;

因此,从检查一个强条件,变成检查一个弱条件。这是提示#3。

若合约中的实际余额高于合约认为的数额会发生什么? 条件弱化够避免了有人向合约发送一小笔付款时,余额与内部计算值不匹配引发的合约自行失效。 但是,但是,检查只说了余额大于totalSupply,要是余额小于totalSupply怎么办?

有这么个事儿,说这三个问题同时出现的话,允许合约持有更多的资金(多于合约认为应该持有的资金),后果就是攻击者能够凭空提现。

注意:合约存款函数也存在缺陷,因为它用的是用户指定的金额,而非msg.amount。 这个函数应该是内置的,且合约还应该有个能用msg.amount调用存款的默认函数。

黑了

详情可以参见:

Possible drain vector in TokenWithInvariants.sol? · Issue #3 · PeterBorah/smart-contract-security-examples​github.com

大概其是说,攻击者先假装提现,让合约觉得余额少了。然后将提现的ETH重新存入并转移到第二个地址。 那么现在,合约中的余额超过了合约认为自己持有的数额,那么所有的超额部分都可以被提走。

“噫吁嚱”是我看到这场黑之后的反应。 重入攻击下,智能合约很容易变智障。一个31行代码的简单token合约,用防御模式编写,在函数入口孜孜不倦的检查不变量,还是上了重入攻击的套。

小贴士

要点就是:不要在合约中执行外部调用。 若调用了,那确保外部调后不再干别的。 若还想干别的,上互斥锁防范重入调用。 不只是刚外部调用的函数需要互斥锁,所有函数中都得上。

给工具链开发者的贴士:Solidity编译器或类似lint的工具需要对这些反模式进行检测并警告。

从更高的层面来说,我觉得EVM允许合约默认功能参与任意复杂行为没什么必要。 好比,除非A允许,否则A调用B时,EVM可以直接禁止合约B及其所有被调用方C到Z回调合约A。或者说,叫跨合约重入禁令,是默认的(可以解禁)。合约A可以不停的调用自己的内部函数,但若调用了外部函数,就回不来了。

这种禁止重入调用的禁令应该不会影响到合约功能,而且还能规避重入攻击。 不介意被重入调用的合约大可以更改默认。当然了,并不是说这种修复方法能规避所有外部调用引起的错误,好比还有跨合约错误等,但至少方向没错。默认禁令的方式,在合约的表达上、性能上或其他,并没有牺牲掉什么东西。那么不介意重入调用的合约,决定关闭默认,也是可以的。

默认禁令的方式或许有点麻烦。 我相信或许有更全面的方法可以避免这类错误。

若真有,请不吝赐教。

Reentrancy Woes in Smart Contracts​hackingdistributed.com

相关文章

  • 智能合约重入漏洞

    写好智能合约还真挺难的。 各种问题 这有什么新鲜的,编程本非易事。 首先,社会上引领技术潮流的,反倒是社媒上一撮精...

  • 区块链智能合约安全之一(盗币攻击)

    下一篇:区块链智能合约安全之二(重入漏洞)transferFrom权限控制不当导致的任意盗币攻击智能合约里的tra...

  • 区块链Solidity安全-重入漏洞

    重入漏洞说明 以太坊智能合约的特点之一是合约之间可以进行相互间的外部调用。同时,以太坊的转账不仅局限于外部账户,合...

  • 合约安全:重入漏洞

    一、漏洞 这个被攻击的EtherStore合约,可以用来deposit和withdraw以太币。withdraw函...

  • 阅读etherscan上所有的合约转账代码

    自从出了智能合约溢出攻击事件之后,大家纷纷讨论发现了智能合约漏洞了之后怎么自由之类的,整天意淫着能找到一个合约漏洞...

  • 合约安全-重入攻击漏洞

    背景:由于公链环境下所有的信息都是共享的,智能合约相当于是完全透明化,任何人都可以调用,外加一些利益的驱动,导致引...

  • 区块链智能合约安全之二(重入漏洞)

    上一篇:区块链智能合约安全之一(盗币攻击) 以太坊智能合约的特点之一是能够调用和利用其他外部合约的代码。合约通常也...

  • 安全事件

    最近,智能合约漏洞很火。 让我们再来看一下4月22日BeautyChain(BEC)的智能合约中一个毁灭性的漏洞。...

  • 本次FTN暂停交易事件回顾

    1.本次FTN暂停交易的原因 FTN的智能合约代码存在安全漏洞。FTN智能合约中的 batchTransfer 批...

  • 以太坊君士坦丁堡升级延期

    ​​昨日凌晨,以太坊君士坦丁堡代码突然爆出“可重入”漏洞,该漏洞可以用来攻击相关合约修改用户余额或其他关键变量。P...

网友评论

    本文标题:智能合约重入漏洞

    本文链接:https://www.haomeiwen.com/subject/xgnjmftx.html