WF曲速未来消息:GodGame漏洞原理以及黑客攻击手法分析

WF曲速未来消息:在8月 22 日,一个名不见经传的游戏God.Game发出通告,声称遭遇黑客攻击,游戏内的以太币被黑客全部转走。

前言:

WF曲速未来消息:在8月 22 日,一个名不见经传的游戏God.Game发出通告,声称遭遇黑客攻击,游戏内的以太币被黑客全部转走。盗走ETH的黑客地址为:0xC30E89DB73798E4CB3b204Be0a4C735c453E5C74。

God.Game简单规则如下:GOD股份购买的所有数量的10%被征税并且作为被动的ETH收入分配给所有GOD所有者。

通过游戏官网规则,以及合约源码分析,不少人会认为God.Game是PoWH3D的直接仿品,安比(SECBIT)实验室仔细分析后发现,它其实是综合“借鉴”PoWH3D 和Zethr的混合仿品。

PoWH3D是最近大热的Fomo3D游戏团队上一款作品。而Zethr则是在PoWH3D基础上进一步开发优化,新增不同玩法的另一款热门游戏。

然后对其进行了详细的分析,得出其根本原因是由于某处关键数据整型溢出漏洞导致...

上面提到,God.Game游戏代码重度参考了PoWH3D和Zethr。而与漏洞相关的关键函数名transferFromInternal()只在Zethr合约代码中有出现。

上图所示问题代码,“创新”地增加了一组关于转账双方是合约、还是普通账户的分支情况处理。面对这一串冗长的代码,只要清楚PoWH3D工作原理,就很容易能发现此处代码逻辑根本说不通,也无法在游戏实际规则中找到适配点。并且这种根据账户类型分别处理账本的逻辑在原版PoWH3D和Zethr中根本没有出现。

攻击手法:

黑客地址:0x2368beb43da49c4323e47399033f5166b5023cda。

黑客的攻击步骤:

1.攻击者购买少量token;

2.创建攻击合约;

3.把token转给攻击合约;

4.调用攻击合约的withdraw函数

5.调用攻击合约的transfer函数

6.调用攻击合约的reinvest函数

7.调用攻击合约的sell函数

8.调用攻击合约的transfer函数

这便是该黑客一系列的攻击步骤,乍一看,充满迷雾,攻击合约也没开源,只能靠逆向,经过层层分析,该攻击合约只是相当于一个“代理”,举个例子,攻击者若调用攻击合约的withdraw函数,那么该攻击合约就会去调用godgame的withdraw函数,然后再把结果返回给攻击者。

那攻击者为何要使用攻击合约间接调用而不直接调用godgame合约,为何要调用这些函数呢?这便是本文的重点了,以下会对攻击者的每个步骤进行剖析。

分析

在理解漏洞之前我们需要先了解一下该合约中几个重要变量,方便后续理解:

1.payoutsTo变量,该变量是用于存储某个用户消费了多少分红;

2.profitPerShare,该变量用于存储当前God代币所能产生的分红比例,非固定,是浮动的;

3.tokenBalanceLedger,该变量用户存储某个用户的代币余额;

4.mydi vidends,获取当前用户的分红余额;

PS:看到上面几个变量,有些人应该会很熟悉,没错,说得就是PoWH3D,这个合约代码和风靡一时的PoWH3D极其相似,熟悉PoWH3D的应该很容易理解。

那么:这些变量之间的有何关联?

profitPerShare和tokenBalanceLedger的乘积便是某个用户所能得到的分红,但不是mydi vidends(最终的分红余额),因为有payoutsTo(分红支出),所以最终用户的分红余额的简化版计算方式为:

从上面的公示能够得到一个结论,那就是profitPerShare * tokenBalanceLedger是必须大于payoutsTo的,否则,在计算最终分红余额的过程中就会发生溢出,将导致显示的分红余额数值非常大。

然后再进一步推导,在没做容错的情况下(该合约确实没对计算最终分红进行容错处理),当profitPerShare * tokenBalanceLedger减少时,payoutsTo的值也需要进行一定量的减少,否则便会出现上述溢出的情况。

再进一步分析,在检查profitPerShare变量所有可能的更改情况,发现了该变量不会减少,只会增加,所以就可以再进一步得出:

当tokenBalanceLedger减少时,payoutsTo也需要进行一定量的减少,否则会产生溢出。

根据合约代码,就会发现只有transfer系列的函数会导致tokenBalanceLedger减少

根据如上代码,transfer函数最终都回调用transferFormInternal函数来进行实际转账,我们继续来看。

太冗长了,我们挑其中的重点看一下:

重点一

通过这一段可以看到,在tokenBalanceLedger_[_from]减少时,payoutsTo_[_from]也会进行相应的减少,这是没问题的,但是我们注意到了“human to human”这个注释,难道contract to human还会有不同的情况?紧接着往上看contract to human的部分。

重点二

注意!在这段代码里面很明显没有对payoutsTo_[_from]有任何减少操作,通过我们上面推导出来的理论,这里没对payoutsTo做处理很可能导致计算最终分红余额的时候产生溢出。

好了,我们再回头看黑客的攻击手法:

前面的不重要,我们直接从黑客的第4个步骤,调用withdraw来解释,先看代码:

上面的代码中我们自行加了一段注释,调用这个函数的目的很明显,增加payoutsTo的值,使计算最终分红余额的时候有溢出的条件。

然后是第5个步骤,调用transfer函数,通过上面的讲解,这里意义也很明确,减少tokenBalanceLedger的值,因为transfer对contract to human的处理不当,导致tokenBalanceLedger的值减少了,而payoutsTo的值没减少,满足溢出条件。

第6个步骤,调用reinvest函数,因为在第5个步骤中已经使分红余额溢出了,调用reinvest将分红转换成token。

第7个步骤,调用sell函数,因为调用reinvest产生了大量的token,godgame一个游戏机制是,流通的token那么token的价格就越高,产生这批token已经导致token的购买价格为天价,于是攻击者调用sell函数来销毁一部分token让token的价格降到正常,以便自己能顺利提款。

第8个步骤,调用transfer函数,将token转移到另外的账户,然后另外的账户直接将token兑换成分红后提现。

总结:

WF曲速未来建议:对于合约的转账数量,一定要需要进行严密逻辑验证。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180824A1LF3400?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券