0x01:前言
援引官方消息,北京时间12月19日,Fantom链上复合收益平台GrimFinance遭遇了闪电贷攻击。知道创宇区块链安全实验室第一时间对本次事件深入跟踪并进行分析。
0x02:事件详情
交易细节如下图所示:
浏览上图的交易过程可知,攻击合约利用闪电贷借取代币WFTM和BTC,将借取的代币与自己铸造的代币质押到SpiritSwap里增加流动性获取lp代币,而问题就出现在攻击者通过depositFor()实现质押的过程中。
通过Tenderly调试该笔交易,攻击者多次递归调用depositFor函数,利用该函数获取大量代币:
比特币挖矿难度下调至52.33T:金色财经报道,BTC.com数据显示,比特币挖矿难度于今日20:51(区块高度800,352)迎来了挖矿难度调整,挖矿难度下降至52.33T,当前全网平均算力为366.43 EH/s。[2023/7/26 16:00:14]
0x03:漏洞分析
depositFor()函数位于的第1115行:
function?depositFor(address?token,?uint?_amount,address?user?)?public?{
?uint256?_pool?=?balance();
Phaver发布新版本,添加照相功能并允许直接在应用内连接多个钱包的NFT:7月5日消息,基于Lens Protocol上的Web3社交应用Phaver宣布发布6.8.2版本更新,新增多个朋友标记,添加Phaver自己的照相功能和新的照片编辑器,还允许用户直接在应用内连接来自多个钱包的NFT。[2023/7/5 22:18:12]
?IERC20(token).safeTransferFrom(msg.sender,?address(this),?_amount);
?earn();
?uint256?_after?=?balance();
?_amount?=?_after.sub(_pool);?//?Additional?check?for?deflationary?tokens
?uint256?shares?=?0;
香港政府成立Web3.0发展专责小组,成员7月1日履新:金色财经报道,香港特区政府已宣布成立Web3.0发展专责小组。专责小组成员包括15名来自相关业界的非官方成员,以及相关主要政府官员和金融监管机构的代表。此专责小组主席由香港财政司司长陈茂波担任,成员则选自政府相关部门、金融监管机构和行业标杆企业。安全审计公司CertiK联合创始人顾荣辉教授也受邀加盟,名列15名非官方成员中。非官方成员任期由7月1日起生效,为期两年。
香港特区政府于去年10月发表《有关虚拟资产在港发展的政策宣言》,说明政府对行业的政策立场和方针,市场对此反应踊跃。虚拟资产是Web3.0生态圈的重要一环,政府将成立有关的专责小组,就Web3.0在港的可持续和负责任发展,向政府提交建议。[2023/7/2 22:12:52]
?if?(totalSupply()?==?0)?{
??shares?=?_amount;
安全团队:BSC链上Level Finance被盗资金目前仍存放在攻击者地址内:金色财经报道,根据区块链安全审计公司Beosin旗下的Beosin EagleEye安全风险监控、预警与阻断平台监测显示,2023年5月2日BSC链上的Level__Finance 项目被攻击,损失资金高达一百万美元。通过分析代码得知,攻击者地址0x61bb...12e创建了攻击合约0xf08a...629,随后利用攻击合约调用了被攻击合约0x9770...63a的claimMultiple函数,由于被攻击合约在users奖励计算后没有进行对应的users账本清除,导致同一个epoch的claimed奖励可以被反复领取。攻击者多次调用函数使用同一个epoch来反复领取Level Token,随后将领取的Level Token在多个pair中swap成3345个BNB(约109万美元),被盗资金目前仍存放在攻击者地址内(0x70319d1c09e1373fc7b10403c852909e5b20a9d5),Beosin将持续对被盗资金监控。[2023/5/2 14:38:03]
?}?else?{
过去一周NFT销售额增长超过43%,突破3.97亿美元:金色财经报道,根据2023年2月18日记录的统计数据,过去7天不可替代代币(NFT)资产的销售额与前一周相比增长了43.97%。本周NFT销售额达到3.9786亿美元,有345,716名NFT买家和大约162万笔交易。以太坊区块链上的NFT销售额占主导地位,占3.6032亿美元,占总销售额的90%以上。[2023/2/19 12:15:40]
??shares?=?(_amount.mul(totalSupply())).div(_pool);
?}
?_mint(user,?shares);
}
该函数的safeTransferFrom()方法从IERC20(token)调用,调用完该方法后,余额balance也会随之变动,最后通过_mint()方法向用户添加质押凭证代币。其中调用的变量token可控,导致攻击者可以自己实现safeTransferFrom()方法,将该方法重入到depositFor()发起攻击。
以实施了5次重入攻击为例,开始_pool的值为0,在重入depositFor方法的前四次里,攻击者一直传入自己铸造的代币,_pool的值会一直保持为0,但在第五次,也就是最后一次传入100个受认可的代币时,_after的值会变成100,而_afer-_pool的差值_amount也就是100,最后由于重入了5次,导致合约会向攻击者铸造100*5的质押凭证代币。
其后果就是攻击者向该合约质押自己铸造不受认可的代币,同样会增加质押总量,最后利用多出来的质押凭证实现套利。
0x04:修复方案
1.由于depositFor()方法里的token可控才是导致这次攻击事件的原因,因此只需要在传递参数的时候让token不可控就行:
function?depositFor(?uint?_amount,address?user?)?public
2.由于套利的原因是depositFor()方法里存在修改代币数量的函数,因此还可以将修改代币的方法单独实现,这样即使token变量可控,也无法成功套利:
function?depositFor(address?token,?uint?_amount,address?user?)?public?{
?IERC20(token).safeTransferFrom(msg.sender,?address(this),?_amount);
}
3.锁定交易token:
function?setLPToken(address?lp)?public?onlyOwner?{
lpToken?=?lp;
}
function?depositFor(uint?_amount,address?user?)?public?{
uint256?_pool?=?balance();
IERC20(lpToken).safeTransferFrom(msg.sender,?address(this),?_amount);
earn();
......
}
0x05:总结
经过完整分析,知道创宇区块链安全实验室明确了该次攻击事件的源头并非网传的闪电贷攻击,攻击者利用GrimBoostVault合约的depositFor方法参数可控,实施了重入攻击,将自己的铸造的无价值代币兑换成了质押凭证,最后通过withdrawAll方法实现套利,而闪电贷?攻击者只是利用闪电贷扩大了套利值。
对于合约代码而言安全性是十分重要的,每一个未经验证的传入参数都可能导致巨大的经济损失,开发者在编写重要操作方法时,须记住零信任原则,谨慎对待每一个传入参数。
来源:金色财经
郑重声明: 本文版权归原作者所有, 转载文章仅为传播更多信息之目的, 如作者信息标记有误, 请第一时间联系我们修改或删除, 多谢。