GRI:Grim Finance闪电贷安全事件分析

0x01:前言

援引官方消息,北京时间12月19日,Fantom链上复合收益平台GrimFinance遭遇了闪电贷攻击。知道创宇区块链安全实验室第一时间对本次事件深入跟踪并进行分析。0x02:事件详情

交易细节如下图所示:

浏览上图的交易过程可知,攻击合约利用闪电贷借取代币,将借取的代币质押到SpiritSwap里增加流动性获取lp代币,而问题就出现在depositFor()函数中。通过Tenderly(https://dashboard.tenderly.co/tx/fantom/0x19315e5b150d0a83e797203bb9c957ec1fa8a6f404f4f761d970cb29a74a5dd6/debugger调试该笔交易,攻击者多次递归调用depositFor函数,利用该函数获取大量代币:

Grin预计将于1月17日0点左右进行第四次硬分叉Grinv5.0.0:据官方消息,匿名币项目古灵币Grin预计将于1月17日0点左右进行第四次硬分叉Grinv5.0.0。按照既定规划,Grin将在最初两年中进行4次硬分叉,即每经过262080个区块(约6个月间隔)进行一次。[2021/1/14 16:08:57]

0x03:漏洞分析

depositFor()函数位于https://ftmscan.com/address/0x660184ce8af80e0b1e5a1172a16168b15f4136bf#code的第1115行:

Grin已完成第三次硬分叉升级:金色财经报道,匿名币项目古灵币Grin已于7月17日在区块高度786240完成第三次硬分叉(v4.0.0网络升级)。据此前报道,Grin客户端发布4.0正式版,Grin已经支持第3次的硬分叉升级。据悉,按照既定规划,Grin将在最初两年中进行4次硬分叉,即每经过262080个区块(约6个月间隔)进行一次。[2020/7/17]

该函数的safeTransferFrom()方法从IERC20(token)调用,最后一次调用,也就是逆序第一次执行后,余额balance也会随之变动。当前铸造凭证数量/前一笔铸造凭证数量固定为3.54:

动态 | Grin预计将于明日达到硬分叉升级区块高度:Grin将于区块高度 524,160 进行硬分叉升级。Grinexplorer 网站显示,目前区块高度为 521,295。根据平均出块时间计算,Grin 估计将于1月16日左右达到硬分叉升级出块高度。[2020/1/15]

我们推导其公式为:

将该公式分子拆分,得到shares/totalSupply的固定比为2.54:

动态 | 古灵币 Grin 再次收到 50 个比特币捐赠 捐赠人为比特币最早期信仰者:完全由社区驱动的隐私币项目古灵币 Grin 开发基金再次收到了一笔共 50 个比特币的捐赠,捐赠人匿名,捐赠者的比特币来自于2010年12月的区块,应为比特币早期参与者。捐赠者曾联系了Grin核心开发团队并表示:我不会管你们如何花钱这笔捐赠,只是想确保你们可以处理它并根据需要进行分配。感觉又像是回到了 2009 年、2010 年的时候。不用担心,你们做得很好。现在有了 Grin,真是太好了,我们的动机并不是赚钱,而是关于技术和协议。此前,Grin 开发基金曾在今年 5 月份收到过一笔共 50 个比特币的捐赠,捐赠人匿名,不过捐赠者的比特币来自于 2010 年 11 月 25 日挖出的 93709 区块。古灵币是一个完全去中心化的社区驱动项目,无 ICO 和预先挖矿,该项目开发资金完全依靠社区捐赠。[2019/11/12]

声音 | 余弦:基于MimbleWimble的BEAM和Grin面临交易中间人劫持等安全问题:区块链安全公司慢雾创始人余弦发微博称,根据最近一段时间的研究,相比其他数字货币,基于MimbleWimble的BEAM和Grin至少有这几种独特安全问题:1. 交易中间人劫持问题;2. 交易针对性拒绝服务问题;3. 交易的交互复杂导致的其他传统网络安全问题。颠覆性的交易设计,大众适应期恐怕会不短。[2019/3/22]

最后将Debug交易里的shares/totalSupply进行计算,其值与shares/totalSupply的固定比相同,因此可以确定套利值只与totalSupply()有关:

其中函数safeTransferFrom()传入的变量token可控,导致攻击者可以自己实现safeTransferFrom()方法,将该方法重入到depositFor(),拉升totalSupply()总量,最后通过_mint()方法向用户添加质押凭证实现套利。以实施了5次重入攻击为例,开始pool的值为0,在重入depositFor方法的前四次里,攻击者一直传入自己铸造的代币,pool的值会一直保持为0,但在第五次,也就是最后一次传入100个受认可的代币时,after的值会变成100,而afer-pool的差值amount也就是100,最后由于重入了5次,导致合约会向攻击者铸造100*5的质押凭证代币。

其后果就是攻击者只质押一次代币,仍能多次增加质押总量实现套利。0x04:修复方案

1.由于depositFor()方法里的token可控才是导致这次攻击事件的原因,因此只需要在传递参数的时候让token不可控就行:

2.由于套利的原因是depositFor()方法里存在修改代币数量的函数,因此还可以将修改代币的方法单独实现,这样即使token变量可控,也无法成功套利:

3.锁定交易token:

0x05:总结

经过完整分析,知道创宇区块链安全实验室明确了该次攻击事件的源头并非网传的闪电贷攻击,攻击者利用GrimBoostVault合约的depositFor方法参数可控,实施了重入攻击,将自己的铸造的无价值代币兑换成了质押凭证,最后通过withdrawAll方法实现套利,而闪电贷?攻击者只是利用闪电贷扩大了套利值。对于合约代码而言安全性是十分重要的,每一个未经验证的传入参数都可能导致巨大的经济损失,开发者在编写重要操作方法时,须记住零信任原则,谨慎对待每一个传入参数。

郑重声明: 本文版权归原作者所有, 转载文章仅为传播更多信息之目的, 如作者信息标记有误, 请第一时间联系我们修改或删除, 多谢。

链链资讯

[0:0ms0-7:50ms