导读
就一个简单的batchTransfer批量转账函数溢出漏洞,导致BEC的市值接近归零。
至于其他建立在ETH智能合约基础上开发的2000多个项目的代币,里面有没有类似的bug,小葱相信也会有的。
美图董事长蔡文胜曾在三点钟群,高调的说出了这句话:
“现在进入你还是先行者,最后观望者进场才是韭菜。”
随即被大众疯传。在他发表完言论没多久,2018年2月,美链(BEC)上交易所会暴涨4000%,后又暴跌。尽管他多次否认,但是聪明的网友早已扒出,他与BEC有着千丝万缕的关系。
今天有人在电报群里说,BEC(美蜜)的代码里面有bug,已经有人利用该bug获得了 57,896,044,618,658,100,000,000,000,000,000,000,000,000,000,000,000,000,000,000.792003956564819968 个 BEC
小葱咋看到这个消息,吓了一跳,BEC(美蜜)整个盘的代币总额才70亿,现在黑客一下之转走了5后面58个零的币,这下BEC直接清盘了吧?
难道这是币圈流行的漫天假消息?
不过小葱发现,徐明星的OKex随即紧急发布了一个公告。
如果说这个公告和这笔接近60亿获利的黑客攻击没有关联,我是不相信的。
不过黑客到底是如何实现的呢?好奇的小葱就来带大家一起观摩学习下,黑客是如何实现的!
我们发现,原来那个黑客的那笔操作记录是 0xad89ff16fd1ebe3a0a7cf4ed282302c06626c1af33221ebe0d3a470aba4a660f
黑客所采取的攻击方法是BEC智能合约
(https://etherscan.io/address/0xc5d105e63711398af9bbff092d4b6769c82f793d)中
batchTransfer批量转账函数存在的漏洞
小葱再来科普一下:batchTransfer批量转账函数有什么漏洞
批量转账,言下之意也就是说给可以按事先指定的几个钱包地址,发送相同数量
我们假设一个批量转账的交易场景
首先,小葱和你达成了一次批量转账交易,你要向小葱我批量发放BEC的代币。
那么小葱肯定得先告诉你,我作为代币接收者(receivers),会向你提供代币接收地址。
然后,小葱得再告诉你,你得向我提供的每个接收地址,发多少指定的代币金额?(value:金额)
一般情况下,你要发送的代币总金额(amount) = 发放的人数* 发送的金额
当然,这里肯定有个先觉条件,你的钱包余额肯定要多过你要发送的代币总金额,否则你就不够钱向小葱我进行撒币了!
从逻辑上看,上述的批量转账流程肯定没有任何问题的,除非你的数学是体育老师教的!我想给别人发送代币,那么我本身的余额一定要大于发送的总金额的!
但是,但是!
这段代码却犯了一个很傻的错!
代码解释
这个方法会传入两个参数
_receivers(代币接收者)
_value(转账金额)
_receivers 的值是个列表,我们发现这个列表里面有两个钱包地址
0x0e823ffe018727585eaf5bc769fa80472f76c3d7
0xb4d30cac5124b46c2df0cf3e3e1be05f42119033
而_value (转账金额)的值是 8000000000000000000000000000000000000000000000000000000000000000吓尿小葱了,黑客要搞这么大笔的转账金额是为了什么?
我们回头再查看代码(如下图)
我们一行一行的来解释
uint cnt = _receivers.length;
是获取 _receivers 里面有几个地址,我们从上面可以看到 参数里面只有两个地址,所以 cnt=2,也就是 给两个地址发送代币
uint256 amount = uint256(cnt) * _value;
黑客攻击者,就是充分利用了这个uint256,他传入很大的_value (转账金额):8000000000000000000000000000000000000000000000000000000000000000
这样他就使 cnt * value 后超过 unit256 的最大值,最后使其溢出导致 amount 变为 0。
下一行代码 require(cnt > 0 && cnt <= 20); require 语句是表示该语句一定要是正确的,也就是 cnt 必须大于0 且 小于等于20
我们的cnt等于2,通过!
require(_value > 0 && balances[msg.sender] >= amount);
这句要求 value 大于0,我们的value是大于0 的 且,当前用户拥有的代币余额大于等于 amount,因为amount等于0,所以 就算你一个代币没有,也是满足的!
balances[msg.sender] = balances[msg.sender].sub(amount);
这句是当前用户的余额 - amount
当前amount 是0,所以当前用户代币的余额没有变动
所以 _receivers 中,黑客地址的余额 则加了57,896,044,618,658,100,000,000,000,000,000,000,000,000,000,000,000,000,000,000.792003956564819968 个 BEC,市值接近60亿!
就一个简单的batchTransfer批量转账函数溢出漏洞,导致BEC的市值接近归零
至于其他建立在ETH智能合约基础上开发的2000多个项目的代币,里面有没有类似的bug,小葱相信也会有的。
不过话说回来,这次的Bug,不知道和最近风头正猛的EOS有没有关系?毕竟柚子可是朝着姨太开火的。
閱讀更多 區塊連線 的文章