Um mês de preparação: como hackearam o projeto Allbridge e o que a Circle tem a ver com isso

Um mês de preparação: como hackearam o projeto Allbridge e o que a Circle tem a ver com isso

O atacante conseguiu criar uma mensagem falsa sobre uma transferência de 1 milhão de USDC e convencer o protocolo de que esses fundos eram reais.

24 de ago. de 2026

Em 19 de agosto de 2026, a conhecida ponte cross-chain Allbridge sofreu um ataque que resultou no roubo de cerca de $190,000. No entanto, o ataque em si não foi realizado em um único dia: o atacante o preparou por quase um mês. Analisamos em detalhe o mecanismo desse ataque e como uma falha na verificação das mensagens cross-chain permitiu ao atacante fazer passar uma transferência de USDC inexistente por uma real.

O que é preciso saber de antemão

Para entender como o ataque foi realizado, primeiro é preciso compreender como funciona o protocolo CCTP da Circle e o sistema de transmissão de mensagens entre blockchains que ele utiliza.

Uma transferência comum via CCTP passa por várias etapas. Primeiro, o TokenMessenger na rede de origem queima USDC. Depois, o MessageTransmitter da Circle verifica a autenticidade da mensagem e a transmite. Em seguida, o TokenMessenger na rede de destino recebe a mensagem, verifica-a e cria a quantidade correspondente de USDC. Por fim, o Router, após confirmar o recebimento efetivo dos fundos, transfere os USDC ao usuário.

Pela transmissão das mensagens responde o contrato Circle MessageTransmitterV2. Ele emite uma attestation para a mensagem completa: uma prova assinada pela Circle de que uma mensagem cross-chain concreta realmente foi verificada e autenticada. No entanto, essa attestation só indica que o conteúdo da mensagem foi certificado pela Circle. Por si só, não prova que a quantia indicada na mensagem realmente foi transferida.

Pela criação de tokens na rede de destino responde a Circle TokenMessengerV2. Depois que o MessageTransmitterV2 recebe a mensagem, ele determina qual contrato deve ser chamado, com base no endereço do destinatário indicado no cabeçalho da mensagem. Em uma operação normal de CCTP, esse endereço deve corresponder ao contrato TokenMessengerV2 na rede de destino. Depois são verificados o TokenMessenger de origem, o token, a quantia e o endereço do destinatário, e somente após passar com êxito por todas as verificações são criados novos USDC.

O módulo CCTP na infraestrutura da Allbridge situa-se mais adiante nessa cadeia. Ele aceita depósitos concluídos e os transforma em registros que o Router pode reconhecer, após o que este transfere os tokens ao usuário. É justamente aqui que aparece um detalhe de importância fundamental.

Nesta etapa fica claro que a função sendMessage da Circle é uma interface universal. Qualquer usuário pode chamá-la e passar um fragmento do conteúdo de uma mensagem cross-chain, que a Circle depois autentica. O mero fato de chamar essa interface não leva automaticamente nem à queima de USDC nem à criação de novos USDC. Uma transferência comum de CCTP exige, além disso, a participação do TokenMessenger na rede de origem. Primeiro ele queima USDC e depois cria uma mensagem com informação sobre os tokens destruídos. No ataque analisado, o atacante pulou essa etapa: simplesmente formou uma mensagem cross-chain sem queimar nenhum USDC.

A causa raiz da vulnerabilidade

No contrato Allbridge CCTPTokenMessenger, a função receiveCctpMessage, destinada a receber mensagens cross-chain, não verificava se o campo sender do cabeçalho da mensagem CCTP coincidia com o endereço do TokenMessenger remoto. O campo recipient também não era verificado frente ao contrato Circle TokenMessengerV2.

Como resultado, o MessageTransmitterV2.receiveMessage transmitia a mensagem cross-chain recebida ao contrato atacante, permitindo-lhe determinar de fato como se os tokens tivessem sido criados com êxito. Ao mesmo tempo, o próprio contrato da Allbridge não verificava adicionalmente se o balanço de USDC do Router havia realmente aumentado após a suposta criação de tokens. Em vez disso, confiava na quantia contida na mensagem que o próprio atacante havia formado, e a registrava como balanço disponível para receber. Essa quantia era guardada no valor receivedTokenAmount associado ao messageHash dentro do hookData da mensagem cross-chain.

Também não havia proteção adicional no hookData. Quando o Router realiza um pagamento, ele recalcula por conta própria o messageHash a partir dos parâmetros da chamada, e depois procura o registro interno de depósito criado previamente para esse hash. Ainda antes de enviar a mensagem para a Polygon, o atacante podia calcular por conta própria o hash necessário para esses mesmos parâmetros e registrar de antemão o messageHash no hookData da mensagem cross-chain. Assim, o registro que o Router encontrava depois era um registro interno criado pelo próprio atacante e não tinha relação com o recebimento efetivo de fundos.

Como resultado, o atacante conseguiu chamar diretamente o sendMessage do contrato Circle MessageTransmitterV2 na rede Polygon e formar uma mensagem cross-chain arbitrária. Depois que a Circle assinou essa mensagem, o atacante conseguiu passar com êxito na verificação da attestation na rede Base. Como resultado, a mensagem falsa foi percebida como um depósito cross-chain real, após o que o Router transferiu os tokens para o endereço indicado pelo atacante.

Como o ataque à Allbridge foi realizado passo a passo

1. Em 26 de julho de 2026, o atacante chamou pela primeira vez diretamente a função sendMessage do contrato Circle MessageTransmitterV2 na rede Polygon. Foi uma operação comum de envio de uma mensagem cross-chain. A transação criou um evento MessageSent, mas não houve nenhuma queima real de USDC. Posteriormente, a Circle emitiu uma attestation para a mensagem completa, e essa etapa transcorreu normalmente, exatamente como o protocolo prevê.

Na mensagem foram colocados dados em um formato característico de CCTP. Como rede de origem foi indicada a Polygon, como rede de destino, a Base, e a quantia declarada era de 1,000,000 USDC. O parâmetro feeExecuted foi definido como zero, e o destinationCaller apontava para o contrato Allbridge CCTPTokenMessenger.

Ao mesmo tempo, o atacante definiu o seu próprio contrato como recipient no cabeçalho da mensagem, indicou no corpo da mensagem o endereço do Messenger remoto configurado como sourceSender, e colocou o messageHash do Router calculado de antemão no hookData. Todos esses parâmetros foram preparados de modo a posteriormente passar pelas verificações da Allbridge.

2. Após criar a mensagem cross-chain maliciosa, o atacante esperou cerca de 24 dias. A razão da espera estava nas particularidades do funcionamento do Router na rede Base. Como ele cumpre a função de reenviar fundos, normalmente não mantém um volume significativo de liquidez por muito tempo.

Somente em 19 de agosto de 2026, quando o relayer da Allbridge acabara de criar cerca de 191,112 USDC como resultado de um depósito CCTP genuíno de outro usuário, o balanço do Router atingiu cerca de 191,156 USDC.

Esses fundos pertenciam a usuários reais e representavam transferências cross-chain à espera de serem enviadas aos seus destinatários. O atacante esperou por esse período muito curto em que o Router tinha liquidez suficiente para realizar o seu plano, e começou o ataque direto apenas seis segundos depois de o depósito genuíno chegar.

3. O contrato atacante chamou primeiro a função receiveCctpMessage do contrato CCTPTokenMessenger, passando a mensagem e os dados de assinatura (attestation) obtidos da transação anterior na Polygon.

As verificações de destinationCaller e sourceSender passaram com êxito, já que ambos os valores haviam sido escolhidos e formados de antemão pelo próprio atacante. Depois o contrato atacante chamou a função receiveMessage do contrato Circle MessageTransmitterV2.

No âmbito dessa função foi executada uma chamada de retorno (callback) ao contrato atacante, já que era justamente ele o indicado no campo recipient do cabeçalho da mensagem. O contrato atacante simplesmente retornou um resultado bem-sucedido, sem realizar a operação esperada de criação de tokens através do Circle TokenMessenger.

A Allbridge também não voltou a verificar o balanço do Router nem se certificou de que o contrato chamado era realmente o Circle TokenMessengerV2. Em vez disso, registrou diretamente o valor amount - feeExecuted em receivedMessages[messageHash]. Assim, dentro do sistema apareceu um registro de supostamente recebidos 1,000,000 USDC, embora não existisse nenhum depósito correspondente.

4. Como a mensagem cross-chain criada de antemão pelo atacante indicava uma quantia de 1,000,000 USDC, enquanto no balanço do Router naquele momento havia apenas cerca de 191,156 USDC, faltavam ao atacante cerca de 808,844 USDC para realizar a transferência posterior.

Para aumentar temporariamente o balanço do Router até o valor necessário, o atacante usou um empréstimo flash (flash loan) da Aave. Isso lhe permitiu tomar emprestados 808,844 USDC durante uma única operação e elevar o balanço do Router até a quantia indicada na mensagem falsa. Depois disso, as condições para o posterior saque de fundos foram atendidas.

5. Em seguida, o atacante chamou a função receiveToken do Router para realizar a operação de liquidação. Com base nos parâmetros da chamada, o Router recalculou por conta própria o hash e obteve um valor que coincidia por completo com o messageHash que o atacante havia calculado de antemão e colocado no hookData.

Depois disso, o Router verificou apenas uma coisa: se no contrato CCTPTokenMessenger existia um registro receivedTokenAmount correspondente a esse messageHash e se ele superava zero. A presença de tal registro foi de fato percebida como prova de que um depósito genuíno havia sido recebido. Como o Router retém uma comissão de 0.1%, após deduzi-la transferiu diretamente os 999,000 USDC restantes ao contrato atacante.

Assim, ao longo de toda a operação, o Router verificou unicamente a presença de um balanço de crédito interno correspondente no contrato CCTPTokenMessenger. Ele não voltou a verificar se esse crédito correspondia a uma entrada real de ativos na blockchain por uma quantia equivalente.

6. Após receber 999,000 USDC, o atacante devolveu à Aave o principal do empréstimo flash - 808,844 USDC - e pagou cerca de 404.422012 USDC de comissão pelo seu uso.

A maior parte das perdas recaiu sobre depósitos cross-chain reais que acabavam de chegar ao Router e ainda não haviam sido transferidos aos seus legítimos destinatários. É digno de nota que os 1,000 USDC de comissões do Router mencionados acima foram roubados mais tarde também por outros atacantes que reproduziram o mesmo método de ataque.

O problema da attestation

A causa principal do ataque foi a insuficiente verificação da mensagem cross-chain por parte da Allbridge. Uma attestation da Circle só prova que o conteúdo da mensagem não foi alterado após a sua autenticação. Não prova que a mensagem realmente foi resultado da queima de tokens na rede de origem ou da sua criação na rede de destino.

A Allbridge confiou diretamente na quantia, no endereço de origem dos fundos e no messageHash que o próprio atacante havia formado na mensagem CCTPTokenMessenger. Esses dados foram registrados como balanço disponível para saque e, de fato, passaram a ser percebidos pelo sistema como o tamanho real do depósito.

Para os sistemas de pontes cross-chain, o princípio-chave é o seguinte: uma mensagem corretamente autenticada e verificada é uma condição necessária para realizar uma liquidação entre redes, mas o fundamento para o pagamento final do Router deve ser o recebimento efetivo dos ativos.

#USDC#Ataque hacker
24 dias de espera e uma transferência falsa: como atacaram a Allbridge