Security
The Bybit $1.5B Hack of February 2025: A Forensic Engineering Postmortem
The Bybit hack was a Safe{Wallet} supply chain compromise, not a crypto key leak. UI-layer spoofing defeated hardware wallets. The architectural controls that would have stopped it.
On February 21, 2025, Bybit lost 500M+ in contributor funds across multiple launches - specifically working on the controls designed to prevent this class of attack - the forensic picture was professionally devastating.
Every control Bybit had in place was the correct control for the threat model they understood. Multisig. Hardware wallets. A reputable third-party signing interface. The attack worked because it operated above all of those controls, at the UI layer, where no cryptographic primitive can help you.
This is the postmortem I wish the industry had written.
The Attack Chain
The reconstruction from on-chain forensics, Safe{Wallet}‘s post-incident report, and Chainalysis’s TraderTraitor attribution:
Step 1: Developer machine compromise. A developer working on Safe{Wallet} (formerly Gnosis Safe) - the multisig interface Bybit used - had their development machine compromised. The compromise vector is assessed with high confidence to be a supply-chain attack: a malicious dependency injected into the developer’s npm package tree, likely through a typosquatting attack or a compromised package maintained by the developer. The malware established persistence on the developer’s macOS machine.
Step 2: AWS S3 injection. Safe{Wallet}‘s web application is served from AWS S3/CloudFront. The compromised developer had deployment credentials to the Safe{Wallet} S3 bucket (standard for a developer working on the frontend). The malware or the attacker using the compromised machine injected modified JavaScript into the live S3 bucket. The modification was surgical: the JavaScript behaved normally for all wallet interactions except those involving Bybit’s specific signing keys.
Step 3: Transaction payload substitution. When Bybit’s signers loaded the Safe{Wallet} interface to authorize what appeared to be a routine cold-to-warm transfer of ~$1.5B in ETH, the modified JavaScript showed them the legitimate transaction - correct recipient, correct amount, correct everything visible in the UI. But the actual transaction being constructed and sent to the Ledger hardware wallet for signing had a different payload: it was a delegate call that changed the Safe’s implementation contract, replacing the multisig logic with a backdoor that allowed a single attacker-controlled address to drain all funds.
Step 4: Hardware wallet signing. Bybit’s signers were using Ledger hardware wallets, which are specifically designed to prevent malware from causing fraudulent transactions. The Ledger showed the raw transaction data for approval. But the raw data showed an execTransaction call to the Safe contract - which looked like a routine multisig execution. The critical detail that would reveal the attack - that the data field contained a delegatecall to change the Safe’s implementation - was not clearly displayed on the Ledger’s small screen. The signers approved.
Step 5: Drain. Once the implementation contract was changed, the attacker’s single address could call the new implementation to transfer any funds from the Safe. The $1.5B in stETH was moved to multiple intermediary addresses, then converted to ETH and distributed across hundreds of addresses - the standard Lazarus Group laundering pattern documented by Chainalysis.
Why Multisig + Hardware Wallets Were Not Sufficient
This is the question every custody engineer must answer honestly.
Multisig (N-of-M threshold signatures) protects against a single signer being compromised. If 3-of-5 signers are required, an attacker would need to compromise 3 independent people or machines simultaneously. This is hard for most attackers.
Hardware wallets protect against malware on the signing computer substituting a different transaction than the one the signer intends to authorize. The private key never leaves the hardware device; the malware can see what the user approves but cannot approve something different.
The Bybit attack bypassed both controls simultaneously by operating at a layer above both: the user interface presentation layer. The hardware wallet signed exactly what it was shown. The multisig executed because the required number of signers approved. Both controls functioned perfectly. The attack substituted what was shown to the users, not what the cryptographic primitives received.
The countermeasures that would have caught this attack:
-
Independent transaction simulation: before presenting to signers, simulate the transaction against a forked mainnet state and display the simulation results - “this transaction will: change the Safe implementation contract to address 0x…” If the simulation shows a storage write to the implementation slot that is not expected, alert and refuse to present for signing.
-
On-chain state verification in the UI: independently verify (via a different RPC endpoint, preferably one the signing interface does not control) that the contract state matches expectations before and after the proposed transaction. If the proposed transaction would change
implementationin the Safe’s proxy storage, flag it as an extraordinary operation requiring additional verification. -
Hardware wallet display verification: Ledger’s “blind signing” (approving a transaction based on hash rather than decoded content) is the specific failure point. Using a hardware wallet that can decode and display EVM function calls - and requiring signers to confirm the decoded function call matches the business intent - would have caught this. Ledger’s newer firmware shows
delegatecallwarnings, but many users disable this for operational convenience. -
TEE-based policy engine: a hardware-attested policy engine that independently receives the raw transaction payload and verifies it against a rule set - “cold wallet transactions may only transfer ETH to whitelisted addresses and may not call
upgradeTo” - would reject this transaction before it reaches the signers.
The On-Chain Forensics
The attacker’s address 0x47666... received the first transfer at block 21,893,543 at 14:03:30 UTC on February 21, 2025. Within the first 4 hours:
- 499,000 ETH split into 8 intermediary addresses
- Intermediary funds further split into 40+ addresses
- Conversion from stETH to ETH via Curve finance and Lido
- Early hop distribution consistent with prior Lazarus Group patterns (cross-referenced against Chainalysis TraderTraitor attribution)
The laundering pattern attempted to exploit exchanges with limited on-chain monitoring. Several exchanges froze funds successfully - Binance, Bitget, and MEXC together froze approximately $24M. The remainder moved to Tornado Cash-style mixing and eventually to OTC desk networks with limited KYC.
Chainalysis’s attribution to the DPRK-linked TraderTraitor group was based on:
- On-chain graph patterns matching prior Lazarus operations (Ronin Bridge 100M)
- Infrastructure reuse: intermediary smart contracts with code patterns from previous operations
- Timing correlation with known TraderTraitor campaigns targeting crypto developers
What Would Have Caught This Attack
The architecture I would implement today, informed by this attack:
Signing Flow with Defense-in-Depth:
Operator creates transaction in business system
↓
Policy Engine (TEE-attested) receives raw transaction
├── Verifies destination against whitelist
├── Verifies no storage writes to implementation/owner slots
├── Simulates transaction on forked state
├── Checks simulation output against business intent
└── If PASS: produces attestation document
↓
Signing interface receives transaction + attestation
├── Verifies attestation (rejects if TEE not attested)
├── Shows decoded transaction (not just hash)
└── Shows simulation results
↓
Hardware wallet displays:
├── Function: transferETH (NOT delegatecall/upgradeTo)
├── Destination: 0xabc... (whitelisted cold→warm address)
├── Amount: X ETH
└── Warning: NONE
↓
Signer approves ← Only here is human judgement required
↓
On-chain execution
The TEE policy engine is the key addition. It independently receives the raw transaction bytes from the business system (not from the signing interface frontend) and verifies them against a policy that the signing frontend cannot modify. Even if the signing frontend is completely compromised, a transaction that fails policy cannot reach the hardware wallet for signing.
Bybit’s Recovery
Bybit’s response was notable for its speed and competence given the scale:
- Trading operations continued without interruption (hot wallet assets were unaffected)
- Emergency bridge loan arranged within 24 hours ($900M from undisclosed lenders)
- solvency maintained throughout (total assets 1.5B loss was painful but not fatal)
- On-chain investigation published within 48 hours
- Safe{Wallet} suspension and audit announced within 72 hours
The response demonstrated institutional resilience. Most exchanges would not have survived a $1.5B theft operationally. Bybit’s warm-cold wallet tiering - which kept trading operations funded independently of the cold wallet - was the critical factor. If hot and warm wallets had been co-mingled with the cold wallet in the same Safe, the attack could have been total.
How This Breaks for Other Teams
Failure 1: Trusting the signing interface’s display. Multisig signing interfaces (Safe, Fireblocks, BitGo) all have this attack surface: the interface renders what it chooses to render, not necessarily the underlying transaction. Any signing workflow where humans approve based on UI display without independent transaction verification is vulnerable. Fix: implement independent transaction simulation. Never approve based on UI alone.
Failure 2: Developer credentials to production S3 bucket. Bybit’s specific attack vector was a developer with write access to the production CDN bucket. This is a standard development practice that created a critical vulnerability. Fix: separate production deployment from development credentials. Production deployments should require a signed artifact from a CI/CD pipeline with known provenance - no individual developer should have direct production write access.
Failure 3: Safe implementation contract upgrades not flagged as extraordinary. The Safe proxy pattern allows the implementation contract to be changed, which is how the backdoor was installed. An implementation change should be as rare as a key ceremony - not something that can happen through a routine execTransaction. Fix: add a governance rule that implementation changes require a separate, explicitly flagged approval process with a higher threshold and a time lock.
Failure 4: Single signing interface for all operations. Bybit used Safe{Wallet}‘s web interface as their sole signing path. A compromised web interface therefore affected all signers. Fix: require at least one signer to use an independently-built verification tool (command-line based, preferably, with a different codebase than the web interface) to verify the raw transaction before approving.
Failure 5: No independent transaction simulation before signer display. The missing control. If the Safe{Wallet} backend had run a mainnet fork simulation and detected the storage write to the implementation slot, it could have refused to display the transaction. Fix: integrate Tenderly, Hardhat fork, or a custom simulation layer before any transaction is presented to signers.
Failure 6: Ledger blind signing enabled. Some Bybit signers reportedly had blind signing enabled, which shows only the transaction hash rather than decoded content. Blind signing exists for operational convenience with complex transactions that the hardware wallet cannot decode. It eliminates the hardware wallet’s primary security benefit. Fix: prohibit blind signing in your custody policy. If the hardware wallet cannot decode the transaction, the transaction should not be approved.
Related reading: The DPRK Threat Model covers TraderTraitor’s full attack playbook. Hot-Warm-Cold Wallet Tiering covers the wallet architecture that prevented Bybit’s loss from being total. AWS Nitro Enclaves for Wallet Signing covers the TEE policy engine architecture that would have blocked this specific attack vector.
Continue Reading
Enjoyed this?
Get one deep infrastructure insight per week.
Free forever. Unsubscribe anytime.
You're in. Check your inbox.