场景描述
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 也被黑产盯上…短短时间内,攻击者从中获利无数。