前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何摧毁黑客梦想, 提升EOS游戏体验? 本营小仙女: 比他们更努力!

如何摧毁黑客梦想, 提升EOS游戏体验? 本营小仙女: 比他们更努力!

作者头像
区块链大本营
发布2018-12-20 17:03:28
6130
发布2018-12-20 17:03:28
举报
文章被收录于专栏:区块链大本营

安全,一直是区块链领域举足轻重的话题。今天咱们聊聊由 RAM 消耗漏洞及回滚交易漏洞引起的安全隐患,以及对应的解决方案。 文章趣味十足且不生涩,干货满满,希望对你有所帮助!

千淘万漉虽辛苦,吹尽狂沙始到金 —— 《浪淘沙》刘禹锡

上回书说到

DApp 假币鱼目混珠

转账函数检测疏漏马虎

对于制造伪 EOS 以次充好,其实只需要检查发行方是否为 eosio,或者调用相关合约查看代币信息,但是检查代币操作依然不够严谨的情况下又会产生更多的变体漏洞,导致遭受变体攻击的风险,所以 EOS 智能合约中的代码非黑即白,切不可模棱两可。

要做到完备的漏洞防御,必须先透彻理解 EOS 业务逻辑特性以及规则限制。本期我们就由 EOS 业务逻辑特性为切入点,解析 RAM 消耗及回滚交易漏洞。

本期话题

陌生转账 RAM 被吞,交易回滚大奖送人

每一位游戏玩家都曾在游戏中体验过一马当先,万夫莫开的畅快淋漓,也体验过心惊胆战,如临大敌的彻骨寒意。但游戏终究是游戏,大多数情况下,都有许多尝试的机会,尤其是单机游戏,可以适时存档后,重新读档不断尝试“从跌倒的地方爬起来”。

在 EOS 游戏和 DApp 不断涌现的今天,还没有出现与传统单机游戏结合的机制。倒是有很多竞猜类的游戏大受欢迎,但是竞猜类游戏以公平竞猜为游戏理念,不能允许玩家以不断尝试的方式获取奖励。

不断尝试确实是增加获取奖励几率很有效的方式,于是黑客们找到了一种零成本不断尝试竞猜的方式,试图在 EOS DApp 中轻而易举拔得头筹。介绍这种攻击手段之前,让我们来了解一下 EOS 特殊的业务逻辑。

基础知识

EOS 智能合约业务逻辑特性

在 EOS 智能合约交易情景中,合约常常需要根据收到 EOS token 的情况来执行相关业务逻辑, 这主要是通过 eosio.token 合约中 transfer 函数的通知回执来实现的:

当用户 A 向用户 B 转账时,用户 B 会接收到这个通知,并可以进行相应的函数处理,这是由require_recipient 的特殊机制产生的结果。

require_recipient 在这里的实现逻辑是: 将原本的 action receiver 修改为传入的账户, 再发起一次 action 调用,相当于带着同样的参数又调用了一次 A 和 B 账户的 transfer 函数。

关于这个特殊的机制,EOS 官方给出了相关的解释:

那么,如果在 B 账户部署一个智能合约,定义一个 transfer 函数就可以进行相应的业务逻辑处理,示例如下:

注意,这里的 transfer 函数使用了上一期提到的 if (from == _self || to != _self)防御手段,验证收到转账的是自己来预防变体转账攻击。

当然,除了 transfer,require_recipient(account_name 合约账户 XXX)也可以调用 XXX 合约中的其他同名函数。

漏洞如影随形

RAM 消耗漏洞

按照上面 B 账户里面的智能合约实现业务逻辑,是没有什么问题的,但是如果按照如下合约实现的话,问题就会出现了:

这个智能合约中,komo::transfer 中的 for 循环用账户 from 的授权写了很多无用的记录到state.db,而这个操作用户在 eosio::transfer 时是不知情的。

有关方面给官方写出了这个情况的修改建议:

在 require_recipient 触发 action handler 执行时, 禁止被触发的 handler 使用当前 action 的授权。 如果被触发的 action handler 有存储要求,可以使用 inline actions 来解决, inline action 被执行时就不会用到原来 action 的授权了。

但是,使用 inline action 如果不加注意,又会产生另一个漏洞。

回滚交易漏洞

历史事件

eos.win 在 2 月 9 日被攻击者利用 inline action 漏洞的回滚交易攻击通关过,交易细节如下:

EOS 合约内部的 action 调用分为 inline action 和 deferred action,用于合约对其他 action的调用,这两种调用方式是有一定区别的:

1. inline action 与原来的 action 是同一个事务,如果 inline action 失败了,整个事务 会回滚; 2. deferred action 与原来的 action 不属于同一个事务,并且不保证 deferred action 能 够成功执行,如果失败了,也不会引起原有 action 的事务回滚。

在早期,很多 EOS 游戏合约都是使用 inline action 这种方式来实现的,从下注、开奖、发 奖、通知,一系列操作虽然写在不同的 action 中,但是执行的时候都是通过 inline action的方式来联动,达到用户下注后自动开奖发奖的效果。

在这种情况下,如果合约通过 require_recipient 来向用户账户发送开奖通知,那么用户账 户就可以通过接收 require_recipient 的通知来判断是否成功赢取奖励,如果失败,那么调用 eos_assert(0)来使 action 执行失败,由于所有 action 都是 inline action,这将会导致整个 transaction 失败,用户下注的 EOS 会退回。

如果合约没有发送 require_recipient 通知,攻击者也能通过自己组装 inline action,然后通过对自身余额或者合约数据库数据的判断来实现回滚攻击。

这样,攻击者制造 action 执行失败后,就能将每次投注的 EOS 退回,从而无成本重新加入游戏,直到获奖为止,模拟了单机游戏中“无限读档”,直到通关的游戏方式。

漏洞修复

在实现自动开奖发奖的一系列动作中,不要惯性思维的使用 inline action,适时使用 deferred action 可以预防整个一套交易流程回滚到下注之前,规避攻击者零成本再次参与游戏的风险。

黑客尚可锲而不舍,安全怎能松懈怠惰

EOS 与以太坊相比,以其吞吐量大,处理速度快,以及交易成本低等优势占据了开发 DApp 的有利地位,与初期的以太坊相比,低级错误导致得安全漏洞发生率似乎有所降低,但是由于游戏以及 DApp 的业务逻辑性比单纯的数字货币智能合约要复杂许多,黑客依然能够在业务逻辑中找到开发者不曾设想过的“套路”,作为迅速获利的垫脚石。

本期的回滚交易攻击说明,即使是攻击者,也想到用不断尝试,不断努力的方式达到自己赢得游戏的目标。作为区块链安全生态的支持者和建设者,我们每一个人更应该以锲而不舍的精神,从底层代码做起,维护区块链相关应用的安全,稳步发展。

参考资料: [1] 警惕!EOS 恶意合约可吞噬用户 RAM 漏洞分析 http://www.cocoachina.com/cms/wap.php?action=article&id=24425 [2] eosflare.io https://eosflare.io/tx/e28fa9fbd6008edc1a66e01ea4e443265eb9bacce0b423351d178dcb 6928de3b [3] Inline action to external contract https://developers.eos.io/eosio-home/docs/sending-an-inline-transaction-to-exte rnal-contract

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-11-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 区块链大本营 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
区块链
云链聚未来,协同无边界。腾讯云区块链作为中国领先的区块链服务平台和技术提供商,致力于构建技术、数据、价值、产业互联互通的区块链基础设施,引领区块链底层技术及行业应用创新,助力传统产业转型升级,推动实体经济与数字经济深度融合。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档