O endereço que os signatários nunca viram: troca no bundle de uma carteira
O desafio
A Brynmor aprovou uma transferência de rotina. Ache onde o código troca o destinatário. Diga para qual endereço ela vai de verdade.
O que você vai aprender
- Identificar código injetado que só dispara para endereços de carteira específicos
- Distinguir os endereços das vítimas em uma lista de alvos do endereço do atacante
- Explicar o que a operation 1 (delegatecall) permite fazer em uma transação de um Safe
- Entender por que a tela do signatário pode ser diferente do que é assinado
- Citar controles contra adulteração de front-end e blind signing
Habilidades testadas
Pré-requisitos
- Ler JavaScript
- O que é uma carteira multisig
Como funciona
Um multisig Safe só executa uma transação depois que owners suficientes assinam seus campos: to, value, data e operation. Os owners costumam assinar por um app web, então quem controla o JavaScript desse app controla o que de fato é assinado.
operation vale 0 para uma chamada normal e 1 para um delegatecall. Um delegatecall executa o código do contrato alvo dentro do próprio Safe, com o saldo e o storage do Safe, então um único delegatecall assinado para o contrato de um atacante entrega a carteira inteira.
Em fevereiro de 2025, atacantes fizeram exatamente isso com a Bybit: JavaScript injetado no front-end do Safe{Wallet} esperou o Safe da cold wallet da exchange, trocou uma transferência de rotina por um delegatecall e restaurou a exibição depois da assinatura. O contrato do atacante então esvaziou cerca de 401.000 ETH e outros tokens, aproximadamente 1,5 bilhão de dólares.
Erros comuns
- Responder a warm wallet (0x0Ac51AA8300882aAa03F7678770495345Dc51774). Esse é o que a tela de revisão mostrou e o que os signatários acreditaram aprovar. O bundle sobrescreve
toantes da assinatura e o restaura depois. - Responder um endereço de
waouba. Essas listas são os alvos: o Safe e os signatários da própria Brynmor, como mostra o queued-tx.json. Elas decidem quando a armadilha dispara, não para onde o dinheiro vai. - Confiar no calldata decodificado.
0xa9059cbbé o selector detransfer(address,uint256), então a carteira mostra uma transferência de valor zero. Com operation 1, é o contrato do atacante que decide o que essa chamada realmente faz.
Como se proteger
- Verifique toda transação multisig em um dispositivo independente: clear signing de
to,operationedatadecodificado em uma hardware wallet, ou umsafeTxHashrecalculado com uma ferramenta offline, nunca apenas pela página web. - Trate
operation: 1como crítico: um Safe Guard pode rejeitar delegatecall, exceto para bibliotecas permitidas como o MultiSend. - Fixe o front-end da carteira em uma build revisada (self-hosted ou content-addressed), monitore o hash do bundle servido e restrinja quem pode escrever no bucket de hospedagem.
- Mantenha a assinatura da cold wallet em máquinas dedicadas e siga um checklist escrito para movimentações grandes.