바이비트(Bybit)最近遭受了一起涉及15亿美元的黑客攻击,此事件引发了区块链安全社群的广泛关注。黑客成功渗透了Bybit的多重签名冷钱包,并通过某种方式篡改或利用既有的安全机制,将大额资产转移至不明地址。
这次攻击不仅对Bybit造成了巨大的财务损失,也对多重签名钱包的安全性提出了新的挑战。本文由BSOS Labs区块链安全研究员撰写,将深入剖析该攻击事件的技术细节,包括Bybit所使用的多重签名架构、攻击者的手法,以及此次事件带来的安全启示。
事件背景
多重签名钱包
在以太坊的区块链设计中,有两种类型的账号,一个是EOA账户(Externally Owned Account),另一种是合约账户(Contract Account),Bybit在这次事件中用来进行资产管理的多重签名冷钱包,就属于后者。这个钱包其实是一份智能合约,通过程序来自定义一些商业逻辑。在多重签名账户的设计中,当这个钱包收到外部传进来的资产后,如果想要进行提取或是任何使用上的操作,则必须要通过这个多重签名钱包所设定的一些门槛,才能够实际执行。
一般用户可以把Safe Wallet想象成是一个公司的金库,而这座金库内由公司的董事们共同进行管理,当公司董事想要提取金库资产时,或是利用这些资产去进行外部投资时,他们必须要先通过以下的流程:
- 董事会内部先提案,决定未来要使用的资金金额,目标以及要执行的操作
- 董事会的成员针对这个提案进行签署,当签署人数超过门槛数值,才能实际执行
举例来说,一个5取3的多重签名钱包,总共会有5个董事,我们称之为Signer,这些Signer可以首先发起提案,提案对应多重签名钱包的名词是Transaction,也有一派说法是Proposal,避免与区块链的transaction混淆。
而这个提案可以是简单的转送ETH/ERC-20到其他账户,也可以是进行一些较为复杂的DeFi操作。接下来这些Signer针对这些Proposal进行签署,表示同意这份提案,过程中会产生一个Signature做为凭证。当有效的Signature数量大于3后,用户可以呼叫Safe Wallet的executeTransaction操作并且提交这些Signature,当验证完这些Signature确实是由认证的Signer,也就是该金库的董事们签署之后,就会实际的去执行当初Proposal的内容。

简单的流程如上图所示,首先有Signer 0去提交一份Proposal,然后由Signer 2, 3确认过Proposal没有问题之后进行签署,通常提交Proposal的人会同时进行签署,所以此时已经拿到3个signature,符合这个多重签名钱包设定的门槛。这时就可以执行这份Proposal的内容,在Safe前端的设计,如果你签署的时候刚好符合门槛,系统会询问你是否要签署后一起执行,你可以选择Yes,或是选择No,然后让别人来帮你执行,差别则是在谁来付这个gas的费用。
代理模式
以上是透过Safe Wallet的介绍来初步了解多重签名钱包的运作,我们接着看Safe的合约设计。上述所提到的逻辑,有很大一部分是写在该智能合约中的,有兴趣的话,可以参考Safe Wallet的主合约实现:https://etherscan.io/address/0x34cfac646f301356faa8b21e94227e3583fe3f5f#code
这份合约并不复杂,程序的数量也没有很大,但是如果每次要创建Safe钱包时,都必须要部署一份这样的合约,是非常消耗Gas的,所以Safe采用了代理模式来降低成本。要注意的是,这里是指代理模式而非可升级代理,与常见的透明代理和UUPS代理不太一样,这里没有预设升级的行为。具体的运作原理比较像EIP-1167中的最小代理。

当每次用户创建Safe钱包时,一份代理就会被创建,这份代理的程序非常精简,基本上只会利用Delegatecall呼叫主合约,呼叫的数据则是用户和代理互动时的data。所有的商业逻辑都在主合约0x34Cf…3F5F之中,但是因为Delegatecall的特性,每份代理的状态(如token balance等)是分离的,如上图。这样的设计,不会因为只有单一一份主合约而造成大家资产混在一起。
简单来说,这个代理通过Delegatecall呼叫主合约,使用主合约的商业逻辑来修改自己代理本身的状态,例如token transfer等操作。
在Bybit的事件中,一样有代理和主合约两个地址,都是在以太坊主网区块链上。
- 프록시: 0x1Db92e2EeBC8E0c075a02BeA49a2935BcD2dFCF4
- 세이프 월렛: 0x34CfAC646f301356fAa8B21e94227e3583Fe3F5F
이더리움(ETH) 프록시의 코드를 살펴보면 masterCopy
주소 변수(L#14)가 있는데, 이 값은 계약 생성 시(L#18의 Constructor
) 한 번 설정됩니다. 초기값은 메인 계약 0x34Cf…3F5F이며, function()
(L#26)은 사용자가 보낸 데이터를 어셈블리 블록의 delegatecall
(L#39)을 통해 메인 계약으로 전송합니다.
메인 계약의 execTransaction
구현을 보면 다음과 같은 중요한 매개변수가 있습니다:
to
: 다중 서명 상호작용 계약 주소value
: 전송할 이더리움(ETH) 양data
:to
주소에 호출할 때 전송할 데이터operation
: 다양한 작업 모드,Safe
에서는call
과delegatecall
을 지원signature
: 각 서명자가 서명한 서명
이번 공격과 관련하여, Bybit CEO는 다중 서명 지갑의 제안을 서명할 때 냉장 지갑의 자산을 핫 지갑으로 이체하려 했다고 합니다. 그러나 실제 실행된 트랜잭션을 살펴보면 value
가 0이고 data
가 null이 아닌 것을 확인할 수 있습니다. 이는 일반적인 이더리움(ETH) 전송이 아니라 WETH 또는 stETH와 같은 ERC20 토큰 전송일 가능성을 시사합니다.
데이터의 처음 4바이트는 함수 선택기를 나타내며, 이를 통해 실행되는 작업을 파악할 수 있습니다. 이 경우 0xa9059cbb
는 ERC20 transfer
작업을 나타냅니다. 그러나 이 작업은 call
(Operation = 0)이 아닌 delegatecall
(Operation = 1)을 사용하고 있습니다. 이는 프록시 계약이 악성 계약 0x9622…C7242의 로직을 사용하여 프록시 자체의 상태를 변경하려는 것으로 보입니다.
결과적으로 악성 계약은 프록시 계약의 masterCopy
변수를 변경하여, 향후 서명자가 프록시 계약을 호출할 때 실제로 실행되는 것이 Safe의 메인 계약이 아닌 새로 설정된 주소가 되도록 하는 것입니다.

계속해서 0xbDd0…9516 계약을 역추적해 보면 두 가지 작업을 볼 수 있습니다. 하나는 L#18에서 ETH를 receiver 주소로 전송하는 sweepETH 함수입니다.

그리고 SweepERC20은 L#35에서 ERC-20 토큰을 모두 한 번에 전송하는 작업을 수행합니다.

따라서 바이비트(Bybit) 내부에서 실수로 execTransaction을 통해 MasterCopy 주소를 업데이트한 후, 이후의 sweepERC20과 sweepETH 작업이 이루어진 것으로 보입니다. 이러한 트랜잭션이 실제로 자산을 전송한 것입니다.

Blind Signing
따라서 이번 사건의 근본 원인은 바이비트(Bybit)가 다중 서명 지갑 서명 시 Safe의 값을 확인하지 않았기 때문인가요? 당시 Operation 값과 다른 중요한 주소 정보를 검증했다면 비정상적인 작업을 조기에 식별하고 이번 공격을 막을 수 있었을까요?
이번 사건에는 여전히 많은 의문점이 있습니다. 먼저 해당 다중 서명 제안은 누가 시작했는지, 다른 서명자들이 제안 내용을 자세히 확인했는지(Safe 프론트엔드 URL 등 중요 정보 포함), 혹시 서명자의 개인 키가 유출되어 전체 시스템이 심각한 보안 위험에 노출되었을 가능성은 없는지 등입니다.
바이비트(Bybit)에 따르면 공동 창립자이자 CEO인 Ben이 서명 과정에서 Safe 웹사이트 주소와 실제 매개변수 정보를 확인했다고 합니다. 그러나 콜드 월렛 서명 시 무작위 코드가 표시되었다는 것은 Safe 프론트엔드 웹사이트가 해커에 의해 변조되었을 수 있음을 의미합니다. 현재 Safe 측에서는 사건 경위를 더 명확히 하기 위해 프론트엔드 서비스를 일시적으로 중단했습니다.
다른 가능성은 바이비트(Bybit)의 컴퓨터가 침해되어 표시된 화면이 Safe 공식 인터페이스가 아닌 해커가 정교하게 위조한 페이지일 수 있다는 것입니다. 이러한 경우는 2024년 10월 16일 래디언트 캐피탈(Radiant Capital) 사건에서도 유사한 공격 방식이 있었습니다: Radiant Post-Mortem.
래디언트(Radiant)도 Safe 다중 서명 지갑을 사용했는데, 당시 3명의 선임 엔지니어가 하드웨어 콜드 월렛으로 서명했고 Tenderly를 통해 트랜잭션 결과를 시뮬레이션하는 등 엄격한 SOP에 따라 확인했습니다. 그러나 서명 및 실행 과정에서 MetaMask에 오류 메시지가 표시되어 재서명을 요구했습니다.
이러한 상황은 드물지 않습니다. 트랜잭션 실행 중 Nonce 또는 Gas 관련 문제로 인해 실패하는 경우가 많아 재실행이 필요합니다. 그러나 이러한 작업이 너무 일반적이어서 지갑에서 재서명 요청이 나오면 엔지니어들이 트랜잭션 내용을 다시 확인하지 않고 넘어가다 해커의 함정에 빠지게 된 것입니다.
어떻게 예방할 수 있을까요? 이러한 공격을 막을 수 없나요?
사실 이번 사건들에서 북한 해커들이 주로 이용한 것은 여전히 인간의 약점입니다. 우리는 이러한 작업에 익숙하다고 생각하여 함정에 빠지기 쉽습니다.
위험을 줄이기 위해서는 다중 서명 지갑 작업 환경을 다른 기기와 격리하고 매번 Payload를 세심하게 확인해야 합니다. Safe와 Ledger 간 정보에 이상이 있으면 즉시 작업을 중단하고 개인 키 보안을 확인해야 합니다.
일정한 SOP 프로세스를 수립하고 각 단계를 엄격히 준수하면 이러한 사건 발생을 효과적으로 예방할 수 있습니다.
결론
바이비트(Bybit) 사건으로 인해 Web3에 그림자가 드리워진 것 같지만, 이는 보안 부족과 높은 위험이라는 인식이 지속되고 있는 것 같습니다. 그러나 이러한 사건이 빈번하게 발생하면서 운영 보안에 더 큰 관심을 가지게 되고, 개인 키 관리와 서명에 대한 교육과 인식이 더욱 깊어질 것입니다.
과거를 돌이켜보면 2021년부터 2023년 사이에 해커 사건이 자주 발생했고, 몇 주 만에 수백만 달러 규모의 스마트 컨트랙트 취약점 손실이 있었습니다. 하지만 이를 통해 업계에서 보안 개발과 감사의 중요성을 점점 더 인식하게 되었고, 버그 바운티 제도도 더 명확해졌습니다. 실제 배포 후 모니터링 시스템도 점점 더 발전하고 있습니다.

따라서 이 글의 결론으로 우리는 미래 산업 발전에 대해 상대적으로 낙관적인 태도를 가질 수 있습니다. 이처럼 단순해 보이지만 큰 손실을 초래한 사건들은 산업이 점점 성숙해짐에 따라 점차 줄어들 것이며, 손실 규모도 감소할 것입니다.
본 글은 BSOS Labs 블록체인 보안 연구원이 작성했습니다. 저자는 국립 대만 대학교 컴퓨터 공학과 석사 학위를 보유하고 있으며, DeFiHackLabs의 보안 연구와 기여, Ocean Finance 스마트 컨트랙트 개발 경험이 있고, 블록체인 보안 분야의 bootcamp 강사로도 활동하고 있습니다.