漏洞发现:在弯曲的草坪上发现了一条毒蛇

  • kupiasec
  • 发布于 2024-05-04 20:41
  • 阅读 40

文章讲述了作者在Avalanche和Curve等DeFi项目中寻找漏洞的经历,特别是发现并报告了Curve池中的重入攻击漏洞,最终获得了高额赏金。

错误通常存在于复杂的地方。

在2023年11月底,在经历了多次在ETH主网上的错误猎杀失败后,我决定转移我的关注点。Avalanche的Multichain Router V6上的漏洞提醒我,虽然以太坊经过了彻底的审查并吸引了大量的MEV机器人,但其他L1链却相比之下受到的关注较少。这从漏洞的简单性以及它在近两年中未被发现的事实中显而易见。Avalanche也很复杂——包括X、P和C链。显然,复杂性增加了错误和疏忽的可能性。

Multichain Router V6漏洞——函数changeMPC缺少访问控制

我筛选了在ImmuneFi上列出的Avalanche项目,Geode Finance引起了我的注意。Geode Finance是Curve的Solidity移植版本,类似于Solidly / Nerve Finance。

Curve是DeFi的前沿之一,已经有许多Solidity版本的Curve分叉,例如Ellipsis、Swerve和LeetSwap。通过这些现场测试,Curve分叉变得相当稳固,这对于Geode Finance也是如此。

在我的评估中,我没有发现Geode Finance存在任何漏洞。然而,Geode Finance具有一种独特的代币叫做gAVAX,它基于_ERC1155_标准,并且池代码中有_onERC1155Received_函数。

嗯,我们之前在这里见过……

这让我开始想到重入攻击,因为在_AVAX_或_ERC1155_代币转移期间是可能有重入的。

由于我已经熟悉Curve的Vyper代码,我快速打开了一个ETH池。

Curve池没有_ERC1155_代币,但它们处理原始ETH,因此重入是可能的。

常见的场景是直接将代币转入池中,以破坏代币的会计。如果任何计算使用了token.balanceOf,则可以通过增加余额来操控。

幸运的是,代码都是在_self.balances_状态变量上运行,因此重入不会影响那些。它在重要的方法中也有重入锁。

有几个地方使用了token.balanceOf。要么是为了检查债务人是否有足够的余额,要么是用一对_balanceOf_来获取实际转移的代币数量。除了一个,在_withdrawAdminFees()_中。

withdraw_admin_fees——使用balanceOf,公共的

_withdrawAdminFees()_是潜在攻击者的完美点。它没有重入锁,使用了token.balanceOf

但我很快注意到,相关函数是特权的。如果它是一个任何人都可以访问的普通函数,就可能触发重入攻击,从而导致池状态和实际代币余额之间的不一致。这让我想起了Curve的丰富池类型,我想知道是否某处可能潜伏着公共的withdrawAdminFees()函数。

我使用CodeIsLaw搜索合约。

codeslaw——搜索withdraw_admin_fees

https://etherscan.io/address/0x94b17476a93b3262d87b9a326965d1e91f9c13e7#code——这个池符合条件。

接下来,我必须找到重入点,即在更新余额之前发生外部调用的地方,_remove_liquidity_imbalance()_就是那个!

好的,我快到了……

深吸一口气,端着一杯咖啡,我开始编写PoC

漏洞在于某些池可被强制破坏,通过在_remove_liquidity_imbalance_的fallback中调用_withdraw_adminfees

remove_liquidity_imbalance——使用raw_call发送ETH

详细步骤:

  • 准备代币
  • 使用代币通过_add_liquidity_添加单侧流动性
  • 通过_remove_liquidity_imbalance_移除流动性,指定ETH提取量为1 wei,以便在减少代币数量时调用fallback,像减少10⁹ wei,以避免函数回滚
  • 在fallback函数中(receive),调用_withdraw_adminfees

结果,池的代币余额在产生少量损失的同时减少了一些(交易费 + 添加/移除流动性舍入)在调用者的侧面。

PoC输出——余额状态与实际余额之间的不一致

你可以看到余额变得低于余额状态变量。

在初步报告提交后,我继续提供额外细节以及后续沟通中的进一步影响。

几小时后,我收到了回复。

我们进行了往返讨论。影响可能通过闪电贷被放大。由于存在OETH金库,攻击者可以闪电贷ETH来铸造OETH,并用其强迫池将大部分代币发送到费用收集者。

我一直喜欢Klein bottle团队,因为他们是最早的创新者之一,他们的代码简单且数学上整洁。正如我所预期的,讨论非常顺利,团队决定授予最高奖金——250,000美元。我很惊讶地发现创始人Michael Egorov直接处理了提交,和他交流是一次很好的体验。

紧急修复很快实施,然后为治理投票提出了永久修复。现在,费用接收者在ETH接收时检查重入,因此_if withdraw_admin_fees()_将回滚如果我们重入。

在检查Curve分叉时,我发现大多数基于Solidity的分叉都有特权的withdrawAdminFees,或者在_removeLiquidity_过程中使用_WETH_而非原始ETH。因此,这些实现被认为是安全的。

2023年的最后几天相对平静,安全事件也很少。然而,对我个人而言,这是一个充满兴奋和迷人经历的时期。

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

时间线

11/29 13:10 报告

11/29 18:47 回复,确认

11/30 内部安全审查

12/2 提交紧急修复提案投票

12/3 应用紧急修复,禁用费用转换

12/6 提交修复提案投票

12/12 应用修复,奖金支付

我仍然觉得,与大量DeFi协议相比,真正认真的安全研究人员数量相对较少。

有许多漏洞在那里等着被发现,但机会只属于有准备的头脑。

机会偏爱有准备的头脑,机会偏爱勇敢者。

路易斯·巴斯德,法国微生物学家和化学家,在1854年里尔大学的讲座中

我是 Marco Croc KupiaSec 的首席安全研究员。

KupiaSec是一个区块链安全组织,旨在通过采用最先进的安全审计流程来实现安全审查的最高质量。

  • 原文链接: medium.com/@kupiasec/fin...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,在这里修改,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
kupiasec
kupiasec
江湖只有他的大名,没有他的介绍。