Em 25 de agosto de 2025, com a assistência de Cantina e Seal911, a Panoptic conduziu uma operação de resgate white hat, protegendo aproximadamente $400K em fundos em risco [1]. A causa raiz foi uma falha na construção do s_positionsHash: o protocolo usava XOR para agregar hashes Keccak256 de IDs de posição em uma única impressão digital. Embora os hashes Keccak256 individuais permaneçam resistentes a colisões, a linearidade matemática do XOR torna a impressão digital composta insegura. Um atacante pode gerar um conjunto de IDs de posição forjados cujo hash agregado por XOR corresponde a qualquer impressão digital alvo, contornando a verificação de posição do protocolo e retirando colateral sem pagar a dívida.
Contexto
A Panoptic é um protocolo descentralizado de negociação de opções perpétuas construído na Ethereum que permite aos usuários negociar opções de venda e compra.
A função withdraw() possui um parâmetro de entrada positionList, que consiste em um conjunto de tokenIds. Cada tokenId representa uma posição. A função withdraw() verifica o status de dívida de cada posição com base no s_positionsHash e então recupera o colateral do usuário.
Para economizar gas, o protocolo não armazena cada posição (ou seja, tokenId) do usuário. Em vez disso, ele calcula uma impressão digital com base em todos os tokenIds do usuário e a registra em s_positionsHash. Os 8 bits mais significativos de cada s_positionsHash representam numLegs, enquanto os 248 bits inferiores representam o user position hash.
Para cada tokenId passado, o protocolo calcula seu hash, pega os 248 bits inferiores e atualiza o user position hash realizando um XOR bit a bit com os 248 bits inferiores do s_positionsHash atual.
Simultaneamente, countLegs é ajustado com base no intervalo numérico do tokenId: permanece inalterado quando o tokenId é menor que , e aumenta em 1, 2 ou 3 quando nos intervalos , e respectivamente. Isso é finalmente escrito nos 8 bits superiores do s_positionsHash para atualizar numLegs.
Análise da Vulnerabilidade
A causa raiz é uma falha no algoritmo do contrato para construir o s_positionsHash, especificamente o uso da operação XOR para agregar resultados de hash Keccak256. Embora uma única função hash permaneça segura, a linearidade matemática da operação XOR torna o algoritmo de impressão digital geral (ou seja, a soma XOR de hashes) inseguro [2].
A linearidade implica que um atacante não precisa quebrar a própria função hash (ou seja, reverter o tokenId a partir do hash). Em vez disso, ele pode empregar uma estratégia combinatória: gerando um grande número de tokenIds aleatórios, calculando seu Keccak256(tokenId) e, a partir desses valores de hash, selecionando um subconjunto específico de modo que a soma XOR desses hashes de tokenId corresponda exatamente à impressão digital alvo da vítima.
Isso permite que um atacante passe um conjunto de tokenIds forjados ao chamar withdraw() para passar na verificação de saúde e recuperar todo o colateral correspondente ao s_positionsHash.
Teoria
Suponha que a impressão digital de posição do usuário s_positionsHash tenha um user position hash de e numLegs de , com tokenIds do usuário . Assim:
Aqui, cada valor de hash de 248 bits pode ser visto como um vetor de 248 dimensões.
Portanto, reside em um espaço de 248 dimensões composto de 0s e 1s (). Neste espaço, a operação XOR é equivalente à adição vetorial (Apêndice I).
O objetivo do atacante é encontrar vetores de 248 dimensões dentre todos os vetores disponíveis, de modo que os 248 bits inferiores de sua soma XOR sejam iguais a . Assim, podemos formular o objetivo do atacante como um sistema de equações lineares:
Especificamente, não precisamos tentar construir diretamente. Em vez disso, selecionamos vetores de hash linearmente independentes (onde é igual à dimensão 248) e os usamos como vetores coluna para construir uma matriz :
O problema então se transforma em encontrar um vetor de coeficientes tal que:
Onde , e .
De acordo com a teoria da álgebra linear, desde que a matriz seja de posto completo, ela abrange todo o espaço -dimensional. Isso significa que para qualquer alvo , o sistema de equações possui uma solução única. Após resolver , simplesmente retemos os vetores para os quais ; sua soma XOR é .
Exemplo
Para facilitar a compreensão, demonstramos esse processo de construção com um estudo de caso. Suponha que os vetores sejam tridimensionais, com cada dimensão consistindo apenas de 0 ou 1, e o valor de hash alvo seja 101, ou seja, .
Em seguida, geramos aleatoriamente 3 valores de hash:
Construímos a matriz usando esses três vetores como colunas e configuramos a equação :
Resolvendo via eliminação de Gauss, obtemos . Isso significa que precisamos selecionar e (correspondentes a ), e sua soma XOR é exatamente igual ao alvo .
Selecionando n Vetores Linearmente Independentes
Como mencionado anteriormente, para resolver , precisamos construir uma matriz de posto completo. Dado que estamos lidando com um espaço vetorial extremamente grande (), a questão central é: Como selecionamos rapidamente vetores linearmente independentes nesse vasto espaço?
Considere o método mais simples: gerar tokenIds aleatoriamente e selecionar seus resultados de hash como vetores.
Sobre , a probabilidade de que vetores -dimensionais selecionados aleatoriamente formem uma matriz de posto completo é:
Quando é grande (neste exemplo, ), essa probabilidade converge para uma constante (Apêndice II):
Isso significa que cada tentativa aleatória tem aproximadamente 28,9% de probabilidade de sucesso. Em média, um atacante precisa de apenas cerca de 3,5 tentativas para encontrar um conjunto de vetores linearmente independentes. Portanto, o custo computacional é extremamente baixo, e o atacante pode rapidamente construir uma matriz que satisfaça as condições.
Para controlar o countLegs nos 8 bits superiores, precisamos apenas ajustar o intervalo dos valores de tokenId gerados aleatoriamente com base no countLegs alvo.
Por exemplo, se quisermos que o numLegs na impressão digital forjada seja 0, simplesmente garantimos que os tokenIds gerados aleatoriamente sejam todos menores que . Como o incremento de leg para tokenIds nesse intervalo é 0, independentemente de quais vetores a solução da eliminação de Gauss selecionar, o numLegs acumulado final será inevitavelmente 0.
Análise do Ataque
O resgatador white hat iniciou múltiplas transações de resgate. Por simplicidade, a discussão a seguir é baseada em apenas uma dessas transações [3].
A lógica central consiste nas seguintes 5 etapas:
- Tomar emprestado 0,23e8 WBTC e 28e18 WETH via flash loan da Aave.
- Depositar 0,23e8 WBTC e 28e18 WETH no contrato poWBTC e no contrato 0x1f8d_poWETH.
- Chamar
mintOptions()do contratoPanopticPoolcom umpositionIdListnormal para tomar fundos emprestados e abrir uma posição alavancada. - Chamar
withdraw(), passando ostokenIds forjados. Como essas posições forjadas têm umpositionSizede 0, a função retornatokenRequiredcomo 0, o que significa que o colateral total exigido para todas as posições é erroneamente calculado como zero. Enquanto isso, os_positionsHashgerado por essestokenIds é exatamente o mesmo que o gerado na etapa 3, permitindo que o resgatador recupere todo o colateral sem pagar nenhuma dívida. - Pagar o flash loan e executar a próxima rodada.
Resumo
Este incidente destaca duas falhas combinadas que juntas possibilitaram a retirada não autorizada de colateral.
- XOR não é uma função de agregação segura para hashes. O Keccak256 é resistente a colisões, mas a linearidade do XOR significa que a soma XOR de múltiplos hashes não herda essa propriedade. Construir um conjunto de entradas cujos hashes XOR resultem em qualquer valor alvo se reduz a resolver um sistema de equações lineares sobre , o que é computacionalmente trivial. A composição de hashes requer operações que preservem a resistência a colisões, como concatenação seguida de re-hashing.
- Validação ausente de IDs de posição. O protocolo não verificou se os
positionIds passados correspondiam a posições de opção válidas. Valores abaixo de carregam umcountLegsde 0 e umpositionSizede 0, o que significa que as posições forjadas não geram dívida. Isso permitiu que o atacante passasse na verificação de saúde com requisito de colateral zero enquanto correspondia à impressão digital alvo.
Referência
Apêndice
Os dois apêndices a seguir fornecem uma explicação e prova matemática das afirmações no texto principal, a saber, que a operação XOR é equivalente à adição vetorial (Apêndice I) e a probabilidade de que uma matriz aleatória seja de posto completo (Apêndice II).
Apêndice I
No corpo finito , a adição é definida como adição módulo 2:
Observa-se que isso é idêntico à operação lógica OR Exclusivo (XOR, símbolo ).
Para o espaço vetorial -dimensional (neste caso ), a adição de dois vetores e é definida como adição componente a componente módulo 2:
Portanto, no espaço vetorial , a adição vetorial é equivalente à operação XOR bit a bit nos componentes do vetor.
Apêndice II
Para que a matriz seja de posto completo, esses vetores devem ser linearmente independentes.
O primeiro vetor pode ser qualquer vetor em exceto o vetor zero, fornecendo escolhas; o segundo vetor não deve residir no subespaço gerado por , que contém vetores, deixando escolhas; seguindo essa lógica, o -ésimo vetor não pode estar no subespaço gerado pelos vetores anteriores, resultando em escolhas possíveis.
O número total de tais matrizes (ou seja, a ordem de ) é:
E o número total de todas as matrizes possíveis é .
Assim, a probabilidade é:
Fazendo , podemos reescrever essa expressão como:
Quando , esse produto converge para uma constante:
Isso significa que para grande, a probabilidade de que uma matriz aleatória seja de posto completo é aproximadamente 28,9%.
Sobre a BlockSec
A BlockSec é um provedor completo de segurança blockchain e conformidade cripto. Desenvolvemos produtos e serviços que ajudam os clientes a realizar auditorias de código (incluindo contratos inteligentes, blockchain e carteiras), interceptar ataques em tempo real, analisar incidentes, rastrear fundos ilícitos e cumprir obrigações AML/CFT, ao longo de todo o ciclo de vida de protocolos e plataformas.
A BlockSec publicou múltiplos artigos de segurança blockchain em conferências de prestígio, relatou vários ataques zero-day em aplicações DeFi, bloqueou múltiplos hacks para resgatar mais de 20 milhões de dólares e protegeu bilhões em criptomoedas.
-
Site oficial: https://blocksec.com/
-
Conta oficial no Twitter: https://twitter.com/BlockSecTeam



