任意地址欺骗攻击:ERC2771Context Multicall 公开披露

OpenZeppelin 团队发现了一个漏洞,该漏洞影响了同时实现 Multicall 和 ERC-2771 的合约,可能导致地址欺骗。文章详细介绍了漏洞的原理、攻击方式、缓解措施以及解决方案,并提供了受影响的第三方合约列表和攻击案例。

OpenZeppelin 团队迅速验证了该问题并非 OpenZeppelin Contracts 库中包含的实现的特有问题。 尽管如此,为了保护生态系统免受此漏洞的影响,OpenZeppelin 事件响应团队牵头识别了可能存在漏洞的合约。在识别阶段之后,OpenZeppelin 团队联系了更广泛的生态系统合作伙伴,以扩展识别工作和缓解措施。 当前情况

概览

描述

攻击可视化

参考

识别漏洞

缓解步骤

步骤 1. 禁用所有可信转发器(如果可能)

步骤 2.

2.1 暂停你的合约(如果可能)

2.2 要求你的用户删除对你合约的任何授权(如果相关)

步骤 3. 准备升级(如果可能)。

步骤 4. 评估快照选项

解决方案

当前情况

这是一个由有问题的集成模式引起的广泛问题。它对生态系统产生了广泛的影响,特别是对于 thirdweb 用户和 thirdweb 分叉。受影响的 thirdweb 合约在此处列出,但可能还有其他通过我们的库或其他实现进行的问题集成,这些集成也可能受到影响。

我们的团队通过协调系统化的联系策略,帮助了几个拥有大量资产的池子,包括这个。尽管如此,在 Dedaub 和 Ironblocks 团队的监控和分析的帮助下,我们观察到一些攻击正在进行:

金额: 84.59 ETH https://explorer.phalcon.xyz/tx/eth/0xecdd111a60debfadc6533de30fb7f55dc5ceed01dfadd30e4a7ebdb416d2f6b6

金额: 17,394 USDC https://polygonscan.com/tx/0x1b0e27f10542996ab2046bc5fb47297bcb1915df5ca79d7f81ccacc83e5fe5e4

金额: 1.06 ETH https://explorer.phalcon.xyz/tx/eth/0x4ed1ec3d33c297560ed8f5a782b54d2c52adb20155c543fb64ba9065e45c046c?line=6

金额: 0.73 ETH https://explorer.phalcon.xyz/tx/eth/0xc9c7b2ae3a6fb82aec113a328d53bfdd7ddd449e2f76da85d169321df20cd22a?line=6

金额: 0.36 ETH https://explorer.phalcon.xyz/tx/eth/0xb5649546e4775e2453d5dd4ded898690fe860154474f92c2fdef4a5770dec025?line=6

金额: 0.29 ETH https://explorer.phalcon.xyz/tx/eth/0x913f68babb2851903df7efe6bbc7c83dbbd1c2a858df0d47a1328750f90305fb

概览

任何同时实现 Multicall 和 ERC-2771 的合约都容易受到地址欺骗的攻击。在 OpenZeppelin 合约库的上下文中,这可以通过 MulticallERC2771Context 来完成。攻击者可以将恶意 calldata 包装在转发的请求中,并使用 Multicalldelegatecall 功能来操纵子调用中的 _msgSender() 解析。

描述

ERC-2771 是元交易的标准。它标准化了应如何为受信任转发器中继的调用解析调用者地址。在此类调用期间,msg.sender 是转发器的地址,而实际调用者只有转发器本身知道(并且使用签名进行验证)。因此,ERC-2771 详细说明了转发器如何将有关原始调用者的此信息传递给被调用的合约。

如在 OpenZeppelin Contracts ERC2771Context 实现中看到的,ERC-2771 标准覆盖了 msgSender()msgData(),以便正确考虑来自受信任转发器的调用。当检测到此类调用时,实际调用者的地址将从 calldata 的最后 20 个字节中提取。

攻击可视化

💡 这是对攻击的简单表示。攻击者可能会在单个 multicall(bytes[]) 中包装多个欺骗调用

参考识别漏洞

可以通过 OpenZeppelin Defender 的代码检查器 检测集成来自 OpenZeppelin Contracts 的 ERC2771ContextMulticall 的合约。OpenZeppelin Defender 安全平台要求满足以下每个条件,然后才能将合约标记为易受攻击:

  • 合约导入任何标题或文件名中带有 Context 后缀的合约。任何变体都假定遵循 ERC-2771 模式。

    • 合约导入任何标题或文件名中带有 Multicall 前缀的合约。

如果合约包含以下所有特征,则会受到影响:

  • 能够使用用户提供的数据对自身进行 delegatecall(例如,Multicall
  • 某些上下文详细信息(例如,调用者的地址)是从受信任合约传递的数据中提取的。特别是,ERC2771Context 或类似的 ERC-2771 实现(包括 GSNRecipient)就是这种情况。
  • 启用的受信任转发器,或者创建转发器的能力。请注意,成功执行攻击的能力仅限于可以调用转发器的那些地址。

缓解步骤

推荐的缓解步骤取决于实例详细信息。在采取行动之前,评估漏洞是否已蔓延到有权访问其他关键功能的函数:

  • 使用 _msgSender() 检查访问控制管理功能。一些具体的例子是使用 _msgSender()onlyOwneronlyRole 函数。

  • 查找常见的转移函数,例如 safeTransferFrom()transfer()

步骤 1. 禁用所有可信转发器(如果可能)

某些自定义 ERC2771Context 实现允许设置受信任的转发器。这样做可以阻止执行任何 gasless 交易,从而限制任何可能的利用。这可能不是令人满意的长期解决方案,但在找到更好的解决方案之前,这是一种临时缓解措施。

可以执行此步骤的用户可以跳过步骤 2。

步骤 2

2.1 暂停你的合约(如果可能)

暂停你的合约会影响你的用户,但可以降低漏洞的风险。但是,根据你的实现,该漏洞可能允许攻击者取消暂停你的合约。尽管这种缓解措施不完整,但它为潜在的攻击者增加了一个小障碍,从而赢得了一些时间来完成后续步骤。

2.2 要求你的用户删除对你合约的任何授权(如果相关)

虽然该漏洞在你的合约中仍然可能被利用,但请务必将受影响的用户指向诸如 Revoke.cash 之类的工具。这是一个不可或缺的步骤,因为它可以在许多情况下显着降低攻击的盈利能力。

步骤 3. 准备升级(如果可能)

如果你的合约无法升级,请转到步骤 4。

此潜在修复需要仅保留 MulticallERC2771Context 合约中的一个,无论它们碰巧都存在。根据你的用户与你的合约交互的方式,一个合约可能比另一个合约对系统的可用性产生更大的影响,这可能有助于你确定保留哪个合约,以最大限度地减少对最终用户的影响。

如果你使用的转发器包含一些批处理机制,你可能希望删除 Multicall,而选择基于 ERC-2771 的批处理解决方案。这将影响你的用户必须签署的内容(EIP-712 类型化数据 + 中继交易)。

你可以使用 OpenZeppelin Upgrades 插件 检查你的升级操作的兼容性,或者 使用 OpenZeppelin Defender 协调你的升级。升级完成后,该漏洞应已修复。如果你已完成此步骤,则可以忽略步骤 4。

步骤 4. 评估快照选项

除非你可以执行步骤 1,否则无法升级的易受攻击的合约无法将自身恢复到完全工作和安全的状态。但是,仅执行步骤 1 会使你的合约不支持元交易。如果你需要重新启用此功能才能使你的系统正常运行,你可能需要计划迁移。

我们建议项目识别可信转发器可能已被授予的任何角色。这是因为即使在完成步骤 1 后,攻击者仍然可以使用转发器。OpenZeppelin Defender 访问控制 模块可以帮助识别感兴趣合约中的访问控制角色。

请注意,迁移是一个复杂的过程,会对你的用户和你交互的其他协议产生影响。但是,这样做可能是成功缓解漏洞所必需的。因此,我们建议你联系值得信赖的顾问来计划迁移。

升级的替代方法是获取你的合约状态的快照。这样做将取决于数据在你的合约中的存储方式,尽管有适用于 ERC-20 和 ERC-721 合约的解决方案。其他不太标准的合约可能需要自定义逻辑才能实现对快照机制的支持。然后,可以在部署新修补版本的系统时复制此状态副本。

区块链会公开跟踪所有更改。因此,一旦你确定了一个“安全”的区块号(在执行任何攻击之前),你应该能够在几天、几周甚至几个月内构建快照。你需要时间来计划如何使用此快照作为新部署的基础。

请记住,你的合约持有的任何资产(作为抵押品)都可能无法转让。此外,如果你的合约是第三方协议中用作抵押品/流动性的资产(例如,它是 AMM 中交易的 ERC-20),你必须考虑该迁移对流动性提供者的影响。

解决方案

为了履行我们对安全生态系统的承诺,我们发布了 OpenZeppelin Contracts 的 4.x 和 5.x 版本的更新,允许将 MulticallERC2771Context 一起使用。

虽然这些模式之间的集成在没有适当措施的情况下仍然存在问题,但对 OpenZeppelin Contracts 库的更新允许以安全和向后兼容的方式进行集成。新版本的 Multicall 带有 ERC2771context 数据的上下文后缀长度,该长度用于标识 ERC-2771 的预期后缀长度。通过这种方式,来自受信任转发器的任何调用都将被识别并适应每个子调用。

现在,Multicall 的使用建议考虑到对收到的 msg.data 的任何期望都可能通过在 Multicall 中包装一个调用来绕过,从而阐明其潜在的危险。

你对任何 OpenZeppelin 服务(包括此处包含的任何信息)的使用均受我们的服务条款约束,该条款可在 https://openzeppelin.com 上找到。为清楚起见,此信息(包括任何潜在的缓解步骤)仅供参考,并且你承认与此类信息相关的风险,包括此类信息可能不准确或不适用于你的情况的风险。你理解并同意,此处包含的信息是在纯粹的非依赖基础上提供的,并且任何使用均由你自行承担风险。

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

0 条评论

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