原文作者:Moonbeam
时间轴
2025 年 2 月 21 日:Bybit 多签钱包被攻击, 15 亿美金通过「合法」签名交易流出。
链上追踪:资金转入匿名地址并分拆混币,攻击者与部分验证节点存在潜在关联。
事后分析:安全审计发现攻击者利用 Safe 前端的供应链漏洞植入恶意脚本。
攻击为什么发生
黑客利用作恶的前端代码使 bybit 多签钱包的签名者确信这是一笔合法交易(例如例行的 token 转账),结果实际上诱导他们对非法交易进行签名,为了阻止签名者通过其他手段发现交易内容有问题,黑客甚至把这次攻击伪造成一笔 transfer 交易,让 bybit 的签名者尽量不通过其他方式检查交易 calldata. (通常把交易内容叫做 calldata)
简而言之攻击方式是这样的:
黑客获得 Safe 前端的开发者权限,修改了前端代码,植入了针对 bybit 攻击的恶意脚本;
bybit 多签成员访问了被污染的网页,看到了假的交易信息:
他们看到的页面: 转账 100 ETH 到地址 A
实际要求签名的是: 修改冷钱包逻辑
这就像一个偷换了显示屏的 ATM 机,屏幕显示取 100 元,实际操作却是取 100 万元。
官方 APP —— 用户的信任盲区
用户认知中的多签交易流程很简单:看到交易 → 签名 → 提交上链,但实际上隐含着一层关键的分离:
用户看到的交易
实际签名的交易
而使用官方 app 会让用户的警惕心理极大降低,以至于忽略掉这一层分离。如果官方 app 页面被攻击了,会导致用户的签名是真实的,他们只是不知道自己在此时究竟签了什么内容。
这时如果可以有独立渠道验证签名内容的真实性,就可以极大程度地杜绝前端攻击带来的风险。这就是区块链所提倡的: Dont trust it, VERIFY it.
「独立渠道验证」的理论基石
我们先来看 Safe 合约的工作原理(截至目前,Safe 合约还是足够安全的):
先把交易内容计算出一个哈希值(类似于生成交易的“指纹”)
用私钥对这个哈希值进行签名
当收集到足够数量的签名后,提交把交易原文和这些签名提交到链上
链上重新根据原文计算哈希值,并验证这些签名是否有效,收集足够的有效交易则执行,否则则拒绝。
哈希和签名的安全和难伪造的属性是区块链 work 的两大基石,不用怀疑。
因此,如果有独立渠道可以在交易被提交上链之前,可以得到交易原文以及签名,就可以验证「用户签名的交易到底是什么」以及「用户是不是对这笔交易进行的签名」。
因此,即使前端或后端被攻击,最坏的情况只是返回错误数据,而错误数据在「独立渠道」会产生以下几种情况:
错误交易原文,错误签名——用户拒绝发送交易上链
错误交易原文,有效签名——用户拒绝发送交易上链
错误交易原文,错误签名——用户拒绝发送交易上链
我们可以看到最坏的情况也只是这笔交易不会被发送上链,除此之外,不会造成任何的链上损失。所以针对类似这种「显示攻击」最好的方式就是多渠道验证,这也符合区块链的精神:dont trust it, VERIFY it.
现有的解决方案
多个多签产品相互验证
目前市场上有很多 safe-compatible 的多签产品,例如 Safe 自己就部署了两版独立的前端页面:
https://eternalsafe.vercel.app/welcome/
https://eternalsafe.eth.limo/welcome/
用户在对一笔多签交易签名之后,自己或者后续的签名者登录到另一个多签产品的页面中,再次查看交易原文,如果不同多签产品显示完全相同的交易内容解析,则可以相信「自己要签名的交易内容」是正确的。
但是这需要不同的多签产品都在使用{Safe}的后端存储链下交易和签名数据并且也会把自己收集到的签名数据发送给{Safe}后端,这对产品之间的协作要求非常苛刻;而且 Safe 对一些不常规交易的原文解析并不友好,就算多个 Safe 前端显示了同样的 calldata,但是如果只是一串没有意义0x abcdefsf,也会让签名者望而却步。
注:目前 Safe 提供的两个独立的替代网站均需自己提供 RPC 链接:
独立的 Safe 交易验证工具
对于 Safe 前端攻击事件,社区的反应也很快,我们在 Safe 官方的 telegram 群里发现已经有人提供了独立的 Safe 交易解析工具,这种方式看起来更加简单直接。
我们也对这个工具进行的验证。如图,只需要把 safe 页面里的交易分享链接粘贴进来,就可以自动读取 Safe 后端数据,并独立验证交易原文的哈希值和签名的正确性,简而言之如果确定图中的 calldata 解析是自己想要的交易,并且「SafeHash Check」和「Signature Check」验证通过,就可以认为「这是自己想发送的交易」并且「自己已经正确签名」了。
当然为了保险起见,也要再仔细核对Safe Address, 通过签名解析出的签名者地址、交互的合约地址以及操作类型是 Call 还是 Delegatecall,例如 bybit 这次被攻击的交易就是 delegatecall 和 transfer 同时出现,一个稍有经验的开发者都会知道这样的组合非常奇怪。
如果遇到不可读的交易信息:
可以点击 Decode,提供该交易方法的 ABI,如:
就可以展示可读的交易信息:
Stay Safe - VERIFY, not trust
Bybit 的多签攻击再次提醒我们,前端信任并不等于交易安全。即便使用的是官方应用,交易内容依然可能被篡改,签名者必须有独立的方式来验证自己签署的内容。
不要轻信,务必验证(Don’t trust it, VERIFY it.)是 Web3 安全的核心原则。希望未来 Safe 生态和更多多签产品能加强独立验签机制,避免类似攻击再次发生。