Skip to content

Commit f8a85d8

Browse files
authored
Merge pull request #1740 from HackTricks-wiki/update_In-depth_technical_analysis_of_the_Bybit_hack_20260107_124809
In-depth technical analysis of the Bybit hack
2 parents c82b534 + 7e8eb21 commit f8a85d8

File tree

3 files changed

+84
-0
lines changed

3 files changed

+84
-0
lines changed

src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292
- [Defi Amm Virtual Balance Cache Exploitation](blockchain/blockchain-and-crypto-currencies/defi-amm-virtual-balance-cache-exploitation.md)
9393
- [Mutation Testing With Slither](blockchain/smart-contract-security/mutation-testing-with-slither.md)
9494
- [Value Centric Web3 Red Teaming](blockchain/blockchain-and-crypto-currencies/value-centric-web3-red-teaming.md)
95+
- [Web3 Signing Workflow Compromise Safe Delegatecall Proxy Takeover](blockchain/blockchain-and-crypto-currencies/web3-signing-workflow-compromise-safe-delegatecall-proxy-takeover.md)
9596
- [Lua Sandbox Escape](generic-methodologies-and-resources/lua/bypass-lua-sandboxes/README.md)
9697

9798
# 🧙‍♂️ Generic Hacking

src/blockchain/blockchain-and-crypto-currencies/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,14 @@ These practices and mechanisms are foundational for anyone looking to engage wit
186186
value-centric-web3-red-teaming.md
187187
{{#endref}}
188188

189+
## Web3 Signing Workflow Compromise
190+
191+
- Supply-chain tampering of wallet UIs can mutate EIP-712 payloads right before signing, harvesting valid signatures for delegatecall-based proxy takeovers (e.g., slot-0 overwrite of Safe masterCopy).
192+
193+
{{#ref}}
194+
web3-signing-workflow-compromise-safe-delegatecall-proxy-takeover.md
195+
{{#endref}}
196+
189197
## Smart Contract Security
190198

191199
- Mutation testing to find blind spots in test suites:
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Web3 Signing Workflow Compromise & Safe Delegatecall Proxy Takeover
2+
3+
{{#include ../../banners/hacktricks-training.md}}
4+
5+
## Overview
6+
7+
A cold-wallet theft chain combined a **supply-chain compromise of the Safe{Wallet} web UI** with an **on-chain delegatecall primitive that overwrote a proxy’s implementation pointer (slot 0)**. The key takeaways are:
8+
9+
- If a dApp can inject code into the signing path, it can make a signer produce a valid **EIP-712 signature over attacker-chosen fields** while restoring the original UI data so other signers remain unaware.
10+
- Safe proxies store `masterCopy` (implementation) at **storage slot 0**. A delegatecall to a contract that writes to slot 0 effectively “upgrades” the Safe to attacker logic, yielding full control of the wallet.
11+
12+
## Off-chain: Targeted signing mutation in Safe{Wallet}
13+
14+
A tampered Safe bundle (`_app-*.js`) selectively attacked specific Safe + signer addresses. The injected logic executed right before the signing call:
15+
16+
```javascript
17+
// Pseudocode of the malicious flow
18+
orig = structuredClone(tx.data);
19+
if (isVictimSafe && isVictimSigner && tx.data.operation === 0) {
20+
tx.data.to = attackerContract;
21+
tx.data.data = "0xa9059cbb..."; // ERC-20 transfer selector
22+
tx.data.operation = 1; // delegatecall
23+
tx.data.value = 0;
24+
tx.data.safeTxGas = 45746;
25+
const sig = await sdk.signTransaction(tx, safeVersion);
26+
sig.data = orig; // restore original before submission
27+
tx.data = orig;
28+
return sig;
29+
}
30+
```
31+
32+
### Attack properties
33+
- **Context-gated**: hard-coded allowlists for victim Safes/signers prevented noise and lowered detection.
34+
- **Last-moment mutation**: fields (`to`, `data`, `operation`, gas) were overwritten immediately before `signTransaction`, then reverted, so proposal payloads in the UI looked benign while signatures matched the attacker payload.
35+
- **EIP-712 opacity**: wallets showed structured data but did not decode nested calldata or highlight `operation = delegatecall`, making the mutated message effectively blind-signed.
36+
37+
### Gateway validation relevance
38+
Safe proposals are submitted to the **Safe Client Gateway**. Prior to hardened checks, the gateway could accept a proposal where `safeTxHash`/signature corresponded to different fields than the JSON body if the UI rewrote them post-signing. After the incident, the gateway now rejects proposals whose hash/signature do not match the submitted transaction. Similar server-side hash verification should be enforced on any signing-orchestration API.
39+
40+
## On-chain: Delegatecall proxy takeover via slot collision
41+
42+
Safe proxies keep `masterCopy` at **storage slot 0** and delegate all logic to it. Because Safe supports **`operation = 1` (delegatecall)**, any signed transaction can point to an arbitrary contract and execute its code in the proxy’s storage context.
43+
44+
An attacker contract mimicked an ERC-20 `transfer(address,uint256)` but instead wrote `_to` into slot 0:
45+
46+
```solidity
47+
// Decompiler view (storage slot 0 write)
48+
uint256 stor0; // slot 0
49+
function transfer(address _to, uint256 _value) external {
50+
stor0 = uint256(uint160(_to));
51+
}
52+
```
53+
54+
Execution path:
55+
1. Victims sign `execTransaction` with `operation = delegatecall`, `to = attackerContract`, `data = transfer(newImpl, 0)`.
56+
2. Safe masterCopy validates signatures over these parameters.
57+
3. Proxy delegatecalls into `attackerContract`; the `transfer` body writes slot 0.
58+
4. Slot 0 (`masterCopy`) now points to attacker-controlled logic → **full wallet takeover and fund drain**.
59+
60+
## Detection & hardening checklist
61+
62+
- **UI integrity**: pin JS assets / SRI; monitor bundle diffs; treat signing UI as part of the trust boundary.
63+
- **Sign-time validation**: hardware wallets with **EIP-712 clear-signing**; explicitly render `operation` and decode nested calldata. Reject signing when `operation = 1` unless policy allows it.
64+
- **Server-side hash checks**: gateways/services that relay proposals must recompute `safeTxHash` and validate signatures match the submitted fields.
65+
- **Policy/allowlists**: preflight rules for `to`, selectors, asset types, and disallow delegatecall except for vetted flows. Require an internal policy service before broadcasting fully signed transactions.
66+
- **Contract design**: avoid exposing arbitrary delegatecall in multisig/treasury wallets unless strictly necessary. Place upgrade pointers away from slot 0 or guard with explicit upgrade logic and access control.
67+
- **Monitoring**: alert on delegatecall executions from wallets holding treasury funds, and on proposals that change `operation` from typical `call` patterns.
68+
69+
## References
70+
71+
- [In-depth technical analysis of the Bybit hack (NCC Group)](https://www.nccgroup.com/research-blog/in-depth-technical-analysis-of-the-bybit-hack/)
72+
- [EIP-712](https://eips.ethereum.org/EIPS/eip-712)
73+
- [safe-client-gateway (GitHub)](https://github.com/safe-global/safe-client-gateway)
74+
75+
{{#include ../../banners/hacktricks-training.md}}

0 commit comments

Comments
 (0)