XSURGE攻击事件全面梳理

创宇区块链安全实验室
创宇区块链安全实验室 机构得得号

Oct 10, 2021 专注构建区块链安全生态,致力于让人类进入安全的区块链世界。

摘要: BSC 链上的 XSURGE 协议遭到闪电贷攻击,损失超过 500 万美元。

前言

8 月 17 日,BSC 链上的 XSURGE 协议遭到闪电贷攻击,损失超过 500 万美元。

对此,知道创宇区块链安全实验室 对攻击流程和代码细节进行了全盘梳理。 

全盘梳理


基础信息

-攻击tx:
0x7e2a6ec08464e8e0118368cb933dc64ed9ce36445ecf9c49cacb970ea78531d2

-攻击合约:

0x1514AAA4dCF56c4Aa90da6a4ed19118E6800dc46


-SurgeToken:

0xE1E1Aa58983F6b8eE8E4eCD206ceA6578F036c21

攻击流程


这里有个小细节,代币转移流程中的顺序是按照事件先后顺序来显示的,而重入之后的买操作引起的事件会在卖操作引起的事件之前,所以在流程中看到的每一个单独的重入攻击中是 SURGE 的买入发生在卖出之前。


漏洞原理

漏洞点在于 SurgeToken 合约中的 sell() 函数,其中对调用者 msg.sender 的 BNB 转账采用的 call() 函数,并且在转账之后才更新代币总量 _totalSupply,是典型的重入漏洞场景。

虽然 sell() 函数使用了 nonReentrant 修饰防止了重入,但 purchase() 函数并没有。重入转回 BNB 给合约,触发 fallback 函数调用 purchase(),由于_totalSupply 尚未减去卖出量,而导致可买入相较正常更多的 SURGE 代币。


复现


价格分析

sell() 函数卖出过程中,输入tokenAmount与输出 amountBNB 的关系:



purchase() 函数买入过程中,输入 bnbAmount 与输出 tokensToSend 的关系:


在重入过程中,sell() 函数卖出后获得的 BNB 通过重入打回 SurgeToken 合约传入 purchase() 函数

故令 sell() 函数的输出 amountBNB 与 purchase() 函数的输入 bnbAmount 相等,可得到整个利用流程中输入与输出的关系:


若要实现套利,需要输出大于输入,则有:


最后得到:


也就是说
重入套利过程中调用 sell() 卖出的代币量必须在代币总量的12.383% 以上


模拟演示

为方便调试,将 SurgeToken 合约中的 mint() 函数可见性改为 public,并为构造函数增加 payable 修饰,在部署时传入 10^15 wei 。


SurgeToken 合约初始化的代币总量为 10^9,根据前面推导出的结论,为攻击合约铸币 200000000(攻击成本),则攻击合约拥有大约 SURGE 代币总量 16% 的代币。

攻击合约调用Attack()函数攻击,查看攻击合约的代币余额已变为 209549307,获利 9549307 。

总结

XSURGE 协议被攻击的本质原因在于 sell() 函数中存在重入漏洞,导致可通过 purchase 函数买入较多的 SURGE 代币而获利。


简而言之,典型的重入漏洞场景,教科书级的案例。

作者:创宇区块链安全实验室;来自链得得内容开放平台“得得号”,本文仅代表作者观点,不代表链得得官方立场凡“得得号”文章,原创性和内容的真实性由投稿人保证,如果稿件因抄袭、作假等行为导致的法律后果,由投稿人本人负责得得号平台发布文章,如有侵权、违规及其他不当言论内容,请广大读者监督,一经证实,平台会立即下线。如遇文章内容问题,请联系微信:chaindd123

链得得仅提供相关信息展示,不构成任何投资建议
本文系作者 创宇区块链安全实验室 授权链得得发表,并经链得得编辑,转载请注明出处、作者和本文链接

更多精彩内容,关注链得得微信号(ID:ChainDD),或者下载链得得App

分享到:

相关推荐

    评论(0

    Oh! no

    您是否确认要删除该条评论吗?

    分享到微信