Am 25. August 2025 führte Panoptic mit Unterstützung von Cantina und Seal911 eine White-Hat-Rettungsaktion durch und sicherte etwa 400.000 US-Dollar an gefährdeten Geldern [1]. Die Grundursache war ein Fehler in der Konstruktion von s_positionsHash: Das Protokoll verwendete XOR, um Keccak256-Hashes von Positions-IDs zu einem einzigen Fingerabdruck zu aggregieren. Während einzelne Keccak256-Hashes kollisionsresistent bleiben, macht die mathematische Linearität von XOR den zusammengesetzten Fingerabdruck unsicher. Ein Angreifer kann eine Reihe gefälschter Positions-IDs generieren, deren XOR-aggregierter Hash mit jedem Ziel-Fingerabdruck übereinstimmt, wodurch die Positionsüberprüfung des Protokolls umgangen und Sicherheiten abgezogen werden, ohne Schulden zurückzuzahlen.
Hintergrund
Panoptic ist ein dezentrales Protokoll für den Handel mit ewigen Optionen, das auf Ethereum aufbaut und Benutzern den Handel mit Put- und Call-Optionen ermöglicht.
Die Funktion withdraw() hat einen Eingabeparameter positionList, der aus einer Menge von tokenIds besteht. Jede tokenId repräsentiert eine Position. Die Funktion withdraw() prüft den Schuldenstatus jeder Position basierend auf s_positionsHash und ruft dann die Sicherheiten des Benutzers ab.
Um Gas zu sparen, speichert das Protokoll nicht jede Position (d. h. tokenId) des Benutzers. Stattdessen berechnet es einen Fingerabdruck basierend auf allen tokenIds des Benutzers und zeichnet ihn in s_positionsHash auf. Die höchsten 8 Bits jedes s_positionsHash stellen numLegs dar, während die unteren 248 Bits den user position hash darstellen.
Für jede übergebene tokenId berechnet das Protokoll deren Hash, nimmt die unteren 248 Bits und aktualisiert den user position hash durch eine bitweise XOR-Operation mit den unteren 248 Bits des aktuellen s_positionsHash.
Gleichzeitig wird countLegs basierend auf dem numerischen Bereich der tokenId angepasst: Es bleibt unverändert, wenn die tokenId kleiner als ist, und erhöht sich um 1, 2 oder 3, wenn sie in den Bereichen , bzw. liegt. Dies wird schließlich in die obersten 8 Bits von s_positionsHash geschrieben, um numLegs zu aktualisieren.
Schwachstellenanalyse
Die Grundursache liegt in einem Fehler im Algorithmus des Vertrags zur Erstellung von s_positionsHash, insbesondere der Verwendung der XOR-Operation zur Aggregation von Keccak256-Hash-Ergebnissen. Während eine einzelne Hash-Funktion sicher bleibt, macht die mathematische Linearität der XOR-Operation den gesamten Fingerabdruck-Algorithmus (d. h. die XOR-Summe von Hashes) unsicher [2].
Linearität bedeutet, dass ein Angreifer die Hash-Funktion selbst nicht brechen muss (d. h. die tokenId aus dem Hash umkehren). Stattdessen können sie eine kombinatorische Strategie anwenden: die Generierung einer großen Anzahl zufälliger tokenIds, die Berechnung ihrer Keccak256(tokenId) und aus diesen Hash-Werten die Auswahl einer bestimmten Teilmenge, sodass die XOR-Summe dieser tokenId-Hashes exakt dem Ziel-Fingerabdruck des Opfers entspricht.
Dies ermöglicht es einem Angreifer, beim Aufruf von withdraw() eine Reihe gefälschter tokenIds zu übergeben, um den Gesundheitscheck zu bestehen und die gesamte Sicherheit zu erhalten, die s_positionsHash entspricht.
Theorie
Angenommen, der Positionsfingerabdruck s_positionsHash des Benutzers hat einen user position hash von und numLegs von mit Benutzer-tokenIds . Somit:
Hier kann jeder 248-Bit-Hash-Wert als 248-dimensionaler Vektor betrachtet werden.
Daher liegt in einem 248-dimensionalen Raum, der aus 0en und 1en besteht (). In diesem Raum ist die XOR-Operation äquivalent zur Vektoraddition (Anhang I).
Das Ziel des Angreifers ist es, 248-dimensionale Vektoren aus allen verfügbaren Vektoren zu finden, sodass die unteren 248 Bits ihrer XOR-Summe gleich sind. Somit können wir das Ziel des Angreifers als System linearer Gleichungen formulieren:
Insbesondere müssen wir nicht direkt konstruieren. Stattdessen wählen wir linear unabhängige Hash-Vektoren (wobei der Dimension 248 entspricht) und verwenden sie als Spaltenvektoren, um eine -Matrix zu konstruieren:
Das Problem verwandelt sich dann in die Suche nach einem Koeffizientenvektor , sodass:
Wobei und .
Gemäß der Theorie der linearen Algebra, solange die Matrix vollen Rang hat, spannt sie den gesamten -dimensionalen Raum auf. Das bedeutet, dass für jedes Ziel das Gleichungssystem eine eindeutige Lösung hat. Nach der Lösung von behalten wir einfach die Vektoren bei, für die gilt; ihre XOR-Summe ist .
Beispiel
Zur besseren Verständlichkeit demonstrieren wir diesen Konstruktionsprozess anhand einer Fallstudie. Angenommen, die Vektoren sind 3-dimensional, jede Dimension besteht nur aus 0 oder 1 und der Ziel-Hash-Wert ist 101, d. h. .
Als Nächstes generieren wir zufällig 3 Hash-Werte:
Wir konstruieren die Matrix mit diesen drei Vektoren als Spalten und stellen die Gleichung auf:
Durch Gauß-Eliminierung erhalten wir . Das bedeutet, wir müssen und auswählen (entsprechend ), und ihre XOR-Summe ergibt exakt .
Auswahl von n linear unabhängigen Vektoren
Wie bereits erwähnt, müssen wir zur Lösung von eine vollrangige Matrix konstruieren. Da wir es mit einem extrem großen Vektorraum zu tun haben (), stellt sich die Kernfrage: Wie wählen wir schnell linear unabhängige Vektoren aus diesem riesigen Raum aus?
Betrachten wir die einfachste Methode: zufällige Generierung von tokenIds und Auswahl ihrer Hash-Ergebnisse als Vektoren.
Über beträgt die Wahrscheinlichkeit , dass zufällig ausgewählte -dimensionale Vektoren eine vollrangige Matrix bilden:
Wenn groß ist (in diesem Beispiel ), konvergiert diese Wahrscheinlichkeit gegen eine Konstante (Anhang II):
Das bedeutet, jeder zufällige Versuch hat eine Erfolgswahrscheinlichkeit von etwa 28,9 %. Im Durchschnitt benötigt ein Angreifer nur etwa 3,5 Versuche, um eine Menge linear unabhängiger Vektoren zu finden. Daher sind die Rechenkosten extrem gering, und der Angreifer kann schnell eine Matrix konstruieren, die die Bedingungen erfüllt.
Um countLegs in den obersten 8 Bits zu steuern, müssen wir nur den Bereich der zufällig generierten tokenId-Werte basierend auf dem Ziel-countLegs anpassen.
Wenn wir beispielsweise möchten, dass numLegs im gefälschten Fingerabdruck 0 ist, stellen wir einfach sicher, dass die zufällig generierten tokenIds kleiner als sind. Da die Beinvermehrung für tokenIds in diesem Bereich 0 ist, wird die endgültige akkumulierte numLegs zwangsläufig 0 sein, unabhängig davon, welche Vektoren die Gauß-Eliminierungslösung auswählt.
Angriffsanalyse
Der White-Hat-Retter initiierte mehrere Rettungstransaktionen. Der Einfachheit halber basiert die folgende Diskussion auf einer einzigen dieser Transaktionen [3].
Die Kernlogik besteht aus den folgenden 5 Schritten:
- Leihen von 0,23e8 WBTC und 28e18 WETH über einen Flash-Loan von Aave.
- Einzahlung von 0,23e8 WBTC und 28e18 WETH in den poWBTC-Vertrag und den 0x1f8d_poWETH-Vertrag.
- Aufruf von
mintOptions()desPanopticPool-Vertrags mit einer normalenpositionIdList, um Gelder zu leihen und eine gehebelte Position zu eröffnen. - Aufruf von
withdraw()unter Übergabe der gefälschtentokenIds. Da diese gefälschten Positionen einepositionSizevon 0 haben, gibt die FunktiontokenRequiredals 0 zurück, was bedeutet, dass die für alle Positionen erforderliche Gesamtsicherheit fälschlicherweise als null berechnet wird. In der Zwischenzeit ist der von diesentokenIds generiertes_positionsHashexakt derselbe wie der in Schritt 3 generierte, was es dem Retter ermöglicht, alle Sicherheiten ohne Rückzahlung von Schulden abzuziehen. - Rückzahlung des Flash-Loans und Ausführung der nächsten Runde.
Zusammenfassung
Dieser Vorfall hebt zwei sich gegenseitig verstärkende Fehler hervor, die zusammen einen unbefugten Abzug von Sicherheiten ermöglichten.
- XOR ist keine sichere Aggregationsfunktion für Hashes. Keccak256 ist kollisionsresistent, aber die Linearität von XOR bedeutet, dass die XOR-Summe mehrerer Hashes diese Eigenschaft nicht erbt. Die Konstruktion einer Menge von Eingaben, deren Hashes zu einem beliebigen Zielwert XOR-summiert werden, reduziert sich auf die Lösung eines Systems linearer Gleichungen über , was rechnerisch trivial ist. Hash-Komposition erfordert Operationen, die die Kollisionsresistenz erhalten, wie z. B. Konkatenation gefolgt von Neuhash.
- Fehlende Validierung von Positions-IDs. Das Protokoll überprüfte nicht, ob übergebene
positionIds gültigen Optionspositionen entsprachen. Werte unter tragen einencountLegsvon 0 und einepositionSizevon 0, was bedeutet, dass die gefälschten Positionen keine Schulden verursachen. Dies ermöglichte es dem Angreifer, den Gesundheitscheck mit einer Sicherheitenanforderung von Null zu bestehen und gleichzeitig den Ziel-Fingerabdruck zu matchen.
Referenz
Anhang
Die folgenden beiden Anhänge bieten eine mathematische Erklärung und einen Beweis für die Aussagen im Haupttext, nämlich dass die XOR-Operation äquivalent zur Vektoraddition ist (Anhang I) und die Wahrscheinlichkeit, dass eine zufällige Matrix vollen Rang hat (Anhang II).
Anhang I
Im endlichen Körper ist die Addition als Addition modulo 2 definiert:
Die Beobachtung zeigt, dass dies identisch mit der logischen Operation Exklusiv-Oder (XOR, Symbol ) ist.
Für den -dimensionalen Vektorraum (in diesem Fall ) ist die Addition zweier Vektoren und als komponentenweise Addition modulo 2 definiert:
Daher ist im Vektorraum die Vektoraddition äquivalent zur bitweisen XOR-Operation auf den Vektorkomponenten.
Anhang II
Um die Matrix vollrangig zu machen, müssen diese Vektoren linear unabhängig sein.
Der erste Vektor kann jeder Vektor in außer dem Nullvektor sein, was Auswahlmöglichkeiten bietet; der zweite Vektor darf nicht im von aufgespannten Unterraum liegen, der Vektoren enthält, was Auswahlmöglichkeiten übrig lässt; dieser Logik folgend darf der -te Vektor nicht im von den vorherigen Vektoren aufgespannten Unterraum liegen, was zu möglichen Auswahlmöglichkeiten führt.
Die Gesamtzahl solcher Matrizen (d. h. die Ordnung von ) ist:
Und die Gesamtzahl aller möglichen -Matrizen ist .
Somit ist die Wahrscheinlichkeit :
Wenn wir setzen, können wir diesen Ausdruck umschreiben als:
Wenn , konvergiert dieses Produkt gegen eine Konstante:
Das bedeutet, dass für große die Wahrscheinlichkeit, dass eine zufällige Matrix vollen Rang hat, etwa 28,9 % beträgt.
Über BlockSec
BlockSec ist ein Anbieter von Blockchain-Sicherheit und Krypto-Compliance. Wir entwickeln Produkte und Dienstleistungen, die Kunden bei der Durchführung von Code-Audits (einschließlich Smart Contracts, Blockchain und Wallets), der Echtzeit-Abwehr von Angriffen, der Analyse von Vorfällen, der Verfolgung illegaler Gelder und der Erfüllung von AML/CFT-Verpflichtungen während des gesamten Lebenszyklus von Protokollen und Plattformen unterstützen.
BlockSec hat mehrere Blockchain-Sicherheitsarbeiten auf renommierten Konferenzen veröffentlicht, mehrere Zero-Day-Angriffe von DeFi-Anwendungen gemeldet, mehrere Hackerangriffe blockiert, um mehr als 20 Millionen Dollar zu retten, und Kryptowährungen im Wert von mehreren Milliarden Dollar gesichert.
-
Offizielle Website: https://blocksec.com/
-
Offizielles Twitter-Konto: https://twitter.com/BlockSecTeam



