EOS合约吞噬用户RAM回放分析及实践

    这几天,有两个朋友问到我“Cannot charge RAM to other accounts during notify”这个错误提示,我才想起原来曾经还存在过这个问题,也许是前段时间的Bancor和“假EOS”漏洞等事件影响力太大,导致很多开发人员忽略了这个RAM更新。于是,我翻了翻笔记,重新整理了下跟大家一起分享,也算是做个记录。

 

合约吞噬用户RAM原理分析

 

    这个bug的核心是require_receipt函数。目前eosio.token智能合约的转账函数transfer会调用require_receipt(to), 当to账号是一个智能合约时就会调用to的智能合约transfer方法。也就是说用户在调用系统合约(安全的代码)转账EOS的时候竟然可能会执行另外一段代码(可能是恶意代码),这段恶意代码还能得到from用户的授权,这可太危险了。这里有两个风险。

    1)如果恶意代码再调用其他合约,比如执行inline action 转账EOS给其他账号,具体金额恶意代码可以任意填写。当然,事实上这个风险肯定是已经被堵上,这个就是大名鼎鼎的eosio.code权限。恶意代码要以from的授权再执行eosio.token这个其他合约,必须得到from账号的eosio.code权限。

    2)恶意代码没法调用其他合约,那就只能在自己的合约里干事。但是在自己合约能干的有价值的事就只剩下ram,使用from的ram在本合约table创建大量数据。

 

哪些用户容易中招

 

      到了这里,你可能会说,恰好转账到恶意合约账号的机会还是很少的。实事上确实如此,但是有些群体是很容易中招的,比如交易所和空投方。

    交易所

        恶意合约用户可以主动从交易所提取EOS到恶意合约账号,这实际上会发起一个EOS转账,自然就会让交易所账号执行恶意代码,然后恶意代码消耗多少RAM就看交易所账号的RAM量了。由于一次交易的执行时间是有限的,因而一次转账消耗的RAM也是有限的,但是由于交易所的EOS转出操作零手续费或者很低的手续费,作恶者就可以重复执行转出操作来消耗大量RAM,所以交易所是中招大户。

 

    空投方

        由于代币空投方一般会空投代币到所有账号,或者活跃账号,这样空投账号就很容易转账到恶意合约账号,自然也就中招了,然后还浑然不觉。

 

Bug修复方法

 

    很显而易见的方案就是不允许在require_receipt引发的合约代码中消耗其他账号的RAM,具体代码如下:

 

EOS合约吞噬用户RAM回放分析及实践_第1张图片

有了这个补丁后,如果再偷RAM就会如下的错误。

    

正规智能合约如何适配这个改动

    

    很多游戏或者代币交换合约都是通过require_receipt来监控EOS转账行为然后修改合约里的table数据做记录或者换币, 也就说是这一过程消耗RAM产品正常的需求。那上面改动后,这个消耗RAM的问题怎么解决呢?智能合约买单, 即将消耗RAM的payer从用户改为智能合约,比如下图

 

        EOS合约吞噬用户RAM回放分析及实践_第2张图片

     如果是一个EOS兑换代币的合约,最后一般是调用add_balance分发代币:

 

漏洞及Require_Receipt实操源码

    

https://github.com/itleaks/eos-contract/tree/master/stealram-exp

|**************************************************
* 本文来自CSDN博主"爱踢门",喜欢请点关注
* 转载请标明出处:http://blog.csdn.net/itleaks
***************************************************|

如果你对EOS,ETH技术及开发感兴趣,请入QQ群讨论: 829789117

EOS合约吞噬用户RAM回放分析及实践_第3张图片
如需实时查看最新文章,请关注公众号"区块链斜杠青年",一起探索区块链未来

EOS合约吞噬用户RAM回放分析及实践_第4张图片

 

          

你可能感兴趣的:(区块链,EOS)