真相只有一个 !God.Game 代币被盗事件原理分析
案情回放
8月22日中午,区块链游戏God.Game宣布游戏内所有代币被攻击者卷走,项目方筹备两个月,游戏却在运营不久后迅速夭折。
我们得知此消息之后,没有等待黑客攻击地址被公布,立即展开了对合约源代码的审计,从代码逻辑和功能准确性等根源问题入手,定位攻击者利用的漏洞,并复原了“案发现场”。
漏洞定位
对源代码进行漏洞排查后发现漏洞原因为dividends变量异常:
首先看一下dividends的计算逻辑:
return (uint256) ((int256)(profitPerShare_*tokenBalanceLedger_[_customerAddress]) - payoutsTo_[_customerAddress]) / magnitude;
每当一个地址token增加或减少操作时,都会对该地址的payoutsTo这个变量进行操作,
购买token增加payoutsTo变量
卖出或转账token减少payoutsTo变量
这些都很容易理解。
但是在转账逻辑我们却发现,对于合约地址,是没有payoutsTo的,这个疑点先记在小本本上。
这是源码的转账部分:
转账
我们再仔细查看一下withdraw函数里面:
我们惊讶的发现在withdraw函数中,会对payoutsTo进行一个赋值操作,赋值为dividends*magnitude;这里magnitude=2**64;
从上面dividends逻辑的(profitPerShare_*tokenBalanceLedger_[_customerAddress])部分可以看出,只要有账户有token那dividends就一定有值的,dividends有值我们就可以进行withdraw操作。
攻击流程推理
首先创建一个攻击合约并转入一定token,调用一次withdraw之后,该攻击合约地址对应的payoutsTo值变为dividends*magnitude;
然后再将攻击合约中token转走,使其token为0,由于原合约转账逻辑中并没有对合约类型地址的payoutsTo做处理,所以此时攻击合约地址对应的payoutsTo值在原合约看来并没有减少;现在将payoutsTo带入dividends的计算中:
(uint256) ((int256)(profitPerShare_ * tokenBalanceLedger_[_customerAddress]) - payoutsTo_[_customerAddress]) / magnitude
由于合约token已经全部转走,tokenBalanceLedger=0,所以此时
(profitPerShare_ * tokenBalanceLedger_[_customerAddress])=0;
payoutTo也为int256
那么简化公式之后上面复杂的公式变为
uint256 (int256(0-payoutsTo))/magnitude;
(uint256) ((int256)表示的是:
uint256对一个int负数强制转化为一个uint无符号数,导致值变成了一个很大的正数。最终导致dividends异常增加。
最终通过调用reinvest功能使用dividens购买大量token,买入token增加后导致token价格增加。最后通过卖出token的方式转走游戏合约中的以太坊。
攻击流程总结
创建一个攻击合约,可以调用God合约并且向该合约转入几个God token
攻击合约调用God合约withdraw的函数,触发payouts[address]值增加
调用攻击合约将攻击合约中的God token全部转出,使合约token=0,攻击合约地址的dividends出现异常;
调用reinvest()可以使用异常devidends购买大量token,因为合约token总量增加,分红增加,token价格上涨,此时任何人都可以卖出少量token来获取到大量的ETH。
蛛丝马迹
我们查看游戏合约异常的dividends证据:
红框内“00000000ffffffffff”的类似结构代表其为负数
由此证明dividends确实出现了类类了型转换异常的情况。
攻击者通过攻击合约调用God合约的reinvest()函数,使用异常的dividends购买了大量God代币,总量约为300亿,此时代币价格迅速攀升,最后,攻击者只卖出了0.9个token就已经将合约中的200多以太坊转走。
攻击流程复现
复现环境:
Ropsten测试链
复现步骤:
部署God合约在测试链上,God地址:
0x92cbCBc31f6bb209f2C4F6cbd0596ba22D71979d
普通用户支付1 ETH购买代币
攻击者支付0.1 ETH购买代币
攻击者部署攻击合约PWN,PWN合约地址: 0x88DF1483Db9d3720378d2CB6859c8487e4412ac7
攻击合约代码地址:
https://ropsten.etherscan.io/address/0x88DF1483Db9d3720378d2CB6859c8487e4412ac7#code
攻击者向PWN合约转4 GOD代币
攻击通过PWN合约调用God合约的withdraw函数,使PWN合约的payoutsTo_变为
攻击者转出PWN合约下的God代币,使得tokenBalanceLedger_为零,此时计算PWN合约的dividendsOf 值所需参数的值为:
profitPerShare_ = 8997439772575371
tokenBalanceLedger_[PWN] = 0
payoutsTo_[PWN] = 0x254197237940000000000000000
执行dividendsOf函数,得到PWN合约地址的分红为dividendsOf = uint(-0x25419723794),此处在由int转化为uint中出现错误:
攻击者通过PWN合约调用GOD合约reinvest函数,利用超大的dividendsOf 值购买代币,获得了大量代币,使得profitPerShare提升到极大值,进而破坏了God 与ETH之间的汇率
异常的profitPerShare值
PWN购买的God代币数
9. God合约的代币数量与主链上数量相近,复现成功
测试God合约代币总量300亿
真实God合约代币总量330亿
总结
经由以上推理与证据的理论验证,以及复现与真实的数据验证,我们确定此次攻击手段定义为类型转换漏洞攻击。
攻击者巧妙利用God合约的设计漏洞,在计算dividends时,未考虑int类型的负值转化为uint时的情况,导致合约被攻击。
从Etherscan上查到的信息来看,部署攻击合约为8月20日04:42:27 PM,卷走ETH为04:57:26 PM。黑客仅仅用了15分钟完成上述所有操作。
除此漏洞之外,我们还在合约中发现如下两个“后门”,God合约的owner(在下列代码中体现为Administrator)可以使用这两个函数转出合约地址下的所有ETH。
此处Administrator可以指定任意账户的代币数,然后可以将这部分代币数兑换为ETH。
此处Administrator取走项目奖励时没有减去已经取走的value值,导致Administrator可以重复取出ETH。
总而言之,目前的游戏合约,尤其是交易属性较重的游戏合约,安全漏洞出现的情况非常普遍,对此,我们提醒广大玩家和投资者,在进入一些“一夜爆红”的游戏之前,要擦亮眼睛,理智投资,最好是参与已经提供审计报告的区块链游戏,对于未经过合约安全验证的游戏不可盲从。同时,各游戏项目方也应该在游戏上线前做好对智能合约的安全审计,以保护自己的项目运营和玩家的资产安全。
投稿作者介绍:
杨霞
成都链安科技CEO,创始人。电子科技大学副教授,最早研究区块链形式化验证的专家。一直为航空航天、军事领域提供形式化验证服务。主持国家核高基、装发重大软件课题等近10项国家课题。CC国际安全标准成员、CCF区块链专委会委员。发表学术论文30多篇,申请20多项专利。
最新热文:
你没看过的V神早期神文,现在读起来仍受益匪浅
为将傅恒与魏璎珞的爱情上链,作为技术小白的我读了EVM上百行代码,终于搞定了
币价涨涨跌跌,程序员竟如此佛系... | 他说
为什么区块链开发者工资这么高?看看他们需要掌握多少东西就知道了
大力戳↑↑↑ 加入区块链大本营读者⑦号群
(群满加微信 qk15732632926 入群)
内容转载请联系微信:qk15732632926
商务合作请联系微信:fengyan-1101
真相只有一个 !God.Game 代币被盗事件原理分析相关推荐
- eos代币映射 代码实战分析
1.首先部署合约,这是eos映射合约地址(0xd0a6E6C54DbC68Db5db3A091B171A77407Ff7ccf),当真正公有链上替换成这个(0xd0a6E6C54DbC68Db5db3 ...
- 在以太坊开发自己的ERC-20代币及如何ICO
今天我将向你展示如何在以太坊区块链上开发你自己的加密货币并将其出售!我将向你展示如何使用以太坊智能合约逐步创建自己的ERC-20代币和众筹销售,如何测试智能合约,如何将智能合约部署到以太坊区块链,以及 ...
- Force DAO 任意铸币攻击事件复盘分析 | 零时科技
事件背景 Force DAO 是 DeFi 投资策略的去中心化自治组织,致力于在 DeFi 世界识别 alpha,Force 以 DAO 的方式,致力于通过遵循社区提出的策略,并通过强有力的激励措施, ...
- Microsoft.Net框架程序设计学习笔记(15):事件之原理分析
完整定义一个事件的方法 以Mail发送为例: 定义一个类型用于保存所有需要发送给事件通知接受者的附加信息. 按.Net框架约定,所有保存事件信息的类型都应该继承自System.EventArgs,且类 ...
- 以太坊代币事件监控_以太坊:什么是ERC20标准?
不以规矩,不能成方圆 许多人应该都听过 代码即法律(Code Is Law),因为程序写完了,无论执行多少次都会得到同样的结果,除非有外界因素的干扰.在多人协作的过程中一定是要按照一个标准来进行分工, ...
- 以太坊代币事件监控_以太坊程序员的常见误解
最近,我偶然读到了一篇题为<程序员关于时区的误解>的文章,让我爆笑不已.这篇文章让我想到了程序员在其它方面的误解,如人名和时间,于是我开始寻找有没有关于以太坊的.奈何寻觅无果,我只得尽自己 ...
- HarmonyDAG团队500万USDT等值代币帮助FCOIN事件用户公告
鉴于Fcoin交易所因资金储备不足导致的无法兑付用户提现事件.HarmonyDAG团队深感遗憾. 为遭受此次不幸事件影响的区块链爱好者,HarmonyDAG基金将会拿出等值500万USDT的代币对每一 ...
- Easyfi遭受黑客攻击,被盗600万美元稳定币以及298万个EASY代币
Easyfi.network创始人兼CEO Ankitt Gaur在推特上表示:4月19日,团队成员报告称,有大量EASY代币从EasyFi官方钱包大量转移到以太坊网络和Polygon网络上未知钱包. ...
- DeFi最大的一次安全事故!黑客盗取超20个项目代币!
今日凌晨,跨链桥项目Chainswap再次遭到黑客攻击,在该桥梁部署智能合约的超20个项目代币都遭遇黑客盗取,几乎酿成DeF发展史上影响范围最大的一次安全事故. 根据多名推特用户公布的信息,该名黑客地 ...
最新文章
- 谷歌曝iPhone重大漏洞!无需接触手机,2分钟即可「隔空」破解所有数据
- redux-form(V7.4.2)笔记(一)
- XML Web Service 安全性
- 跟公务员稍稍的接触了下
- 关于 ng-template 通过 @input 传入另一个 Component 不能工作的问题调试
- c语言调试出错误怎么改,C语言调试常见错误及修改方法(附习题)
- Python 的PIL,可以解决ImportError The _imagingft C module is not installed
- not null primary key什么意思_为什么我使用了索引,查询还是慢?
- token详解及常见防范措施
- meteor---在合并打包多个文件ZIP下载的功能
- 【水管规格】4分管、6分管水管的直径,丝口螺纹,铝塑管接头
- 类似print shopmail可变数据生成,排版、拼版实现
- iOS宏定义的黑魔法 - 宏菜鸟起飞手册
- CAS 服务端的搭建
- URL 编码 - 从 %00 到 %ff
- angularJs-基础用法
- 计算机检索策略制定过程,计算机文献检索的基本方法与策略
- 人类的行为与程序计算
- STM32硬件I2C与软件模拟I2C超详解
- 数据分析项目实战1——淘宝用户购买行为分析(天池)
热门文章
- AutoJs学习-实现带进度条的在线文件更新
- 中山黄埔有没有学计算机学校,在广东中山黄埔的技校,女生是蓝色的校服的,哪个学校叫什么名字,还有就是哪个学校有什么可以学...
- 智能灵活的jQuery 相册插件
- 苹果加快自研处理器!M1X、M2齐曝光
- iOS 音频-audioUnit 总结
- 仿盘和诈骗项目横行,NFT治理将走向何方?
- 我用Python做了一个咖啡馆数据分析
- Eclipse运行项目提示“类路径引用的项目不存在”
- 老闪创业那些事儿(71)——财神是如何修炼的
- 求高精度幂 java_JAVA高精度_求高精度幂