Back to Blog

~US$ 320M perdidos: exploits da Liquid Network e Symbiosis | BlockSec

Code Auditing
17 de setembro de 2026
14 min read
Key Insights
  • Este relatório abrange 2 incidentes de segurança que totalizam aproximadamente $320M em perdas na Liquid Network, uma sidechain do Bitcoin, e na Symbiosis, uma ponte do Bitcoin implantada na BNB Smart Chain, Ethereum e Rootstock. A exploração da Liquid Network foi responsável por mais de 99% do total, com a Symbiosis contribuindo com uma estimativa de $770K.

  • Em ambos os casos, a verificação que deveria ter impedido a falsificação foi executada e reportou sucesso enquanto atestava a coisa errada. Um nó da Liquid retornou true para um rangeproof que nunca examinou, porque um veredito para uma prova diferente havia sido registrado sob a mesma chave de cache. Os signatários da Symbiosis produziram uma assinatura válida sobre um valor de mint que seu próprio decodificador do lado do Bitcoin havia calculado a partir de campos controlados pelo depositante.

  • O valor de um saldo falsificado depende da saída, não do seu valor nominal. Quase todos os 4.000 L-BTC sem garantia da Liquid saíram através do peg bidirecional como bitcoin real, e ~$320M foram movidos; o syBTC que a Symbiosis emitiu chegou a mais de duas mil vezes o suprimento de bitcoin, mas os pools pelos quais ele tinha que ser vendido detinham 11,26 syBTC, e a perda para os provedores de liquidez e usuários chegou a uma estimativa de 9,97 BTC.

Durante a semana passada (07/09/2026 - 13/09/2026), observamos 2 incidentes de segurança com uma perda total estimada de aproximadamente $320M.

Data Incidente Tipo Perda Estimada
06/09/2026 * Liquid Network Construção Falha de Chave de Cache ~$320M
11/09/2026 Symbiosis Validação Falha de Depósito Off-Chain ~$770K

*O incidente da Liquid Network ocorreu em 6 de setembro e não foi coberto no relatório da semana passada. Ele está incluído aqui para fins de completude.

Melhor Auditor de Segurança para Web3

Valide design, código e lógica de negócios antes do lançamento

Destaque da Semana: Liquid Network

O incidente da Liquid Network foi selecionado por seu mecanismo sutil de colisão de chave de cache e pelas perdas substanciais que causou. Ao criar uma transação cujos dados de validação redividiram os bytes de uma transação anterior, o atacante fez com que um resultado de validação em cache fosse retornado para uma prova que nunca foi verificada.

Em 06/09/2026, a Liquid Network, uma sidechain do Bitcoin, foi explorada por aproximadamente $320M [1]. Uma colisão no cache de validação de rangeproof do Elements, o software de nó que a Liquid executa, permitiu que um veredito valid registrado para uma saída fosse retornado para uma segunda saída, inteiramente diferente, cuja prova foi, portanto, aceita sem nunca ter sido examinada. O atacante usou isso para criar 4.000 L-BTC que nenhum bitcoin respaldava, e então os retirou através do peg-out comum da rede. No dia seguinte, 3.400 BTC foram devolvidos à federação, deixando cerca de 598,5 BTC com o atacante [2].

Contexto

A Liquid Network é uma sidechain do Bitcoin construída sobre o Elements, uma plataforma blockchain de código aberto derivada do código-fonte do Bitcoin. Ela existe para mover bitcoin de forma mais rápida, mais barata e mais privada do que a cadeia principal permite. O bitcoin cruza entre as duas redes por meio de um peg de mão dupla: em um peg-in, um usuário bloqueia BTC com a federação da rede, um grupo fixo de organizações examinadas que custodiam conjuntamente os fundos do peg, e recebe uma quantidade equivalente de L-BTC; em um peg-out, o usuário destrói L-BTC e a federação libera o BTC correspondente. Os blocos da Liquid não são minerados. Um conjunto rotativo de nós funcionários da federação os propõe, e um limiar de assinaturas da federação os finaliza.

Assim como o Bitcoin, a Liquid rastreia fundos como saídas de transação não gastas, em vez de saldos de contas. Uma transação nomeia saídas não gastas existentes, as desbloqueia e cria novas saídas, e o valor que ela cria deve ser igual ao valor que ela consome. Cada saída carrega um script de bloqueio, seu scriptPubKey. Uma saída cujo script começa com OP_RETURN nunca pode ser gasta; ela existe para carregar dados, e um peg-out é expresso exatamente como esse tipo de saída.

A Liquid também oculta valores por padrão. Em vez de escrever um número em uma saída, ela escreve um compromisso de Pedersen para esse número. Compromissos são aditivos, então um nó pode confirmar que as entradas e saídas de uma transação se equilibram sem conhecer nenhum dos valores envolvidos. Essa propriedade tem duas faces: um compromisso também pode ocultar um valor que se comporta como negativo, o que permitiria que as saídas de uma transação excedessem suas entradas e ainda assim se equilibrassem. Cada saída cujo valor é oculto carrega, portanto, um rangeproof, uma prova de que o valor comprometido está dentro de [0, 2^64). Verificar um rangeproof é custoso, e a mesma saída é verificada mais de uma vez — quando a transação entra na mempool, e novamente quando ela chega em um bloco — então o Elements mantém um cache das provas que já aceitou, indexado pela prova e pelos dados contra os quais ela foi verificada.

Análise da Vulnerabilidade

O defeito está na forma como o Elements, o software de nó que todo participante da Liquid executa, armazena em cache rangeproofs já verificados.

CachingRangeProofChecker::VerifyRangeProof() deriva uma entrada de cache para a saída à sua frente e, em caso de acerto, retorna sucesso imediatamente sem tocar na prova:

A entrada vem de ComputeEntryRangeProof(), que escreve quatro campos, um após o outro, em um único fluxo SHA-256 e finaliza o digest:

Os quatro campos são o próprio rangeproof, o compromisso de Pedersen para o valor, o gerador de ativo que identifica qual ativo a saída contém, e o scriptPubKey, incluído para que uma prova aceita se vincule a um script de bloqueio específico.

Nenhum dos quatro campos carrega um prefixo de comprimento ou um separador. O rangeproof e o scriptPubKey variam em comprimento; o compromisso de Pedersen e o gerador de ativo são sempre pontos de 33 bytes. O digest, portanto, registra apenas os bytes concatenados, sem nada para marcar onde um campo terminou e o próximo começou. Dois conjuntos diferentes de quatro campos que por acaso se concatenam para o mesmo fluxo de bytes produzem a mesma entrada, e qualquer um que seja validado primeiro deixa para trás um veredito que o outro coleta. O hasher é semeado com um salt aleatório por nó, mas o salt é prefixado igualmente a ambos os fluxos, então ele altera o digest sem distinguir as duas entradas. O defeito foi corrigido no commit 94000967 [3].

Análise do Ataque

A análise a seguir é baseada nas transações 271147...187ec5 e f24a4b...0a183f, ambas aceitas por nós executando o código vulnerável.

  • Passo 1: O atacante publicou uma transação cuja primeira saída é um OP_RETURN carregando 67 bytes de dados.

Seu scriptPubKey mostra 6a 43 — o opcode OP_RETURN seguido por um push de 67 bytes — depois dois valores de 33 bytes e um 6a final. Esses 67 bytes empurrados não são dados que essa transação precisa. São o compromisso de valor e o gerador de ativo de uma saída que ainda não existia. Validar essa saída armazenou um veredito valid sob a entrada correspondente aos seus próprios quatro campos.

  • Passo 2: O atacante então enviou a transação de inflação. Sua saída OP_RETURN tem um scriptPubKey consistindo do único byte 6a, e seu compromisso de valor é exatamente o valor de 33 bytes embutido no push da transação anterior. Seu campo de rangeproof foi construído a partir do rangeproof, compromisso e gerador de ativo da transação anterior, seguidos pelos dois bytes 6a 43.

Os quatro campos dessa saída, portanto, se concatenam para o mesmo fluxo de bytes da primeira transação, redividido ao longo de limites diferentes:

Primer:     P0 │ C0 │ X │ S0,  where S0 = 6a 43 <33-byte C1> <33-byte X> 6a
Inflation:  P1 │ C1 │ X │ S1,  where P1 = P0 ‖ C0 ‖ X ‖ 6a 43  and  S1 = 6a

Both concatenate to:  P0 ‖ C0 ‖ X ‖ 6a 43 ‖ C1 ‖ X ‖ 6a

O cache retornou o veredito anterior, e P1 nunca foi verificado — na verdade, não se trata de um rangeproof. C1 compromete um pequeno valor negativo. A outra saída da transação, uma saída comum de pagamento para hash de chave pública testemunhada do endereço do atacante ex1q7kg...qa2w, carregava um grande compromisso positivo com um rangeproof genuíno, e os dois se compensavam, fazendo com que a transação se equilibrasse. Isso deixou 4.000 L-BTC não gastos que nenhum bitcoin respaldava.

  • Passo 3: O atacante fez o peg-out. Duas transações queimaram 3.996,01834922 e 2,65138358 L-BTC por meio de saídas comuns de peg-out OP_RETURN, totalizando 3.998,66973280 L-BTC. Os nós funcionários que autorizam peg-outs os validaram com o mesmo código vulnerável e liberaram o bitcoin: 3.995,99999857 BTC e 2,49749857 BTC chegaram ao atacante no Bitcoin, 3.998,49749714 BTC no total.

A rede pausou e se dividiu em duas cadeias enquanto o incidente era resolvido [4], e retomou com o peg-out inválido rejeitado [2]: um explorador de blocos hoje mostra a transação primer confirmada, mas não a transação de inflação, mesmo que o bitcoin que ela liberou já tivesse saído da carteira da federação. Às 16:09:25 UTC do dia seguinte, o atacante devolveu 3.400,00000000 BTC à carteira de peg da federação, mantendo os ~598,5 BTC restantes pendentes [2], enquanto os dois lados negociavam por meio de mensagens embutidas em transações do Bitcoin [4].

Conclusão

O atacante não quebrou nenhuma criptografia e não comprometeu nenhuma chave. O defeito estava na forma como o cache de rangeproof identificava o que já havia verificado. Sua chave concatenava quatro campos — dois deles de comprimento variável — em um único fluxo de hash sem nada marcando onde cada campo terminava, de modo que um segundo conjunto de campos poderia redividir os mesmos bytes e recair na mesma entrada. Um veredito valid armazenado foi então retornado para uma prova que nenhum nó jamais havia verificado, e uma vez que um rangeproof deixa de restringir o valor por trás dele, um razão confidencial perde a única coisa que mantinha seus valores ocultos não negativos. Uma saída criada tornou-se 4.000 L-BTC, e o peg de mão dupla os transformou em bitcoin na cadeia principal.

Qualquer identificador derivado de mais de uma entrada de comprimento variável precisa se comprometer com os limites entre elas, seja prefixando cada campo com seu comprimento, seja hasheando os campos em slots separados de tamanho fixo. Sem isso, a derivação não é injetiva, e duas entradas distintas podem ser confundidas como uma só. O requisito é mais crítico onde um cache substitui uma verificação, porque ali um acerto é uma decisão de não executá-la.


Verificação de Segurança Gratuita

Uma verificação de segurança rápida com nosso mecanismo de análise automatizado interno.

Verificação gratuita

Mais Incidentes Nesta Semana

Symbiosis

Em 11/09/2026, a rota Bitcoin da ponte cross-chain Symbiosis foi explorada em suas implantações na BNB Smart Chain, Ethereum e Rootstock, custando aos provedores de liquidez e usuários uma perda estimada de 9,97 BTC (~$770K, ao preço de ~$77K de 11 de setembro) [5]. Um código off-chain que decide quanto bitcoin sintético emitir a partir de um depósito em Bitcoin obteve a identidade do depositante de uma parte da transação que o próprio depositante controla, permitindo que o atacante se passasse pelo administrador e reduzisse a taxa mínima abaixo de zero; em seguida, subtraiu essa taxa do depósito sem verificar seu sinal, de modo que a subtração acabou somando.

Contexto

Symbiosis é um protocolo de liquidez cross-chain que move valor entre cadeias por meio de bloqueio e emissão, em vez de transferir o próprio ativo: em cadeias com contratos inteligentes, os tokens de um usuário são bloqueados pelo contrato Portal na cadeia de origem, e o contrato Synthesis emite uma quantidade equivalente de um token sintético, um sToken, na cadeia hospedeira; queimar o sToken libera o original [6]. O Bitcoin chega por meio dessa rota como syBTC, um token com 8 casas decimais correspondentes à menor unidade do próprio bitcoin, emitido na BNB Smart Chain, Ethereum e Rootstock e pareado em pools contra BTCB, cbBTC, WBTC e RBTC [5].

O Bitcoin não tem nada disso: nenhum contrato inteligente, portanto nenhum contrato Portal para bloquear depósitos. Em seu lugar existe o portal — um endereço Bitcoin designado que desempenha a mesma função. Um depósito é uma transação Bitcoin comum pagando a esse endereço, com as instruções para a cadeia de destino anexadas como dados. Um código off-chain pertencente à ponte lê esses dados para saber quem está depositando, quanto e para onde o token sintético deve ir, e aplica a taxa do portal — subtraída do valor depositado antes que o valor a ser emitido seja definido — cujo mínimo é um parâmetro definido por seu administrador.

Nada do lado do Bitcoin é visível para a cadeia de destino, então uma Relayers Network transporta a solicitação resultante através das cadeias. A solicitação chega ao BridgeV2, o ponto de entrada on-chain da ponte, como uma chamada codificada que ele encaminha ao Synthesis. A autorização repousa sobre uma chave MPC: os signatários do protocolo detêm partes de uma única chave privada e produzem conjuntamente uma assinatura sobre a solicitação. O ponto de entrada para solicitações retransmitidas carrega um único modificador e não faz mais nada antes de despachar a chamada:

Esse modificador faz o hash da solicitação e exige que a assinatura que a acompanha seja válida para o endereço MPC:

O que o contrato estabelece é que a chave MPC assinou a solicitação. O valor que a solicitação carrega é calculado do lado do Bitcoin.

Análise da Vulnerabilidade

O defeito não está nos contratos da cadeia de destino. Está no serviço off-chain que lê depósitos em Bitcoin e os transforma em solicitações cross-chain. Seu código-fonte não está publicamente disponível, então a descrição a seguir segue o post-mortem da equipe [5], juntamente com um relatório de auditoria de terceiros de 2024 que contém um trecho de código que parece relacionado [7].

Duas falhas no caminho de depósito precisaram coincidir, e o post-mortem afirma que nenhuma delas era suficiente por si só.

A primeira está na forma como o depositante é identificado. As instruções anexadas a um depósito são decodificadas para recuperar quem o está fazendo, e o decodificador obtinha essa identidade de uma parte dos dados da transação que quem gasta a entrada controla. Um depositante poderia, portanto, se nomear como qualquer parte que o protocolo reconheça, incluindo o administrador do portal, o papel que define a taxa mínima que o portal aceitará.

A segunda está na forma como essa taxa é aplicada. A auditoria de 2024 relatou a linha em decodeWrap() que calcula o valor a ser emitido subtraindo a taxa do valor da saída de depósito:

Value: types.Satoshi(tx.TxOut[idx].Value) - info.PortalFee,

Sua constatação foi que types.Satoshi é um tipo inteiro assinado, enquanto a estrutura info que carrega PortalFee não é confiável e é controlada pelo usuário, de modo que o resultado pode ser levado a um valor negativo e, serializado para a cadeia de destino como um valor não assinado, torna-se grande o suficiente para emitir uma quantidade arbitrária de bitcoin sintético. A auditoria registrou o problema como corrigido na época [7]. O post-mortem de 2026 descreve o mesmo tipo de falha: a taxa foi subtraída do depósito sem uma verificação de seu sinal [5], de modo que uma taxa abaixo de zero ampliava o depósito em vez de reduzi-lo. Nada no caminho de depósito parece limitar o valor a ser emitido pelo bitcoin efetivamente recebido.

Análise do Ataque

Doze emissões forjadas passaram pela BNB Smart Chain, Ethereum e Rootstock em aproximadamente quatro minutos [5]. A análise a seguir é baseada em uma delas, a transação 0x9a2bc0...21b9b959 na BNB Smart Chain.

  • Passo 1: Passando-se pelo administrador do portal, o atacante moveu a taxa mínima que o portal aceita para abaixo de zero, de modo que um depósito declarando uma taxa negativa fosse processado em vez de rejeitado [5].

  • Passo 2: O atacante depositou 330 satoshi, que aparece como 0x000000000000014a. A solicitação que chegou à BNB Smart Chain carregava 0x400000000000014a — o mesmo valor com o bit para 2^62 definido, 4.611.686.018.427.388.234 unidades base. A diferença entre os dois é exatamente 2^62, então a taxa subtraída desse depósito foi de -4.611.686.018.427.387.904 satoshi:

    330 - (-4,611,686,018,427,387,904) = 4,611,686,018,427,388,234

    A solicitação foi assinada e retransmitida nessa forma.

  • Passo 3: receiveRequestV2Signed() verificou a assinatura MPC sobre a solicitação e a repassou, chegando a metaMintSyntheticTokenBTC(). Essa função resolveu a representação sintética do token real para o ID da cadeia de origem, syBTC, e chamou synthesize() para o valor total assinado. Tudo isso foi transferido para o endereço do atacante 0x025122...5d3Ba2: 46.116.860.184,27388234 syBTC.

  • Passo 4: O atacante vendeu o token sintético nos pools que o continham. Um único swap por meio de um pool Uniswap v4 syBTC/WBTC liquidou 18.446.744.072.845.450.682 unidades base de syBTC, cerca de quatro vezes o que a transação acima emitiu, e retirou 4,38897292 WBTC.

Encaminhado adiante, o produto desse swap chegou a aproximadamente 137 ether.

A equipe pausou a rota Bitcoin, e cerca de 15,2 BTC dos fundos do portal foram movidos para endereços de reserva em poucas horas [5]. Foi oferecida uma recompensa de 20% de qualquer valor devolvido, aberta até 13 de setembro [8]. As demais rotas do protocolo não foram afetadas.

Conclusão

Nenhuma chave foi roubada e nenhum contrato foi enganado para executar código que não foi escrito para executar. A assinatura que a cadeia de destino verificou era genuína; o que ela autorizou foi um número que o código off-chain já havia produzido incorretamente de duas maneiras distintas: uma vez ao obter a identidade do depositante de um campo que o próprio depositante controla, permitindo que o atacante se passasse pelo administrador do portal e reduzisse sua taxa mínima abaixo de zero, e novamente ao subtrair essa taxa do depósito sem verificar seu sinal, de modo que uma taxa negativa ampliava o depósito em vez de reduzi-lo.

Uma identidade obtida de uma entrada não confiável não é uma identidade: um papel privilegiado só pode ser estabelecido por algo que o depositante não pode escolher, como o endereço que efetivamente autorizou a entrada gasta, verificado contra uma lista mantida pelo protocolo — não um campo que o depositante é livre para preencher. Um valor que é subtraído precisa de limites de ambos os lados: uma taxa deveria ser obrigada a ficar entre zero e o valor do depósito, e o valor a ser emitido nunca deveria ser permitido exceder o que a cadeia de origem efetivamente recebeu. Qualquer um dos dois limites teria impedido isso sozinho.

Comece com o Phalcon Security

Detecte cada ameaça, alerte o que importa e bloqueie ataques.

Experimente gratuitamente agora

Referências

[1] https://x.com/Liquid_BTC/status/2096696272447218108

[2] https://x.com/Liquid_BTC/status/2097404704028545175

[3] https://github.com/ElementsProject/elements/commit/94000967f6dc05b1afd435e79b1bbc597e29f816

[4] https://www.coindesk.com/markets/2026/09/08/white-hat-hackers-return-most-of-usd320m-bitcoin-taken-from-liquid-network

[5] https://x.com/symbiosis_fi/status/2099566361940795831

[6] https://docs.symbiosis.finance/crosschain-liquidity-engine/synthesizing-process

[7] https://github.com/symbiosis-finance/audits/blob/master/Symbiosis%20Relayers%20Network/Symbiosis%20Relayers%20Network%202024%20-%20Decurity.pdf

[8] https://x.com/symbiosis_fi/status/2098442463358718264

Sobre a BlockSec

BlockSec é uma provedora full-stack de segurança blockchain e compliance cripto. Construímos produtos e serviços que ajudam os clientes a realizar auditoria de código (incluindo contratos inteligentes, blockchain e carteiras), interceptar ataques em tempo real, analisar incidentes, rastrear fundos ilícitos e cumprir obrigações de AML/CFT, ao longo de todo o ciclo de vida de protocolos e plataformas.

A BlockSec já publicou diversos artigos de segurança blockchain em conferências renomadas, reportou vários ataques de dia zero em aplicações DeFi, bloqueou múltiplos ataques para resgatar mais de 20 milhões de dólares, e protegeu bilhões em criptomoedas.

Best Security Auditor for Web3

Validate design, code, and business logic before launch. Aligned with the highest industry security standards.

BlockSec Audit
~US$ 320M perdidos: exploits da Liquid Network e Symbiosis | BlockSec