EOS dApp 漏洞盘点-EOSDice弱随机数漏洞一

Written by WeaponX@零时科技

本文所有过程均在本地测试节点完成

文章用到的所有代码均在 https://github.com/NoneAge/EOS_dApp_Security_Incident_Analysis

0x00 背景

零时科技监测到,EOSDice在2018年11月3日受到黑客攻击,根据EOSDice官方通告,此次攻击共被盗2,545.1135 EOS,约合 1.35 万美元(2018年11月4日价格 1 EOS ≈ 5.13 USD)。在这里插入图片描述

0x01 技术分析

由于EOSDice被攻击是因为该游戏的的随机数算法被破解,而且使用的defer action进行开奖。那我们具体分析一下EOSDice的随机数算法是否存在漏洞。

因为EOSDice的合约已经开源,我们从Github上找到了EOSDice的随机数算法:在这里插入图片描述

https://github.com/loveblockchain/eosdice/blob/f1ba04ea071936a8b5ba910b76597544a9e839fa/eosbocai2222.hpp#L172

可以看到,EOSDice官方的随机数算法为6个随机数种子进行数学运算,再哈希,最后再进行一次数学运算。EOSDice官方选择的随机数种子为

tapos_block_prefix # ref block的信息

tapos_block_num # ref block的信息

account_name # 本合约的名字

game_id # 本次游戏的游戏id,从1自增

current_time # 当前开奖的时间戳

pool_eos # 本合约的EOS余额

其中随机数种子account_name、game_id、pool_eos很容易获取到,那么如果需要预测随机数,必须要预测所有的随机数种子,也就是 说current_time、tapos_block_prefix、tapos_block_num也要可以预测。

那么,首先分析current_time是否可以预测

根据EOS官方的描述在这里插入图片描述

其实返回的就是一个时间戳,由于EOSDice开奖使用的是defer action,因此,我们只需要知道下注的action的时间戳再加上delay_sec就可以算出开奖reval的时间戳了。EOSDice的delay_sec为1秒,所以开奖时时间戳 = 下注时时间戳 + 1000000。

接着,我们分析tapos_block_prefix和tapos_block_num是否可以预测

其实,tapos_block_prefix和tapos_block_num均为开奖block的ref block的信息。EOS为了防止分叉,所以每一个block都会有一个ref block也就是引用块。因为reveal开奖的块在下注前并不知道,它的ref block看似也不知道,所以貌似这两个种子是未来的值。不过,根据EOS的机制,因为开奖采用的是defer action,所以reveal开奖块的ref block为下注块的前一个块,也就是说tapos_block_prefix和tapos_block_num是在下注前可以获取到的!在这里插入图片描述

至此,EOSDice的随机数种子在下注前均可以获取,那就意味着我们可以在下注前预测到下注后的随机数,完全可以达到必中的效果。

下面是我们测试攻击的合约,完成的功能是根据EOSDice的随机数算法来预测此次下注的随机数的值,然后选择roll的值比预测值大一即可中奖。在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述下面,我们的测试攻击脚本,完成的功能是获取最新的块和块的id,计算出EOSDice开奖action的tapos_block_prefix和tapos_block_num,发送给测试攻击的合约。在这里插入图片描述

测试流程:

1.创建相关账户并设置权限在这里插入图片描述2.给相关账户发送代币在这里插入图片描述3.编译相关合约并部署在这里插入图片描述4.初始化EOSDice合约在这里插入图片描述最后,我们来测试一下,我们可以很容易的获取到下次投注的game_id,此次为109。在这里插入图片描述我们看一下合约的执行结果,可以看出,攻击合约预测的随机数和EOSDice的开奖action算出来的完全一致!这样就可以达到每次必中!在这里插入图片描述

0x02 官方修复

官方修复其实很简单:

开奖的action由一次defer action变成了两次defer action在这里插入图片描述https://github.com/loveblockchain/eosdice/commit/50a05dfb6c0d68b6035ed49d01133b5c2edaefdf

账户的余额用很多账户的总和加起来当成随机数种子在这里插入图片描述https://github.com/loveblockchain/eosdice/commit/3c6f9bac570cac236302e94b62432b73f6e74c3b

首先,开奖的action由一次defer action变成了两次defer action,根据前面我们提到的内容,defer action的ref block为发起defer action的前一个块。但是,在我们下注的时候这个块是无法预知的;其次,EOSDice的账户余额用了很多账户的余额的总和来当种子,这个貌似也是无法预测变化的。不过这样真的安全了吗?很明显,不是的,仅在6天后EOSDice再次受到随机数攻击,下篇文章我们会详细分析第二次攻击。

0x03 推荐修复

如何得到安全的随机数是一个普遍的难题,但是在EOS上尤其困难,因为EOS并不提供随机数接口。所以随机数的种子必须得自己选择,选择种子的准则就是无法被提前预知。零时科技安全专家推荐参考EOS官方的随机数生成方法来生成较为安全的随机数

https://developers.eos.io/eosio-cpp/docs/random-number-generation

0x04 Refer

https://blog.csdn.net/TurkeyCock/article/details/84730045

https://igaojin.me/2018/11/04/EODIDEC-%E9%9A%8F%E6%9C%BA%E6%95%B0%E8%A2%AB%E6%94%BB%E7%A0%B4/

https://developers.eos.io/eosio-nodeos/reference#get_block

https://github.com/loveblockchain/eosdice/tree/f1ba04ea071936a8b5ba910b76597544a9e839fa

https://developers.eos.io/eosio-cpp/docs/random-number-generation

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值