零时科技 || 深入 Bybit 攻击事件 Part1 - 关于 Safe{Wallet}
2025-04-15 17:08
零时科技
2025-04-15 17:08
订阅此专栏
收藏此文章


背景介绍


2025 年 2 ⽉ 21 ⽇晚,我们监测到⼀笔涉及 Bybit 交易所的重⼤安全事件。当晚 02:16 UTC ,我们监测到 Bybit Cold Wallet 发起⼀笔⼤额转账:

https://etherscan.io/tx/0xb61413c495fdad6114a7aa863a00b2e3c28945979a10885b12b30316ea9f072c ,

转出 401,346 ETH 价值约 1.5 BillionUSD 。经过多⽅确认,确定这是⼀起针对 Bybit 的攻击。



关于 Safe{Wallet}


经过多⽅的分析和调查,整个事件的⼤致流程已经比较清晰。攻击者⾸先利⽤钓⻥的⼿段,攻击了 Safe{Wallet} 和核⼼开发者,窃取到了 AWS 的 CloudFront 或者 S3 的 Access Key 。随后,利⽤ Access Key 向 Safe{Wallet} 的前端注入恶意代码。恰好,受影响时, Safe{Walllet} 被 archive.org 的 Wayback Machine 收录。具 Wayback Machine 显⽰, Safe{Wallet} 的前端代码在 2025 年 2 ⽉ 19 ⽇ 17:28:33 已经被注入恶意代码。



恶意代码出现在前端 js ⽂件 _app-52c9031bfa03da47.js 中,



我们讲其中恶意代码的核⼼逻辑取出,如下:



整个逻辑比较简单,当 sd.getAddress() 即 Safe 钱包的地址在["0x1db92e2eebc8e0c075a02bea49a2935bcd2dfcf4","0x19c6876e978d9f128147439ac4cd9ea2582cd141"] 中,

则将 to 地址设置为: 0x96221423681a6d52e184d440a8efcebb105c7242 ,

data 设置为:0xa9059cbb000000000000000000000000bdd077f651ebe7f7b3ce16fe5f2b025be29695160000000000000000000000000000000000000000000000000000000000000000 ,然后调⽤ executeTransaction 签名交易。

其中,恶意的 js 代码中: 0x1db92e2eebc8e0c075a02bea49a2935bcd2dfcf4 ,

这个钱包地址就是 Bybit 失窃的多签冷钱包地址。也就是说,攻击者的恶意代码是针对 Bybit 的冷钱包进⾏定向攻击,这样做的好处是尽量减少被发现的⼏率。防⽌其他⽤户注意到。其中 to 地址也就是 Safe 钱包即将调⽤的合约地址为 0x96221423681a6d52e184d440a8efcebb105c7242 ,这个智能合约未开源,经过反编译发现合约功能很简单,仅仅实现了⼀个 transfer 函数,函数的功能是将合约的 slot0 改为 recipient 地址。



se.data.data 就是调⽤上述合约的 calldata ,其中前四个字节为 0xa9059cbb ,就是 transfer(address recipient, uint256value) 的签名。后续的参数分别为 recipient 为: 0xbdd077f651ebe7f7b3ce16fe5f2b025be2969516 ,value 为 0 。因为, Bybit 钱包使⽤的 Safe{Wallet} 版本为 1.1.1 ,改版本的钱包执⾏合约调⽤的逻辑为 MultiSig Address-[Signature]->Wallet MasterCopy Proxy-[Delegatecall]->Safe Wallet Logic Contract-[Delegatecall | calldata]->TargetContract Address ,所以实际上修改的是 Wallet MasterCopy Proxy 的 slot0 ,也就是正式接管了该钱包。

恶意代码中,其中的另⼀个地址: 0x19c6876e978d9f128147439ac4cd9ea2582cd141,是攻击者⽤来测试攻击流程的测试地址。也就是说,改恶意代码会劫持两个钱包,钱包 1 为 Bybit 的 Cold Wallet ,钱包 2 为攻击者的测试钱包。由于 Bybit Cold Wallet 的代码版本为 1.1.1 ,所以攻击者同样创建了⼀个 1.1.1 版本的 Safe 钱包,创建的交易为:https://etherscan.io/tx/0x8df9884dd022f900ea7ebcbd0d47356137e3dcc8032e36d8706bed86f158f7c8 ,由于 Safe 的 App 已经⽆法创建老版本的钱包,攻击者是如何创建的呢?

我们看到,攻击者是调⽤ Proxy Factory 1.1.1 的 createProxyWithNonce 来创建的在 Ethereum mainnet 上测试钱包



于是,我们在 Sepolia 测试链上同样利⽤ createProxyWithNonce 创建了⼀个 Safe 钱包, version 为 1.1.1 。我们的创建交易为 https://sepolia.etherscan.io/tx/0xa7ce1ce4cb5ccb65eb9a35842ebde8f9a161dd561bce80528dbb7362efc33ff0 ,创建的钱包地址为:0xfdfd440e9d920a8a577eb3d586547986b889ad56。

但是,我们创建的钱包地址却⽆法导入到 Safe 的 app 中。



我们可以看到 Safe 创建 Multisig wallet 的代码如下:



由于 Safe 创建 Wallet 使⽤ create2 来创建 proxy := create2(0x0, add(0x20, deploymentData), mload(deploymentData),salt) ,所以只需要保证 MasterCopy , initializer , saltNonce ⼀直,就可以创建相同地址的钱包。于是,我们利⽤和攻击者同样的参数,在 Sepolia 测试链上创建了与攻击者在 Ethereum mainnet 上相同的地址 0x19c6876e978d9f128147439ac4cd9ea2582cd141 ,创建交易为 https://sepolia.etherscan.io/tx/0x3ec6ef599d1df75c9f255f4c1a0edaed8ef992a4fd6ea90af50a05ca962c9e69 ,但是该地址仍⽆法导入 Safe 的 app 中。



⽽攻击者在 Ethereum mainnet 上创建的地址即可成功导入到 Safe app 中,



随后,我们在官⽅的⽂档中发现,Safe 钱包在 L1 上使⽤ trace-base 来索引创建好的钱包,https://github.com/safe-global/safedocs/blob/f487ace5e0221437277bd9d56fb340794dda424c/pages/advanced/cli-guides/recovery-safe-deployment.mdx#L42



理论上,所有通过 Factory 创建的钱包都可以使⽤ Safe app,因为攻击者篡改了 Safe app 的前端代码,导致只有使⽤ Safe app 才会收到攻击。但是,我们通过 Factory 1.1.1 创建的 Safe 钱包始终⽆法被索引,所以也⽆法测试。我们也不知道为何攻击者创建的钱包可以被 Safe 索引。




关于安全


由于 Bybit 使⽤的 Safe{Wallet}版本为 1.1.1 比较老,⽬前最新的版本 1.4.0 对于本次攻击的攻击⼿法(利⽤修改 slot0 来接管钱包)已经失效了



我们可以看到,此处已经由 delegatecall 变为了 call ,也就意味着只能修改被调⽤合约本⾝的 slot ,⽆法修改 proxy 的 slot 。但是,后续还需防范类似的攻击⼿段,攻击者可能直接构建转移资产的交易,因此,我们建议在签名交易前,先使⽤ Safe 内置的 Tenderly 对交易进⾏模拟后,确认⽆误再进⾏签名。





若需了解更多产品信息或有相关业务需求,可扫码关注公众号或移步至官网:


微信号noneage

官方网址https://noneage.com/





推荐阅读

REVIEW




END





点击阅读全文 立刻直达官网

     /www.noneage.com/    


【免责声明】市场有风险,投资需谨慎。本文不构成投资建议,用户应考虑本文中的任何意见、观点或结论是否符合其特定状况。据此投资,责任自负。

零时科技
数据请求中
查看更多

推荐专栏

数据请求中
在 App 打开