如何使用硬件钱包进行(不)盲签Safe多重签名交易
如何使用硬件钱包进行(不)盲签Safe多重签名交易
在区块链安全领域,多重签名交易是一种常见的安全保障机制。然而,如果签署者在不了解交易细节的情况下盲目签署,仍然可能带来巨大的安全风险。本文通过分析Radiant Capital黑客事件,深入探讨了如何使用硬件钱包安全地进行多重签名交易,为区块链开发者和安全从业者提供了宝贵的安全实践建议。
2024年10月,Radiant Capital遭遇黑客攻击,超过5300万美元的不同代币从Arbitrum和BNB Smart Chain的协议实例中被盗。本文作者通过重现攻击过程,详细分析了如何通过仔细检查硬件钱包屏幕来避免盲目签署关键的元交易。
Safe 元交易
在Safe的上下文中,元交易允许代表特定多签合约执行交易的协议。它们存储在Safe后端中,直到收集到所需的法定人数签名。一旦收集完成,元交易将被提交到链上进行执行。Safe合约验证签名,如果签名足够且有效,它将执行元交易。
在Radiant黑客事件的具体案例中(为简化解释,我将仅关注Arbitrum实例),3/11 Safe多签是Radiant的Pool Provider合约的所有者。持有被盗资产的合约以及用户授予许可的合约是Lending Pool,这是一个可升级的合约,其实施在黑客攻击前位于0x453213A0。Pool 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 data是SafeTx的一个字段,
重现签名过程
为了重现该事件,我使用了一个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中所示:
- 没有指向Pool Provider。
- 没有调用transferOwnership函数。
然而,根据官方事后报告,这并不是一个常规情况,签署者的设置被以某种方式攻破,以至于Safe UI和注入的钱包(在此重现中为Rabby)都没有显示正在签署的真实数据。因此,硬件钱包(在此情况下为Trezor Safe 3)是检测恶意签名的最后防线。
如图所示,Trezor Safe 3足够聪明,可以解释EIP-712,并在签署之前让我们检查和确认每个结构化数据的组件。
在我的观点中,此阶段攻击者无法远程篡改硬件钱包以显示虚假交易。事实上,只要攻击者有物理访问权限并披露PIN,攻击者就会控制私钥,即使没有用户确认,也能拥有签署所需的一切。
综上所述,在这个阶段发生了两个潜在错误:
- 使用的硬件钱包不兼容EIP-712,导致数据以字节字符串的形式显示,导致盲目签署。与被盗的价值相比,兼容的钱包成本微不足道。
- 签署者缺乏必要的知识和/或意识,无法仔细检查EIP-712类型数据的每个字段。任何负责在具有如此TVL的协议中授权这些操作的人都应接受彻底培训,以确保他们具备这方面的专业知识。
参考资料
- Rekt News. (2024年10月17日). Radiant Capital — Rekt II
- Radiant Capital. (2024年10月18日). Radiant Capital 事后报告
- Ethereum Improvement Proposals. EIP-712: 结构化数据哈希和签名
- Trezor. 常见安全威胁