SharkTeam
- 关注
北京时间2023年11月11日,Raft遭受闪电贷攻击,项目方损失360万美元,但随后攻击者几乎将全部ETH转入黑洞地址销毁,不知是刻意还是失误。
SharkTeam对此事件第一时间进行了技术分析,并总结了安全防范手段,希望后续项目可以引以为戒,共筑区块链行业的安全防线。
一、事件分析
攻击者地址:
0xc1f2b71A502B551a65Eee9C96318aFdD5fd439fA
攻击合约:
0x0A3340129816a86b62b7eafD61427f743c315ef8
0xfdc0feaa3f0830aa2756d943c6d7d39f1d587110
0x011992114806e2c3770df73fa0d19884215db85f
被攻击合约:
0x9ab6b21cdf116f611110b048987e58894786c244
0xd0db31473caad65428ba301d2174390d11d0c788
攻击交易:
0xfeedbf51b4e2338e38171f6e19501327294ab1907ab44cfd2d7e7336c975ace7
攻击流程:
(1) 攻击者(0xc1f2b71A)通过闪电贷借取6000枚cbETH。
(2)随后向攻击合约(0x9ab6b21c)转移6001枚的cbETH。
(3)攻击者(0xc1f2b71A)调用liquidate函数(使用预先创建的仓位),目的是通过逻辑漏洞改变storedIndex变量的值。
(4)攻击者(0xc1f2b71A)随后调用60次managePosition函数,每次使用1wei的cbETH换取1wei的rcbETH-c,总计获得60wei。
(5)攻击者(0xc1f2b71A)通过上一步获得的60wei rcbETH-c加上已更改的storedIndex变量,使攻击合约(0x0A334012)目前的rcbeth-c的余额到了10050枚。
(6) 攻击者(0xc1f2b71A)调用managePosition函数使用rcbETH-c换回cbETH.
(7)然后调用managePosition函数凭借剩下的rcbETH-c代币借出了6.7m枚R代币。
(8)将获得的R代币兑换为sDai,Dai,USDC等代币
(9)攻击者(0xc1f2b71A)最后将所有代币兑换为WETH并提取成ETH发给零地址。
(10)最后攻击者(0xc1f2b71A)偿还闪电贷后,仅获得7ETH。
二、漏洞分析
攻击的本质是在铸造份额代币是精度计算出现了问题,使得关键变量index值被操纵,并且未详细考虑代币精度的四舍五入问题。
rcbETH中,balanceOf函数不仅通过原生的balanceOf计算余额,还与storedIndex相乘后才是最终的余额。
攻击者(0xc1f2b71A)在第二步中预先将6001枚cbETH转入了InterestRatePositionManager合约中,随后在liquidate函数中,将cbETH的setIndex函数传参设置为了当前的cbETH余额。
导致在setIndex函数中最后计算得到的storedIndex变量变大了上千倍。
并且在cbETH合约中,mint函数使用divUp函数来进行铸造,在divUp模式中,遵循向上取整原则,只要a不等于0,那么最终计算出的结果最小也会是1。
所以在第四步中攻击者只用了一wei的cbETH就换到了1wei的rcbETH-c,而由于storedIndex变量变大了上千倍,所以1wei的rcbETH-c最终呈现出来的余额也会变大上千倍。导致攻击者获得足够的rcbETH-c后不仅可以把cbETH给换回来,还能借出大量的R代币。
三、安全建议
针对本次攻击事件,我们在开发过程中应遵循以下注意事项:
(1)在进行份额币铸造时,严格校验币和币之前的精度问题。
(2)开发代币精度时,慎重考虑取整情况,是否需要向上取整。
(3)项目上线前,需要向第三方专业的审计团队寻求技术帮助。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)