Am 3. August 2023 wurde ein MEV Bot auf Arbitrum angegriffen, was zu einem Schaden von 800.000 US-Dollar führte. Die Hauptursache dieses Angriffs war unzureichende Überprüfung von Benutzereingaben.
Angesichts der komplexen Interaktionen zwischen MEV Bots und ihren Verträgen, die nicht verifiziert sind, zeigt sich, dass Nicht-Open-Source-Code keine Sicherheit garantiert, insbesondere für DeFi-Protokolle.
Hintergrund
MEV Bot
Ein MEV Bot (Maximum Extractable Value Bot) ist darauf ausgelegt, profitable Gelegenheiten auf der Blockchain zu identifizieren und auszuführen. Er operiert, indem er ausstehende Transaktionen (d. h. im Mempool) oder On-Chain-Zustände analysiert, um Gewinne durch Arbitrage zu erzielen.
Im Gegensatz zu typischen Frontrunning- und Sandwich-Attacken-MEV-Bots konzentrierte sich der in diesem Angriff angegriffene MEV Bot auf die Ausführung von Strategien wie Dreiecksarbitrage und Schuldenliquidierung. Diese Bots selbst tragen zur Preisstabilisierung für AMMs bei und unterstützen Kreditprotokolle bei der Liquidation, um einen reibungslosen Betrieb zu gewährleisten, und stellen damit einen wesentlichen Bestandteil der gesunden Funktionsweise des DeFi-Ökosystems dar.
Flashloan
Flashloans stellen eine einzigartige Innovation im DeFi-Ökosystem dar – eine Form der unbesicherten Kreditvergabe. Sie können über Flashloans bis zu einer Milliarde Dollar ohne Sicherheiten leihen, vorausgesetzt, der Kredit wird innerhalb derselben Transaktion zurückgezahlt. Wird der Kredit nicht innerhalb dieser Transaktion zurückgezahlt, wird er rückgängig gemacht, als ob die Transaktion nie stattgefunden hätte.
Dieser Mechanismus wird üblicherweise für Arbitrage oder zur Nutzung anderer DeFi-Strategien verwendet, um temporäre Marktineffizienzen auszunutzen.
Die Schwachstelle
Kurzfassung
Die unzureichende Validierung von Benutzereingabeparametern ermöglichte es dem Angreifer, einen FakeFlashloanProvider einzuschleusen. Der Vault-Vertrag nutzte diesen Provider, um einen Flashloan zu initiieren. Anschließend genehmigte der Vault-Vertrag Tokens an den FakeFlashloanProvider, möglicherweise zur Begleichung des Flashloans, was zur unbefugten Übertragung von Vermögenswerten aus dem Vault führte.
Ausführliche Version
Der ausgenutzte Vertrag ist:
Vault: Der betroffene Vertrag 0xd614927acfb9744441180c2525faf4cedb70207f dient als „Vault“, der Reserven bereitstellt und Flashloans von anderen Protokollen wie AAVE und Balancer ermöglicht.Arbitrage Bot: Der anfällige Vertrag 0x8db0efee6a7622cd9f46a2cf1aedc8505341a1a7, der als „Arbitrage Bot“ fungiert, hält die Kreditnehmerrolle im „Vault“-Vertrag inne.
Die Funktion 0x0582f20f() im „Arbitrage Bot“ ist der Haupteinstiegspunkt für die Auslösung von Arbitragen.
Sie ruft zunächst borrow() im „Vault“ auf, um den ursprünglichen Kapitalbetrag zu erhalten, und führt dann die Arbitrage-Logik über einen delegatecall an einen externen Vertrag aus, der in den Calldata spezifiziert ist und keiner Validierung unterliegt.
function 0x0582f20f(...) {
...
v67, /* uint256 */ v68 = address(0xd614927acfb9744441180c2525faf4cedb70207f).borrow(address(v39), address(v9[0]), v29).gas(msg.gas);
...
// 0x4da91757 = swap(address,address,address,uint256,uint256,uint256,address)
MEM[MEM[64] + 32] = uint224(address(MEM[0 + v4[v69]])) | 0x4da9175700000000000000000000000000000000000000000000000000000000;
v82 = address(v76 >> 96).delegatecall(MEM[(MEM[64]) len 228], MEM[(MEM[64]) len 0]).gas(msg.gas);
...
v189 = v170.refund(0x410085df, address(v9[0]), address(v39), v68, address(v9[0]), v29, v186, 4 + MEM[64] + (varg2.length << 5) - (4 + MEM[64]) + 192).gas(msg.gas);
...
}
Anschließend ruft sie 0x512b7351() im „Vault“ auf und startet einen Flashloan an den FakeFlashloanProvider-Vertrag des Angreifers.
Die Funktion 0x512b7351() verlangt, dass msg.sender auf der Whitelist steht, aber dies wurde durch den vorherigen delegatecall erfolgreich umgangen, wodurch die Prüfung umgangen wurde. Dies ist ein sehr kritischer Schritt.
function 0x512b7351(...) public nonPayable {
...
if (_borrow[msg.sender] >= 1) {
v0 = !_refund;
}
require(v0, Error('BBVault: FORBIDDEN'));
...
v38 = v23.length;
v39 = v23.data;
_refund = keccak256(v23);
...
<FakeFalshloanProvider>.flashloan(...);
...
}
Während des Flashloan-Callbacks überweist die executeOperation() im „Vault“ zunächst die geliehenen Vermögenswerte an den „Arbitrage Bot“ MEVBot 0x8db0ef und ruft dann dessen 0x7fe3ba8b() auf.
function executeOperation(...) {
...
require(_refund == keccak256(v3.data), Error('BBVault: STATUS'));
Token.transfer(ArbitrageBot, amountBorrowed);
<ArbitrageBot>.call(0x7fe3ba8b...);
}
Der „Arbitrage Bot“ vertraut diesem externen Aufruf und überweist die erhaltenen Vermögenswerte an den FakeFlashloanProvider zurück.
Der „Vault“ erkennt dies jedoch nicht und erteilt dem FakeFlashloanProvider weiterhin eine Genehmigung zur Rückzahlung des Flashloans am Ende von executeOperation().
Der Angriffsprozess
Angriffstransaktion: 0x864c8cfb8c54d3439613e6bd0d81a5ea2c5d0ad25c9af11afd190e5ea4dcfc1f
Der Angreifer ruft 0x0582f20f() des „Arbitrage Bot“ auf, der wiederum einen Delegate Call an den Vertrag des Angreifers durchführt.


Der hack_contract_2 ruft dann die Funktion 0x512b7351() des Opfers auf. 0x512b7351() erfordert, dass msg.sender auf der Whitelist steht, aber dies wurde durch den vorherigen delegatecall erfolgreich umgangen, wodurch die Prüfung umgangen wurde.

Das Opfer ruft dann den FakeFlashloanProvider-Vertrag des Angreifers auf, überträgt alle geliehenen Vermögenswerte an das Opfer und ruft executeOperation() des Opfers auf.

Die Funktion 0x7fe3ba8b() des Arbitrage Bots führt erneut einen delegatecall an den Vertrag des Angreifers durch, diesmal werden alle Vermögenswerte zurück an den Angreifer übertragen.
Zu diesem Zeitpunkt wurden die vom Flashloan Provider des Angreifers geliehenen Vermögenswerte zurückgezahlt.

Das Opfer („Vault“) genehmigt Token für den FakeFlashloanProvider, möglicherweise mit der Absicht, den Flashloan zurückzuzahlen.

Der Angreifer nutzt diese Genehmigung aus, um Gewinne zu erzielen, indem er transferFrom verwendet, um Gelder vom Opfer abzuziehen.
Sicherheitsempfehlungen
Nicht-Open-Source-Code garantiert keine Sicherheit
Die Annahme, dass nicht-Open-Source und obfuskierter Code Sicherheit gewährleistet, ist ein Trugschluss. Dieser MEV Bot-Vorfall zeigt, dass Geheimhaltung nicht vor Exploits schützt und Entwicklern ein falsches Gefühl der Sicherheit vermitteln kann.
Strikte Eingabevalidierung
Es ist unerlässlich, alle Vertragsinteraktionen und Calldata sorgfältig zu validieren, insbesondere wenn Standardinterfaces wie Flashloan- und Swap-Callbacks verwendet werden. Die Gewährleistung der Datenintegrität und Sicherheit sollte bei der Vertragsgestaltung und -implementierung Priorität haben.
Lesen Sie weitere Artikel dieser Serie:
- Einführung: Die zehn "großartigen" Sicherheitsvorfälle im Jahr 2023
- #1: Ernte von MEV Bots durch Ausnutzung von Schwachstellen im Flashbots Relay
- #2: Euler Finance Vorfall: Der größte Hack des Jahres 2023
- #3: KyberSwap Vorfall: Meisterhafte Ausnutzung von Rundungsfehlern mit extrem subtilen Berechnungen
- #4: Curve Vorfall: Compilerfehler erzeugt fehlerhaften Bytecode aus unschuldigem Quellcode
- #5: Platypus Finance: Überleben von drei Angriffen mit einem glücklichen Zufall
- #6: Hundred Finance Vorfall: Katalysator für die Welle präzisionsbezogener Exploits in anfälligen Fork-Protokollen
- #7: ParaSpace Vorfall: Ein Wettlauf gegen die Zeit, um den bisher kritischsten Angriff der Branche abzuwehren
- #8: SushiSwap Vorfall: Ein ungeschickter Rettungsversuch führt zu einer Reihe von Nachahmungsangriffen
- #10: ThirdWeb Vorfall: Inkompatibilität zwischen vertrauenswürdigen Modulen legt Schwachstelle offen



