场景描述
FOBO3D 游戏介绍: http://xqdoc.imedao.com/164fa5baa1b1174f3fd9ce75.pdf
Fomo3D 游戏最最核心的规则就是最后一个购买的玩家获得最大的利益
其中主要规则: 最后一个购买的玩家获得奖池中 48%的 eth
Fomo3D 游戏第一轮游戏结束的时候,钱包 0xa169df5ed3363cfc4c92ac96c6c5f2a42fccbf85 的用户最终拿走了 10,469 eth 的奖金。攻击者凭借着对区块链原理的了解进行刷钱阻塞的攻击方式,让自己成为最后一名。这次攻击的结果,也直接影响了类 Fomo3D 的所有游戏,最后一名获得收益的形式,都会此种方式攻击。
地址描述
- 项目方官网: https://exitscam.me/play
- 收益地址:
0xa169df5ed3363cfc4c92ac96c6c5f2a42fccbf85 - 被攻击合约: 0xa62142888aba8370742be823c1782d17a0389da1
- 攻击发生的交易 Hash: 0xe08a519c03cb0aed0e04b33104112d65fa1d3a48cd3aeab65f047b2abce9d508
- 配合攻击的合约: 0x18e1b664c6a2e88b93c1b71f61cbf76a726b7801
攻击方式
在快结束的时候买 KEY,因为最后一名购买的玩家将会获得奖池中 48% 的 ETH,所以使用各种手段确保后面没有人能够再买进来。只要自己顺利成为最后一名,就可以拿走大奖了。
可以有的方式:
- 和各大矿主协商好,请矿工挖矿成功后,不要打包别人买 KEY 的交易
- 可以通过某种技术手段,配合高额的交易手续费,让矿机自动选择只打包我的交易,而不打包别人的交易。
这里攻击的方式是第二种,通过高额的 gas 费,让矿池抢着打包自己的交易,通过高额 gas 把资源占满,让低 gas 的交易无法进行。使用高额的以太费用和技术手段让以太坊堵塞了 3 分钟。其他玩家无法打包购买 KEY 的交易,之后自己顺利成为最后一名获奖者。
攻击分析
攻击的合约是 0x18e1b664c6a2e88b93c1b71f61cbf76a726b7801,这个合约的创建 HASH 是 https://etherscan.io/tx/0x21ebb34d74aa487f036d5b8b5cf9cbfc7083b9fec3614a312341a3ab01592293 ,创建人是黑客地址 0xa169df5ed3363cfc4c92ac96c6c5f2a42fccbf85。
在最后的 6 个区块中,差不多 1 分半钟的时间里,攻击者给出了 190/190/501/501/501/501 的高额 GAS 费用,一举垄断了所有以太坊所有的算力。gas 费用消耗达到了 19 个 ETH。因为超高的 gas 费用,所以其他用户几乎无法在以太坊上执行任何操作。(太坊平均每 14 秒左右出一个块,该区块中会打包一些交易。而每个区块能够进行的运算量是有限的,一个区块的 gas 上限一般为 8000000。)
为了让交易不回滚,攻击者还使用了一个特殊的指令 assert(),这是一个类似于 require 的函数,他和 require 唯一的区别就是,当条件不满足时,assret 会耗光所有的 gas。原理是因为在 EVM 底层的执行过程中,assret 对应一个未定义过的操作符 0xfe,EVM 返回 invalid opcode error,并报错结束。
而攻击者这里所做的事情呢,就是在确定自己是最后一个 key 的持有者时,发起超大 gasprice 的交易,如图所示:
整个流程:
- Fomo3D 倒计时剩下 3 分钟左右
- 攻击者购买了最后一个 key
- 攻击者通过提前准备的合约发起大量消耗巨量 gas 的垃圾交易
- 3 分钟内不断判断自己是不是最后一个 key 持有者
- 无人购买,成功获得大奖
反思
再写合约的时候,尽量避免最后一名"赢家通吃"的情况,因为高额利润的诱惑,成本非常低。而且这种攻击方式已经会被普遍应用了,这种代码逻辑方式已经属于设计漏洞了。
类似攻击
除了 Fomo3D 被盗事件以外, Last Winner 等类 Fomo3D 也被黑产盯上…短短时间内,攻击者从中获利无数。