前言
8月17日,BSC链上的XSURGE协议遭到闪电贷攻击,损失超过500万美元。对此,知道创宇区块链安全实验室对攻击流程和代码细节进行了全盘梳理。
全盘梳理
基础信息
-攻击tx:0x7e2a6ec08464e8e0118368cb933dc64ed9ce36445ecf9c49cacb970ea78531d2-攻击合约:
0x1514AAA4dCF56c4Aa90da6a4ed19118E6800dc46
Axie Infinity部分早期投资者已将解锁的AXS代币转入交易所,或有抛售倾向:10月26日消息,P2E游戏Axie Infinity代币AXS于本周开始引来大约2150万枚AXS(价值2亿美元)的大额解锁,Axie Infinity向早期投资者和内部人士解锁了首批1000万枚AXS代币,这可能会给AXS代币带来抛售压力。区块链数据显示,一个标记为“Axie Infinity: Token Vesting”的钱包向6个收件人转移了785334个AXS代币(价值660万美元)。据TokenUnlock网站称,这些收件人在Axie 2020年年中的一轮私人销售中被列为顾问和早期投资者。
数字资产管理公司Arca是在私募期间购买AXS的机构投资者之一,通过与该公司相关联的钱包收到了43.75万枚AXS(约合400万美元)。但根据Etherscan和Nansen的区块链数据,该钱包将这些代币全部转入FTX。另外,数据显示另一位早期投资者收到17.85万枚AXS(约合170万美元)的解锁代币后立刻将这些代币转移到了币安 。报道称,将代币转移到交易所表明这些投资者可能会抛售他们的资产,从而从他们的原始投资中获得巨额利润。据悉,参与私募的投资者当时以8美分的价格购买了AXS,目前AXS在交易所的价格约为9美元,他们可能会从其初始投资份额中获得11,150%的利润。
另TokenUnlock数据显示,加密投资公司DeFiance Capital和Delphi Digital可以分别收到16万枚AXS(约合150万美元)和75万枚AXS(约合680万美元)解锁代币,区块链数据表明他们尚未收到他们的代币份额。(CoinDesk)[2022/10/26 16:38:55]
-SurgeToken:
UBOXSEA公测即将开启:据UBOXSEA官方介绍,8月5日14:00(GMT+8)将正式开启公测,参与公测活动的用户只需在规定时间内完成对应任务,就有机会获已通过北版科技完成版权登记的图片NFT,且经版权登记的图片NFT受到保护,NFT收藏家可对违规使用该NFT的情况依法追究责任。UBOXSEA将在公测结束正式上线主网后的7个工作日内随机抽取150名用户发放奖励。[2021/8/4 1:34:37]
0xE1E1Aa58983F6b8eE8E4eCD206ceA6578F036c21
MXC抹茶上线FXS 开盘上涨166.66%:12月21日17:20,MXC抹茶考核区上线FXS(Frax Share),开放USDT交易。FXS开盘价为4.5USDT,当前最高报价12USDT,最高涨幅166.66%。资料显示,Frax是一个分数算法稳定协议,该协议介绍了一种加密资产的概念,即部分靠抵押支撑,部分靠算法稳定。注:信息仅供分享,不构成任何投资建议。[2020/12/21 15:59:40]
攻击流程
这里有个小细节,代币转移流程中的顺序是按照事件先后顺序来显示的,而重入之后的买操作引起的事件会在卖操作引起的事件之前,所以在流程中看到的每一个单独的重入攻击中是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^15wei。
SurgeToken合约初始化的代币总量为10^9,根据前面推导出的结论,为攻击合约铸币200000000,则攻击合约拥有大约SURGE代币总量16%的代币。
攻击合约调用Attack()函数攻击,查看攻击合约的代币余额已变为209549307,获利9549307。
总结
XSURGE协议被攻击的本质原因在于sell()函数中存在重入漏洞,导致可通过purchase函数买入较多的SURGE代币而获利。
简而言之,典型的重入漏洞场景,教科书级的案例。
郑重声明: 本文版权归原作者所有, 转载文章仅为传播更多信息之目的, 如作者信息标记有误, 请第一时间联系我们修改或删除, 多谢。