点击关注「零时科技」,实时获取区块链安全最新动态!
本文所有过程均在本地测试节点完成
文章用到的所有代码均在 https://github.com/NoneAge/EOS_dApp_Security_Incident_Analysis/tree/master/NoneAge-20180914-EOSBET-transfer-notification-forgery
0x00背景
在2018年9月14日遭到黑客攻击,根据EOSBet
官方通告,此次攻击共被盗44,427.4302 EOS
(折合人民币160万,9月14日价格)。
0x01技术分析
EOSIO_ABI
,问题主要出在以下代码
该合约对action
进行转发的时候仅仅验证了code == self
(调用者必须是该合约本身,即eosbetdice11
)和code == N(eosio.token)
(调用者必须是eosio.token
)。从这里看似乎是验证了只有合约本身和eosio.token
可以调用合约函数。
但是,开发者忽略了这一点。如果A
合约直接向B
合约发起一个transaction
调用B
合约的函数,那么本质上是B
合约自身完成函数调用,也就是说任何合约都可以调用eosbetdice11
合约中abi
暴露的函数。
黑客可以直接调用eosbetdice11
合约中的transfer
函数,即不用消耗任何EOS
来玩EOSBet
,输了不赔赢了稳赚。
0x02攻击复盘
创建eosio.token
账户
部署eosio.token
合约并初始化
创建游戏账户、开奖账户和攻击者账户
设置账户随机权限和开奖权限
向相关账户冲入代币
部署游戏合约并初始化
模拟黑客攻击(伪造转账通知)
查询游戏订单
可见,游戏订单已经生成,查询attacker
和eosbetdice11
账户
按照游戏规则,只有在支付了EOS
后才能生成游戏,但是被黑客攻击后生成订单并没有消耗任何的EOS
。
最后对该订单进行开奖。
总结,黑客伪造转账通知来玩游戏不消耗任何EOS
,游戏成功即可获利,即使最后游戏失败也不会有任何损失。
0x03后记
EOSBet随后将修复方案公开
EOSBet
官方给出的修复方案是仅有eosio.token
合约可以调用transfer
函数。官方修复后将代码开源到Gitlab,地址为https://gitlab.com/EOSBetCasino/eosbetdice_public
,但是在整整一个月后又遭到了转账通知伪造攻击。欲知详情,请听下回分解:D
0x04修复方案
零时科技安全专家建议,要防止转账通知伪造必须在处理转账交易时要验证以下内容:
-
通知是否来自
eosio.token
,即只处理eosio.token
发送的通知 -
转账发起人或者接受人是否是自己,即转账必须跟合约本身有关,不处理其他合约的转账通知
0x05Refer
https://medium.com/@eosbetcasino/eosbet-transfer-hack-statement-31a3be4f5dcf
https://gitlab.com/EOSBetCasino/eosbetdice_public
https://github.com/ganjingcun/bet-death-causes
0x06测试视频
零时科技
NoneAge
深圳零时科技有限公司,专注于区块链安全领域。公司团队由从事安全技术研究和安全服务多年且经验丰富的高级网络安全专家组成,为客户提供专业的安全服务和安全解决方案。
原文始发于微信公众号(零时科技):EOS dApp漏洞盘点分析1-EOSBet遭受转账通知伪造攻击
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论