分析SharkTeam的ERC2771 Multicall中任意地址替换漏洞的原理

robot
摘要生成中

2023年12月8日,OpenZeppelin发布了重要的安全警告。原来,在共享ERC-2771标准和Multicall类型功能时存在地址被替换的风险!我深入研究了这个漏洞,并希望分享我的发现。

攻击分析

考虑一种攻击:

  • 攻击者:0xFDe0d1575Ed8E06FBf36256bcdfA1F359281455A
  • 交易: 0xecdd111a60debfadc6533de30fb7f55dc5ceed01dfadd30e4a7ebdb416d2f6b6

攻击方案简单而巧妙:

  1. 恶意攻击者将5 WETH兑换为大约3,455,399,346 TIME
  2. 然后构造了巧妙的calldata参数,并调用了[Forwarder].execute
  3. 此功能在TIME合约中启动了multicall,剩余的calldata用于burn() - 在池中销毁代币!

它是如何工作的?

在这次攻击中,星星汇聚在一起:ERC-2771、Multicall和精心编制的数据。TOKEN合约继承了ERC2771Context,这里开始变得有趣起来!

ERC-2771提供了虚拟的msg.sender,允许将交易委托给第三方。同时,真实地址被添加到calldata中。当[Forwarder]调用合约时,_msgSender()检查这些数据并裁剪最后20个字节作为"真实" msg.sender。

Multicall 将一个调用转换为多个调用,从而节省燃气。它接受一个调用数组,并通过 deleGatecall() 执行它们。

而这里是陷阱!攻击者移动 calldata,使得前 4 个字节的新数据对应于函数 burn(),而参数是巨额的代币。在 0x20 行中添加了 TIME-ETH 流动性池的地址,成为 "预期的" msg.sender!

问题的根源

在 ERC-2771 [Forwarder] 从未计划与 multicall 一起使用!攻击者将参数 _msgSender() 添加到 multicall 的外部调用中。在 multicall 函数内部,一些函数也添加了这些参数,这使得它们能够模拟来自任何地址的调用!

保护措施

  1. 新版 OpenZeppelin Multicall 现在保存 ERC-2771 的上下文长度,并在每次子调用时考虑它。

  2. ThirdWeb 更进一步,禁止任何合约调用 multicall,防止使用 [Forwarder].

这个漏洞是一个鲜明的例子,说明单独安全的组件组合在一起可能会造成灾难性的缺口!所有开发者都应该记住:始终检查不同标准之间的交互。

ETH-0.3%
查看原文
此页面可能包含第三方内容,仅供参考(非陈述/保证),不应被视为 Gate 认可其观点表述,也不得被视为财务或专业建议。详见声明
  • 赞赏
  • 评论
  • 转发
  • 分享
评论
0/400
暂无评论
交易,随时随地
qrCode
扫码下载 Gate App
社群列表
简体中文
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)