你的RAM可能已被EOS恶意合约吞噬

曲速未来安全区
曲速未来安全区 机构得得号

Aug 03, 2018 专注于为读者提供区块链安全领域最新讯息

摘要: 恶意 EOS 合约存在吞噬用户 RAM 的安全风险。现将漏洞分析公布出来,供社区研究参考,以方便自查和防御。

 写在前面的话:

7月24日消息,据有消息称收到情报:恶意 EOS 合约存在吞噬用户 RAM 的安全风险。本次发现的漏洞,恰好会导致用户账户内的RAM可能被恶意消耗,引发直接财产损失。

恶意EOS合约存在吞噬用户RAM的安全风险,需要引起各大交易所、钱包、token空投方、DApp、用户等的警惕,避免遭受损失。

EOS最新消息

EOS,是专门为商用分布式应用而设计的一款高性能区块链操作系统,是一种新的区块链架构,旨在实现分布式应用的高性能扩展。EOS的发布,被誉为区块链3.0时代的到来。

在EOS智能合约执行过程中,需要消耗EOS节点的cpu和内存资源,这些资源按照交易发生时的CPU资源和RAM资源价格,支付给EOS节点,从前一段时间被爆炒的RAM价格就可以看到RAM的稀缺性。

7月27日就有报道 EOS的内存RAM,曾一个星期涨了15倍,两个星期涨了50倍,暴涨把EOS推到了风口浪尖,也着实让RAM火了一把。现在EOS的RAM容量上限为64Gb,此后通过逐步增加容量到1Kb。目前,EOS交易价格约为8.79美元,该加密货币总市值已经达到78.75亿美元,在所有加密货币市值排名中位列第四位。

什么是RAM

RAM就是EOS的内存,它不是一种代币或通证,它就是EOS的内存资源而已。它在EOS软件平台上对应的就是内存数据库资源。作为DAPP开发者,RAM是一项宝贵资源,数据库记录需要消耗RAM。为了保持超级节点的高效运行,节点、RAM、内存总量有上限(以后会扩容),如果要保持区块链数据可以随时存储、修改,就需要这部分数据存储在内存中,而内存的使用需要用户自己去EOS系统中购买,不需要的时候再卖给系统,换回EOS代币。而随着RAM不断地被租用,剩余可用的RAM越来越少时,RAM所需要抵押的EOS就会越来越多,也就是说RAM的价格会越来越贵。

RAM有什么作用?​

在 EOS 网络上,大量的操作都需要消耗RAM来存储数据,比如创建一个 EOS 账号、创建一个 EOS 智能合约、进行 EOS 转账等。

经过几天的反复调试确认沟通后,已经充分了解漏洞危害。为了避免在这段真空期内发生恶意利用攻击,现决定将漏洞细节公布出来,供社区研究参考,以方便自查和防御。

EOS 的合约可以通过require_recipient触发调用其他合约,设计这样的机制给合约的开发者提供了很大的便利性, 但是也带了新的问题,因为在测试的时候发现require_recipient 有可利用的漏洞导致RAM在不知情的情况下被滥用。

某个用户给合约转账,合约可以在用户不知情的情况下消耗用户的RAM(下面的例子中可以消耗200多人民币的RAM)

随后得到了官方的回应:

这一漏洞需要引起各大交易所,钱包,空投方,以及用户的注意 
在问题没有解决之前,用户应避免使用有大量RAM的账号给陌生账号转账

问题分析

在DAPP 的开发过程中, 为了获取转账信息, 一种方法是采用require_recipient来订阅转账通知, 原理是这样的: 

在系统合约eosio.token 的transfer 中, 转账时会分别通知from 和 to;   

如果账户to 本身是个合约账户, 并且也实现了相同的transfer 方法, 则这个to合约的transfer方法会被调用。 

在自己的合约实现相同的transfer 方法:

这个流程看似没什么问题,但是却带了安全隐患,可以恶意消耗账号from 的RAM 资源。 在上面的例子中 komo::transfer 故意用账户from 的授权写了很多无用的记录到state db, 而这个操作用户在授权eosio::transfer时是不知情的。

问题验证

在测试网络中分别创建3个账号, test11111111, test22222222, komo11111111(合约账户, 部署了上面的合约komo) 

测试之前查看 test11111111 RAM 资源

给普通账户 test22222222 转账

再次查看test11111111 RAM资源

没有变化, 还是107.5 KiB;再给合约账户 komo11111111 转账

再次查看test11111111 RAM资源, 发现被消耗了(142.2-107.5)= 34.7K 字节! 原因是上面komo::transfer 中的for 循环用账户test11111111的授权写了很多数据到state db

代码分析

因为komo::transfer 这个handler 是被eosio.token::transfer 中的require_recipient 触发的, 在代码中当前action 已有账户 from 的授权。 所以检查权限时不会报错。

​并且我们发现, 只要维持这个数据结构占据的字节不变,这个窃取的RAM在komo合约中是可以一直使用的。

修复办法

曲速区建议:在require_recipient触发action handler 执行时, 禁止被触发的handler 使用当前action 的授权。  
被触发的 action handler 有存储要求怎么办? 可以使用inline actions 来解决, inline action 被执行时就不会用到原来action 的授权了。

防御手段

相关项目方在做转账操作时可通过命令行 “cleos get code” 判断目标地址是否为合约地址,避免RAM被恶意吞噬导致损失。

另外在问题未解决之前,可以减少用来转账的账户持有的 RAM 数量,尽可能避免遭受损失。

链得得仅提供相关信息展示,不构成任何投资建议
本文系作者 曲速未来安全区 授权链得得发表,并经链得得编辑,转载请注明出处、作者和本文链接

更多精彩内容,关注链得得微信号(ID:ChainDD),或者下载链得得App

分享到:

相关推荐

    评论(0

    Oh! no

    您是否确认要删除该条评论吗?

    分享到微信