2025年2月21日,在一名攻击者通过社交工程手段入侵了Safe{Wallet}开发人员的机器后,Bybit损失了约15亿美元。攻击者向Safe{Wallet}的AWS S3存储桶注入了恶意JavaScript,专门针对Bybit的交易。注入的代码在签名过程中篡改了交易内容:Safe{Wallet}的用户界面显示了一笔合法的交易,而实际发送给签名者Ledger设备的数据包则将Bybit的Safe合约升级到一个恶意实现,使攻击者获得了完全控制权。一旦签名并执行,攻击者就耗尽了合约中的所有资产。详细的技术分析请参阅我们之前的报告[1, 2]。
背景
Safe{Wallet}(又称GnosisSafe)是一种采用n-of-m模式的多重签名钱包基础设施:执行一笔交易需要至少n个签名,总共有m个签名者。
每个Safe钱包都被部署为一个代理合约。有两个存储变量是本次事件的核心:
masterCopy(槽位0):实现合约的地址。该合约包含所有执行逻辑,包括签名验证和升级机制。代理通过delegatecall将所有调用委托给masterCopy。threshold(槽位4):所需的最小签名数(n)。对于Bybit的Safe,这个数字是3。
由于代理使用delegatecall,在masterCopy上调用的任何函数都在代理的存储上下文中执行。这意味着delegatecall的目标可以直接覆盖槽位0的masterCopy,在一笔交易中替换整个实现。
漏洞分析
攻击路径跨越了系统的三个层面,每个层面都呈现出攻击者利用的结构性条件:
前端服务模式。 Safe{Wallet}的前端JavaScript是从AWS S3存储桶提供的。在这种架构中,任何拥有该存储桶写入权限的人都可以修改为签名者构建交易的代码。子资源完整性(SRI)哈希或代码签名等完整性验证机制可以减轻此风险,但它们对于大多数dApp前端而言尚未成为标准实践。攻击者通过被入侵的开发人员机器获得了写入权限,并悄悄修改了提供的JavaScript。
UI显示和签名数据之间的差异。 注入的JavaScript在Safe{Wallet}的用户界面上显示了一笔看起来合法的交易,同时向Ledger硬件钱包发送了不同的数据包。Ledger屏幕上显示的交易详情将与用户界面有所不同,但解读硬件钱包屏幕上的原始交易数据并非易事,尤其是对于复杂的多重签名操作。这种差异允许攻击者收集了三份针对恶意数据包的有效签名。
代理升级模式。 如背景中所述,delegatecall在代理的存储上下文中执行目标代码。Safe代理架构将所有调用路由到一个位于槽位0的masterCopy指针。覆盖此指针可以将代理定向到一个完全不同的实现,包括其签名验证逻辑,只需一笔交易。n-of-m模式决定了谁可以发起交易,但一旦交易被批准并执行,它就可以修改实现本身。如果新的实现移除了签名验证,那么对于所有后续交易,多重签名保护将实际上消失。
攻击分析
攻击分三个步骤进行:恶意代码注入,实现替换,以及资产盗窃。
步骤1:恶意代码注入
攻击者入侵了一台Safe{Wallet}开发人员的机器,并向提供前端的AWS S3存储桶注入了恶意JavaScript。注入的代码专门针对来自Bybit Safe地址的交易。根据Bybit首席执行官Ben Zhou的说法[2],Safe{Wallet}的用户界面显示了一笔合法的交易,而不同的数据包被发送到了签名者的Ledger设备。签名者批准了用户界面上显示的交易,使攻击者获得了三份针对恶意数据包的有效签名。
步骤2:实现替换
攻击者提交了带有这三个收集到的签名的恶意交易。Safe代理将调用委托给了masterCopy,其execTransaction()验证了签名,然后执行了交易数据包:一个delegatecall到攻击者的合约(0x962214...5c7242)。由于此delegatecall在代理的存储上下文中运行,攻击者的transfer()函数在槽位0处覆盖了masterCopy的值,替换为恶意实现地址(0xbDd077...9516)。从这时起,所有对Safe合约的调用都被委托给攻击者的代码。
步骤3:资产盗窃
现在masterCopy指向攻击者的实现后,多重签名要求不再适用。攻击者直接在Safe合约上调用了SweepERC20()和SweepETH()。这些函数定义在攻击者的实现合约中,在没有任何签名验证的情况下转移了所有持有的资产。执行了五笔耗尽交易,总计损失约15亿美元。
相关合约和交易
| 类型 | 描述 | 地址/哈希 |
|---|---|---|
| 合约 | Bybit的Safe合约 | 0x1Db92e2EeBC8E0c075a02BeA49a2935BcD2dFCF4 |
| 合约 | 原始的masterCopy合约 | 0x34CfAC646f301356fAa8B21e94227e3583Fe3F5F |
| 合约 | 恶意的masterCopy合约 | 0xbDd077f651EBe7f7b3cE16fe5F2b025BE2969516 |
| 合约 | 攻击者的合约(即transfer()) | 0x96221423681A6d52E184D440a8eFCEbB105C7242 |
| 交易 | 替换masterCopy合约的交易 | 0x46deef0f52e3a983b67abf4714448a41dd7ffd6d32d32da69d62081c68ad7882 |
| 交易 | 耗尽15,000 cmETH的交易 | 0x847b8403e8a4816a4de1e63db321705cdb6f998fb01ab58f653b863fda988647 |
| 交易 | 耗尽90,375 stETH的交易 | 0xa284a1bc4c7e0379c924c73fcea1067068635507254b03ebbbd3f4e222c1fae0 |
| 交易 | 耗尽8,000 mETH的交易 | 0xbcf316f5835362b7f1586215173cc8b294f5499c60c029a3de6318bf25ca7b20 |
| 交易 | 耗尽401,346 ETH的交易 | 0xb61413c495fdad6114a7aa863a00b2e3c28945979a10885b12b30316ea9f072c |
| 交易 | 耗尽90 USDT的交易 | 0x25800d105db4f21908d646a7a3db849343737c5fba0bc5701f782bf0e75217c9 |
总结
此次事件表明,Web2基础设施的妥协如何能够级联引发灾难性的链上损失。攻击者将一次Web2漏洞、前端操纵和代理升级串联成一条单一的攻击路径,绕过了多重签名保护,而没有利用任何链上漏洞。
关键教训:
- 前端的完整性值得与链上安全同等的关注。 攻击链始于前端服务层。随着dApp越来越多地处理高价值交易,使用完整性验证(SRI、代码签名、可复现构建)保护前端代码并监控未经授权的更改,已成为一项基本要求。
- 硬件钱包验证在实践中仍然困难。 硬件钱包可以显示实际的签名数据包,但要解读小型屏幕上复杂的多重签名交易数据,是一个已知的可用性挑战。提高设备上交易摘要的可读性,是钱包生态系统中一个尚未解决的问题。
- 代理升级机制是高杠杆目标。 Safe代理架构将所有逻辑通过一个单一的可升级指针进行路由。任何允许一步到位实现替换的机制都会集中风险。添加一个时间锁、二次确认步骤或独立的守护者来进行升级,可以降低单次被入侵交易的影响。
参考
关于BlockSec
BlockSec是一家提供全栈式区块链安全和加密合规服务的公司。我们构建产品和服务,帮助客户在协议和平台的整个生命周期内进行代码审计(包括智能合约、区块链和钱包)、实时拦截攻击、分析事件、追踪非法资金,并满足AML/CFT义务。
BlockSec曾在顶尖会议上发表多篇区块链安全论文,报告了数起DeFi应用的零日攻击,拦截了多次黑客攻击挽回了超过2000万美元的损失,并保障了数十亿美元的加密货币安全。
-
官方Twitter账号:https://twitter.com/BlockSecTeam



