如何使用硬件钱包进行(不)盲签Safe多重签名交易

这篇文章讨论了辐射漏洞,其中超过5300万美元被盗,原因是受影响的多签名签名者盲目地签署了一个转移合同所有权的关键元交易

我们的硬件钱包屏幕是签署任何交易时最后一个不可篡改的前线,双重检查我们签署的内容至关重要。

在 Radiant 漏洞爆发后的余波中,共有超过 5300 万美元¹ 的不同代币从 ArbitrumBNB Smart Chain 的协议实例中被盗。我的好奇心促使我尝试重现攻击的情况,并查看通过仔细检查我们的硬件钱包屏幕,如何避免盲目签署关键的元交易。

这篇文章的目的是不讨论协议管理中的薄弱安全实践,例如 3/11 多签设置(27% 的法定人数)或缺乏关键协议更改的时间锁延迟,也不研究这次攻击的复杂性,该攻击似乎经过了长时间的精心策划并专门针对 Radiant 团队。

我认为导致陷阱的致命错误是 3 名多签签署者在使用他们的硬件钱包设备签署致命的元交易时。凭借对该问题的充分了解,很容易意识到他们正在签署一个 transferOwnership 功能调用。

Safe 元交易

在 Safe 的上下文中,元交易允许代表特定多签合约执行交易的协议。它们存储在 Safe 后端中,直到收集到所需的法定人数签名。一旦收集完成,元交易将被提交到链上进行执行。Safe 合约验证签名,如果签名足够且有效,它将执行元交易。

在 Radiant 黑客事件的具体案例中(为简化解释,我将仅关注 Arbitrum 实例),3/11 Safe 多签 是 Radiant 的 Pool Provider 合约的所有者。持有被盗资产的合约以及用户授予许可的合约是 Lending Pool,这是一个可升级的合约,其实施在黑客攻击前位于 0x453213A0Pool Provider 的所有者能够任意替换 Lending Pool 实施的逻辑 💀,而这正是发生的事情。在劫持所有权后,攻击者用恶意代码替换了逻辑,使他或她能够从 Lending Pool 中抽走所有资产。

因此,引发攻击的关键失败只是,攻击者以某种方式设法让多签的总签署者(11)中的法定人数(3)签署了一项将 Pool Provider 的所有权转移到其控制的地址的元交易。transferOwnership 元交易 的 nonce 为 230,可以在 Safe UI 中看到。

Raw data 字段代表元交易的 ABI 编码的 calldata。在以太坊合约调用中,calldata 的前 4 个字节通常表示正在合约中调用的函数的选择器。元交易一旦被执行(在 3 个签名验证之后),Safe(msg.sender)多签就会使用 calldata 调用 Pool Provider 执行 transferOwnership 函数。由于 Safe 在那时是所有者,因此交易成功。

仅通过查看选择器的 4 个字节,我们无法确定调用的是哪个函数。然而,通过快速在 openchain.xyz 数据库中检查,我们可以确认相关的选择器对应于 transferOwnership 函数。让我们记住这一点,因为稍后它会很重要。

根据 Radiant 的官方事后报告²,3 名签署者的设备被攻破,Safe UI 显示与他们盲目签署的内容 不同的元交易

EIP-712 和 Safe 元交易离链签名

要理解授权签署者在签名时如何检测到这次攻击,我们需要理解 Safe 元交易如何在离链签名。EIP-712 是以太坊用于签署结构化数据的标准。不要被其规范中使用的符号所吓倒³;它的目标是标准化签名流程,以便能够以安全的方式在链上签署和验证离线消息。通过标准化和可组合的过程,钱包供应商可以轻松实现方法来解读签署的数据,向用户显示这些数据,并避免盲签一串字节。

EIP-712 可签名数据结构由 Solidity 结构定义,并且…… Bingo!Safe 在其合约中定义了一个 Solidity 结构 用于其元交易。

    struct SafeTx {
        address to;
        uint256 value;
        bytes data; <-- Safe UI 中的原始数据
        int8 operation;
        uint256 safeTxGas;
        uint256 baseGas;
        uint256 gasPrice;
        address gasToken;
        address refundReceiver;
        uint256 nonce;
    }

由于 Safe 元交易遵循 EIP-712 规范,钱包供应商可以实现以下哈希树结构来计算元交易摘要并进行签名,但首先让用户检查他们正在签署的结构化数据的每个字段。请注意,在 Safe UI 中显示的 Raw dataSafeTx 的一个字段,

重现签名过程

为了重现该事件,我使用了一个 2/2 Safe 多签和一个作为 Rabby 钱包外部签署者设置的 Trezor Safe 3。

此外,我创建了一个 虚拟 2/2 Safe 多签,并生成了一个与 Radiant 漏洞中的恶意交易具有相同特征的转让所有权元交易。你可以在 Safe UI 中检查到,与真实交易一样,原始数据字段的前 4 个字节与 transferOwnership 函数的选择器(0xf2fde38b)对应。元交易的目标设置为一个虚拟可拥有合约(0x3dbF0Cdd),已部署用于模仿 Pool Provider

在这个设置中,让我们开始为 Safe 多签的授权签署者的签名过程!

Safe UI 签名模态。

Rabby 钱包签名弹窗。

在这一点上,在正常情况下,一位授权签署者应该已经看到了足够多的红旗,立即停止签名过程,因为他们想要签署的原始元交易,如 Radiant 的 Safe 多签 UI 中所示:

  1. 没有指向 Pool Provider
  2. 没有调用 transferOwnership 函数。

然而,根据官方事后报告,这并不是一个常规情况,签署者的设置被以某种方式攻破,以至于 Safe UI 和注入的钱包(在此重现中为 Rabby)都没有显示正在签署的真实数据。因此,硬件钱包(在此情况下为 Trezor Safe 3)是检测恶意签名的最后防线。

如图所示,Trezor Safe 3 足够聪明,可以解释 EIP-712,并在签署之前让我们检查和确认每个结构化数据的组件。

在我的观点中,此阶段攻击者无法远程篡改硬件钱包以显示虚假交易⁴。事实上,只要攻击者有物理访问权限并披露 PIN,攻击者就会控制私钥,即使没有用户确认,也能拥有签署所需的一切。

综上所述,在这个阶段发生了两个潜在错误:

  1. 使用的硬件钱包不兼容 EIP-712,导致数据以字节字符串的形式显示,导致盲目签署。与被盗的价值相比,兼容的钱包成本微不足道。
  2. 签署者缺乏必要的知识和/或意识,无法仔细检查 EIP-712 类型数据的每个字段。任何负责在具有如此 TVL 的协议中授权这些操作的人都应接受彻底培训,以确保他们具备这方面的专业知识。

[1]: Rekt News. (2024年10月17日). Radiant Capital — Rekt II https://rekt.news/radiant-capital-rekt2/

[2]: Radiant Capital. (2024年10月18日). Radiant Capital 事后报告 https://medium.com/@RadiantCapital/radiant-post-mortem-fecd6cd38081

[3]: Ethereum Improvement Proposals. EIP-712: 结构化数据哈希和签名 https://eips.ethereum.org/EIPS/eip-712

[4]: Trezor. 常见安全威胁 https://trezor.io/learn/a/common-security-threats

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

0 条评论

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