前言
8月17日,BSC链上的XSURGE协议遭到闪电贷攻击,损失超过500万美元。对此,知道创宇区块链安全实验室对攻击流程和代码细节进行了全盘梳理。
全盘梳理
基础信息
-攻击tx:0x7e2a6ec08464e8e0118368cb933dc64ed9ce36445ecf9c49cacb970ea78531d2-攻击合约:
0x1514AAA4dCF56c4Aa90da6a4ed19118E6800dc46
-SurgeToken:
0xE1E1Aa58983F6b8eE8E4eCD206ceA6578F036c21
数据:近日有143万枚FXS已解锁,约合1170万美元:金色财经报道,Lookonchain数据监测显示,最近有约143万枚FXS(约合1170万美元)已解锁。[2023/4/23 14:21:59]
攻击流程
这里有个小细节,代币转移流程中的顺序是按照事件先后顺序来显示的,而重入之后的买操作引起的事件会在卖操作引起的事件之前,所以在流程中看到的每一个单独的重入攻击中是SURGE的买入发生在卖出之前。
0xScope:另一地址也曾在币安宣布上线RPL之时买入5353 RPL:金色财经报道,链上数据分析平台0xScope发推称,除了此前提到的以0x5f2c开头的地址外,另一个以0xac5ca开头的地址也在币安宣布上线RPL的数秒之后买入了5353枚RPL,此后该地址将3000枚RPL转入了币安,又在1inch将剩下的2353枚RPL卖出。
稍早之前,0xScope发推称一个以0x5f2c开头的地址在币安官宣上线RPL前10分钟买入近6200枚RPL,并在币安发布公告后10分钟卖出,在20分钟内盈利5.54万美元。[2023/1/18 11:19:07]
漏洞原理
漏洞点在于SurgeToken合约中的sell()函数,其中对调用者msg.sender的BNB转账采用的call()函数,并且在转账之后才更新代币总量_totalSupply,是典型的重入漏洞场景。
XSURGE官方在遭遇攻击前披露SurgeBNB合约存在漏洞,随后不久遭攻击损失500万美元:归属社区的DeFi项目XSURGE今日遭遇闪电贷攻击,XSURGE官方在遭攻击前发布了关于SurgeBNB漏洞的声明。XSURGE表示,当地时间8月16日发现了SurgeBNB合约的潜在安全漏洞。由于SurgeBNB合约不可更改且已被放弃,因此无法追溯修补该代币。XSURGE称没有透露任何关于此漏洞性质的具体细节,但强烈建议用户尽快迁移出SurgereBnb,因为该漏洞随时都可能被攻击者触发。XSURGE官方决定将风险公开通知所有持有人。
在声明发布后,XSURGE随后便表示遭遇攻击,攻击者是通过后门漏洞在SurgeBNB中窃取了500万美元。由于SurgeUSD或SurgeETH不提取BNB,因此它们不能成为未来攻击的目标。
此前消息,PeckShield:XSURGE遭到闪电贷攻击。[2021/8/17 22:19:13]
动态 | Tata Elxsi将展示基于IOTA的车对车通讯解决方案:IOTA News今日在推特上表示,Tata Elxsi有限公司将在WCX20上展示一个基于IOTA的“可扩展、去中心化的车对车(Vehicle-to-Vehicle)安全通讯解决方案。据了解,Tata Elxsi是印度技术和设计公司,隶属于塔塔(Tata)集团。[2020/2/2]
虽然\nsell()函数使用了nonReentrant修饰防止了重入,但purchase()函数并没有。重入转回BNB给合约,触发\nfallback函数调用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代币而获利。
简而言之,典型的重入漏洞场景,教科书级的案例。
郑重声明: 本文版权归原作者所有, 转载文章仅为传播更多信息之目的, 如作者信息标记有误, 请第一时间联系我们修改或删除, 多谢。