#4 GMX Vorfall: Cross-Contract Reentrancy umgeht vier Jahre alte Absicherung

#4 GMX Vorfall: Cross-Contract Reentrancy umgeht vier Jahre alte Absicherung

Am 9. Juli 2025 erlebte die dezentrale Perpetual-Plattform GMX einen Exploit [1, 2], der auf ihren V1-Vertrag im Arbitrum-Netzwerk abzielte und zu einem Verlust von etwa 42 Millionen US-Dollar führte. Der Angreifer nutzte eine Cross-Contract Reentrancy-Schwachstelle aus, um den GLP-Preis zu manipulieren und dann mit dem verzerrten Preis die zugrunde liegenden Vermögenswerte aus den Liquiditätspools von GMX V1 abzuziehen.

Hintergrund

GMX V1 [3] ist eine dezentrale Perpetual-Trading-Plattform, die auf Arbitrum eingesetzt wird. Sie ermöglicht es Benutzern, Perpetual-Kontrakte auf mehreren Krypto-Assets mit Hebelwirkung auf erlaubnisfreie und nicht-verwahrte Weise zu handeln. GMX V1 folgt einem einzigen Multi-Asset-Pool-Design, bei dem die Liquidität für alle unterstützten Assets in einem einheitlichen Vault-System aggregiert wird.

Positionsmanagement in GMX

Das Positionsmanagement in GMX ist ein zweistufiger Prozess. Insbesondere erstellen Benutzer Erhöhungs-/Verringerungsaufträge, indem sie mit den Verträgen OrderBook oder PositionRouter interagieren. Anschließend führt ein autorisiertes Keeper-Konto die Aufträge der Benutzer aus, was die globalen Short-Daten im Vertrag ShortTracker und den entsprechenden Zustand des Vertrags Vault aktualisiert. Die folgenden beiden Abbildungen veranschaulichen die beiden Ausführungspfade (die Pfade Orderbook-Execution und Router-Execution) für die Verwaltung von Positionen in GMX. Bei diesem Vorfall nutzte der Angreifer beide Pfade, um die globalen Short-Daten zu manipulieren und Gewinne zu realisieren.

Der Orderbook-Execution-Pfad

Der Router-Execution-Pfad

GMX Vault

Der Vertrag Vault in GMX ist für die Verwaltung der Positionen und Vermögenswerte der Benutzer verantwortlich (z. B. die Finalisierung von Gewinn und Verlust). Um böswillige Interaktionen zu vermeiden, ist der Vertrag Vault nur zugänglich, wenn das "Hebel-Fenster" geöffnet ist (d. h. die Variable isLeverageEnabled im Vertrag Vault ist über die Funktion Timelock.enableLeverage() auf true gesetzt). Diese Validierung erzwingt, dass die Auftragsausführung den festgelegten Pfaden (orderbook-execution und router-execution) folgen muss.

GMX Short Tracker

Der Vertrag ShortTracker ist für die Verfolgung und Aktualisierung der globalen Short-Daten (z. B. der Variable globalShortAveragePrice) während der Auftragsausführung verantwortlich. Gemäß den Pfaden orderbook-execution und router-execution wird die Funktion updateGlobalShortData() des Vertrags ShortTracker vor der Ausführung der Aufträge der Benutzer aufgerufen, um die neuesten globalen Short-Daten zu synchronisieren. Dieser Schritt stellt die korrekte Gewinn- und Verlustrealisierung für die Positionen der Benutzer sicher.

Verringerung der WETH-Position

Im Gegensatz zu anderen Aufträgen löst die Verringerung der WETH-Position über den Pfad orderbook-execution den Aufruf der Funktion _transferOutETH() im Vertrag OrderBook aus, um WETH-Token abzuheben und native ETH-Token an die Benutzer zu übertragen. Wenn der Empfänger _receiver ein Vertrag ist, kann sendValue() die fallback()-Funktion des Vertrags auslösen und so eine potenzielle Reentrancy-Schwachstelle einführen. Bei diesem Vorfall nutzte der Angreifer diese Reentrancy-Schwachstelle wiederholt aus, um erhebliche Gewinne zu erzielen.

GLP-Token

Das GLP (GMX Liquidity Provider)-Token repräsentiert die vereinigten Anteile an verschiedenen Vermögenswerten im Vault-Vertrag. Benutzer können Vermögenswerte bereitstellen und einlösen, indem sie GLPs prägen und verbrennen.

Der GLP-Preis kann mit den folgenden Gleichungen berechnet werden:

GLPPreis=AUMGLPGesamte Auflage\text{GLPPreis}= \frac{\text{AUM}}{\text{GLPGesamte Auflage}}

AUM=i=Asset[0]Assets(ΔGlobalShort[i]+AUMAndere[i])\text{AUM} = \sum^{Assets}_{i = Asset[0]}(\Delta_{\text{GlobalShort[i]}} + \text{AUM}_{\text{Andere[i]}})

ΔGlobalShort[i]=globaleShortGro¨ße×(AssetMarktpreisglobalerShortDurchschnittspreis)globalerShortDurchschnittspreis\Delta_{\text{GlobalShort[i]}} = \frac{ \text{globaleShortGröße} \times (\text{AssetMarktpreis} - \text{globalerShortDurchschnittspreis} ) }{ \text{globalerShortDurchschnittspreis} }

Wo:

  • GLPTotalSupply steht für die Gesamtauflage der GLP-Token.
  • AUM besteht aus den folgenden beiden Komponenten.
    • ΔGlobalShort\Delta_{\text{GlobalShort}} repräsentiert den uPnL (d. h. den nicht realisierten Gewinn und Verlust) aller Short-Positionen.
    • AUMOther\text{AUM}_{\text{Other}} repräsentiert die bereitgestellte Liquidität des LP zuzüglich des nicht realisierten uPnL aller Long-Positionen. Dieser Term blieb während des Vorfalls vor der Gewinnrealisierung nahezu unverändert.
  • AssetMarketPrice ist der Marktpreis (in USD) des zugrunde liegenden Vermögenswerts.
  • globalShortSize ist die Summe (in USD) aller Short-Positionen.
  • globalShortAveragePrice ist der durchschnittliche Einstiegspreis der aggregierten globalen Short-Position.

Bei diesem Vorfall verzerrte der Angreifer den globalShortAveragePrice, um den GLP-Preis zu manipulieren und Gewinne zu erzielen.

Schwachstellenanalyse

Die Hauptursache ist eine Cross-Contract Reentrancy-Schwachstelle im Vertrag OrderBook. Wie im Hintergrund beschrieben, löst die Verringerung von WETH-Positionen über den Pfad orderbook-execution einen Low-Level-Fallback-Aufruf an den Empfänger über _transferOutETH() aus. Die Funktion trägt einen nonReentrant-Modifikator, aber dieser Schutz verhindert nur die Reentrancy innerhalb des OrderBook-Vertrags selbst, nicht aber Cross-Contract-Aufrufe an den Vault.

Im normalen Betrieb kann die increasePosition()-Funktion des Vault nur über PositionRouter und PositionManager aufgerufen werden, die ShortTracker aufrufen, um globalShortAveragePrice vor jeder Positionsänderung zu aktualisieren. Der Angreifer erstellte Aufträge mit einem bösartigen Vertrag als Empfänger und rief während des Fallback-Aufrufs direkt increasePosition() im Vault auf, wobei PositionRouter/PositionManager und die zugehörige ShortTracker-Aktualisierung umgangen wurden. Durch wiederholtes Öffnen und Schließen von Short-Positionen ohne Aktualisierung von globalShortAveragePrice verzerrte der Angreifer schrittweise die Variable. Der verzerrte Wert blähte den GLP-Preis auf, wodurch der Angreifer Gewinne durch Prägung und Einlösung von GLPs erzielen konnte.

Angriffsanalyse

Der Angreifer startete eine Reihe von Transaktionen, die die globalen Short-Daten manipulierten und den Gewinn realisierten. Insbesondere kann dieser Vorfall in drei Phasen unterteilt werden: Vorbereitung, Preismanipulation und Gewinnrealisierung. Alle zugehörigen Transaktionen sind in der folgenden Tabelle aufgeführt.

Tx Nr. Phase Beschreibung Transaktion Zeit (UTC)
1 Vorbereitung Bereitstellung des Angriffskontrakts 0xa4ece5...8cd4c93f 09. Juli 2025 12:16:32 Uhr
2 Erstellung eines WETH-Long-Orders zur Erhöhung 0x0b8cd6...e90a4712 09. Juli 2025 12:22:28 Uhr
3 Ausführung des WETH-Long-Orders zur Erhöhung 0x28a000...7bf0beef 09. Juli 2025 12:23:23 Uhr
4 Erstellung eines WETH-Long-Orders zur Verringerung 0x20abfe...decc49af 09. Juli 2025 12:24:56 Uhr
5 Preismanipulation 1 Ausführung des WETH-Long-Orders zur Verringerung 0x1f00da...6a4a7353 09. Juli 2025 12:25:37 Uhr
6 Ausführung des WBTC-Short-Orders zur Verringerung 0x222cda…c994464e 09. Juli 2025 12:25:43 Uhr
7 Preismanipulation 2 Wie Tx 5 0xc9a469...221293c2 09. Juli 2025 12:26:25 Uhr
8 Wie Tx 6 0x1cbf25...d853943a 09. Juli 2025 12:26:30 Uhr
9 Preismanipulation 3 Wie Tx 5 0xb58415...3b4cfb0b 09. Juli 2025 12:27:22 Uhr
10 Wie Tx 6 0x5a37ff...cb59c3b7 09. Juli 2025 12:27:28 Uhr
11 Preismanipulation 4 Wie Tx 5 0xff6fe6...377bf108 09. Juli 2025 12:28:13 Uhr
12 Wie Tx 6 0xbd65d6...e0187be6 09. Juli 2025 12:28:18 Uhr
13 Preismanipulation 5 Wie Tx 5 0x105273...19fcdec6 09. Juli 2025 12:29:12 Uhr
14 Wie Tx 6 0x0cdbac...84339fcc 09. Juli 2025 12:29:17 Uhr
15 Gewinnrealisierung Gewinnrealisierung 0x03182d....a32626ef 09. Juli 2025 12:30:11 Uhr
16 Rückerstattung Nachricht an den Angreifer 0x92a39e...89547380 09. Juli 2025 14:04:19 Uhr
17 Antwort auf das GMX-Protokoll 0x1d806c...919feac0 11. Juli 2025 06:29:00 Uhr
18 Antwort an den Angreifer 0x9c4ca9...39fa27fc 11. Juli 2025 07:42:17 Uhr
19 Rückerstattung 0x62b845...99211841 11. Juli 2025 08:04:34 Uhr
20 Rückerstattung 0x255d0a...9321b3 11. Juli 2025 08:08:27 Uhr
21 Rückerstattung 0xceafc3...a6313b22 11. Juli 2025 10:17:23 Uhr

Vorbereitungsphase

  1. (Tx 1) Der Angreifer stellte den Angriffskontrakt bereit, der als Empfänger von Vermögenswerten während der Auftragsausführung dient. Der Angriffskontrakt enthielt eine bösartige fallback()-Funktion.

  2. (Tx 2) Der Angreifer erstellte im Vertrag OrderBook einen WETH-Long-Order zur Erhöhung für den Angriffskontrakt.

  3. (Tx 3) Ein Keeper führte den Erhöhungsauftrag des Angreifers (erstellt in Schritt 2) aus, der eine WETH-Long-Position für den Angriffskontrakt eröffnete. (Tx 3).

  4. (Tx 4) Der Angreifer erstellte im Vertrag OrderBook einen WETH-Long-Order zur Verringerung für den Angriffskontrakt.

Manipulationsphase

  1. (Tx 5) Ein Keeper führte den WETH-Long-Order zur Verringerung des Angriffskontrakts (erstellt in Schritt 4) über den Pfad orderbook-execution aus. Die Ausführung löste die bösartige fallback()-Funktion im Angriffskontrakt aus.

    Da fallback() während des "Hebel-Fensters" aufgerufen wurde, interagierte der Angriffskontrakt direkt mit dem Vertrag Vault, um eine WBTC-Short-Position zu eröffnen (über increasePosition()), ohne globalShortAveragePrice zu aktualisieren, und erstellte anschließend einen WBTC-Short-Order zur Verringerung/Schließung.

  2. (Tx 6) Ein Keeper führte den WBTC-Short-Order zur Verringerung (erstellt in Schritt 5) über den Pfad router-execution aus. Die Ausführung erstellte über den Fallback-Mechanismus im Vertrag PositionRouter auch einen WETH-Long-Order zur Verringerung.

    Da die WBTC-Short-Position ohne Aktualisierung von globalShortAveragePrice eröffnet wurde, verursachte die Schließung der Position bei gleichzeitiger Aktualisierung der Variablen einen unerwarteten Rückgang von globalShortAveragePrice.

  3. (Tx 7-14) Der Angreifer wiederholte die Schritte 5-6 viermal. Infolgedessen wurde globalShortAveragePrice von 1,08e35 auf 1,9e33 verzerrt.

Gewinnrealisierungsphase

  1. (Tx 15) Ein Keeper führte den WETH-Long-Order zur Verringerung (erstellt in Tx 14) über den Pfad orderbook-execution aus. Diese Ausführung löste aufgrund der Reentrancy-Schwachstelle im Vertrag OrderBook die Gewinnrealisierungslogik im Angriffskontrakt aus.

    1. Bei der Fallback-Ausführung borgte sich der Angriffskontrakt zunächst einen Flash-Loan von 7.538.567e18 USDC.

    2. Der Angriffskontrakt rief mintAndStakeGlp() auf, um 4.129.578e18 GLPs unter Verwendung von 6.000.000e18 USDC zu prägen.

    3. Der Angriffskontrakt rief Vault.increasePosition() auf, um eine WBTC-Short-Position mit den verbleibenden 1.538.567e18 USDC zu eröffnen. Da die globalen Short-Daten von WBTC extrem verzerrt waren, verstärkte die Auftragsausführung den AUM erheblich und erhöhte den GLP-Preis rapide.

    4. Der Angriffskontrakt rief unstakeAndRedeemGlp() auf, um GLPs zum erhöhten Preis gegen mehrere Vermögenswerte im Vertrag Vault einzulösen.

    5. Der Angriffskontrakt rief Vault.decreasePosition() auf, um die WBTC-Short-Position zu schließen.

    6. Der Angriffskontrakt wiederholte die Schritte 8.b-8.e viermal, um alle Vermögenswerte im Vertrag Vault abzuziehen.

    7. Der Angriffskontrakt zahlte den Flash-Loan mit einem Gewinn von fast 42 Millionen US-Dollar zurück.

Rückerstattung

Nach Verhandlungen mit dem Angreifer (Tx 16-18) akzeptierte der Angreifer schließlich eine 10%ige Prämie und gab die restlichen gestohlenen Vermögenswerte zurück (Tx 19-21).

Zusammenfassung

Dieser Vorfall beinhaltete einen mehrstufigen Exploit gegen GMX V1 auf Arbitrum, der zu einem geschätzten Verlust von 42 Millionen US-Dollar führte. Der Angreifer nutzte eine Reentrancy-Schwachstelle im Vertrag OrderBook aus, um die Variable globalShortAveragePrice zu verzerren und den GLP-Preis aufzublähen. Durch die Ausnutzung des manipulierten Preises zog der Angreifer eine beträchtliche Menge an Vermögenswerten ab.

Wichtige Lektionen:

  • Cross-Contract Reentrancy: Ein nonReentrant-Modifikator in einem einzelnen Vertrag verhindert nicht die Reentrancy in andere Verträge desselben Systems. Zugriffskontrollmechanismen, die auf einer temporären Flagge beruhen (z. B. das "Hebel-Fenster"), können umgangen werden, wenn ein externer Aufruf erfolgt, bevor die Flagge zurückgesetzt wird.
  • Betriebssicherheit: Dieser Angreifer nutzte das Protokoll in drei verschiedenen Phasen aus und führte insgesamt 15 Transaktionen durch. Dieser Vorfall unterstreicht die kritische Notwendigkeit einer Echtzeitüberwachung, schneller Warnungen und effektiver Abhilfemaßnahmen.

Referenz

  1. https://x.com/GMX_IO/status/1942955807756165574
  2. https://x.com/GMX_IO/status/1943336664102756471
  3. GMX V1

Über BlockSec

BlockSec ist ein Full-Stack-Anbieter für Blockchain-Sicherheit und Krypto-Compliance. Wir entwickeln Produkte und Dienstleistungen, die Kunden bei der Code-Prüfung (einschließlich Smart Contracts, Blockchain und Wallets), der Echtzeit-Abwehr von Angriffen, der Analyse von Vorfällen, der Rückverfolgung von illegalen Geldern und der Erfüllung von AML/CFT-Verpflichtungen über den gesamten Lebenszyklus von Protokollen und Plattformen hinweg unterstützen.

BlockSec hat mehrere Blockchain-Sicherheitsarbeiten auf renommierten Konferenzen veröffentlicht, mehrere Zero-Day-Angriffe von DeFi-Anwendungen gemeldet, mehrere Hacks blockiert, um mehr als 20 Millionen Dollar zu retten, und Kryptowährungen im Wert von Milliarden gesichert.

Sign up for the latest updates