Von: 九九
Hintergrund
Am 5. Dezember 2023 gab die Web3-Basisentwicklungsplattform Thirdweb bekannt, dass im vorgefertigten Smart Contract ein Sicherheitsproblem festgestellt wurde und alle ERC20-, ERC721- und ERC1155-Token, die mit dem vorgefertigten Smart Contract bereitgestellt wurden, betroffen seien. (Informationen zu bestimmten betroffenen Vertragscodeversionen finden Sie unter: https://blog.thirdweb.com/security-vulnerability/)

Nach Angaben des SlowMist-Sicherheitsteams wurde am 7. Dezember 2023 der Time-Token im ETH-Mainnet genau wegen dieser Schwachstelle angegriffen und der Angreifer erzielte einen Gewinn von etwa 190.000 US-Dollar. Es gibt immer noch viele Token-Verträge mit angegriffenen Schwachstellen. Das SlowMist-Sicherheitsteam hat sofort in die Analyse eingegriffen und die Ergebnisse wie folgt mitgeteilt:
Vorkenntnisse erforderlich
1. ERC-2771 ist der Standard für Metatransaktionen. Benutzer können die Ausführung von Transaktionen an einen externen Forwarder delegieren, der häufig als Relay oder Forwarder bezeichnet wird.
Normalerweise wird die Adresse des direkten Anrufers im Vertrag mit msg.sender abgerufen. Bei Verwendung von ERC-2771 werden jedoch die eingehenden Anrufdaten abgeschnitten, wenn msg.sender die Weiterleitungsrolle übernimmt, und die letzten 20 Wörter werden abgerufen . Abschnitt als direkte Anruferadresse der Transaktion.

2. Multicall ist eine intelligente Vertragsbibliothek, die die stapelweise Ausführung mehrerer Funktionsaufrufe ermöglicht und so die Transaktionskosten senkt. Diese Bibliothek wird häufig verwendet, um die Leistung und Benutzererfahrung von DApps zu optimieren, insbesondere wenn mehrere Lesevorgänge erforderlich sind.
Wie aus dem Code hervorgeht, führt die Multicall-Bibliothek, die vom anfälligen Vertrag im Thirdweb-Projekt verwendet wird, andere Funktionen im Vertrag aus, der auf die Bibliothek verweist, indem sie die DelegateCall-Funktion zyklisch aufruft.

Grundursache
Die Hauptursache der Sicherheitslücke besteht darin, dass der Token-Vertrag sowohl die ERC-2771- als auch die Multicall-Bibliothek verwendet. Der Angreifer ruft die Multicall-Funktion des Token-Vertrags über die Ausführungsfunktion des Forwarder-Vertrags auf, um andere Funktionen im Vertrag auszuführen (z. B. das Brennen von Token). Diese Methode besteht das isTrustedForwarder-Urteil von ERC-2771 erfolgreich und löst schließlich den Aufrufer der Funktion in die letzten 20 Bytes der böswilligen Aufrufdaten auf. Daher gelang es dem Angreifer, den Vertrag erfolgreich zu täuschen und zu glauben, der Anrufer sei die Adresse eines anderen Benutzers, was wiederum zur Zerstörung der Token anderer Benutzer führte.
Analyse von Angriffsschritten
Hier nehmen wir die Angriffstransaktion 0xecdd11...f6b6 als Beispiel für die Analyse:
1. Der Angreifer nutzte zunächst 5 WETH, um 345.539.9346 Time-Token im Uniswap V2-Pool einzutauschen.

2. Rufen Sie dann die Ausführungsfunktion des Weiterleitungsvertrags auf, um bösartige Daten zu erstellen und die Multicall-Funktion des Token-Vertrags aufzurufen. Zu diesem Zeitpunkt wird der Token-Vertrag die Brennfunktion des Token-Vertrags basierend auf den übergebenen bösartigen Daten aufrufen Durch den Angreifer werden 62.227.259.510 Zeit-Token zerstört.

3. Da im vorherigen Schritt eine große Anzahl von Zeit-Tokens im Pool verbrannt wurde, wodurch der Preis der Zeit-Tokens sofort anstieg, kann der Angreifer die im ersten Schritt erhaltenen Zeit-Tokens schließlich umkehren und so den Pool auf 94 WETH leeren.

Analyse des Angriffsprinzips
In der Ausführungsfunktion des Forward-Vertrags wird nach der Überprüfung der Signatur von req.from der Aufruf zur Interaktion mit req.to (Token-Adresse) verwendet. Die vom Angreifer übergebenen req.data sind


Da 0xac9650d8 die Funktionssignatur der Multicall-Funktion ist, wird die Multicall-Funktion des Token-Vertrags aufgerufen und der von der Multicall-Funktion übergebene Datenwert lautet 0x42966c6800000000000000000000000000000000000c9112ec16d958e8da8180000760dc 1 e043d99394a10605b2fa08f123d60faf84.
Warum enthält der an die Multicall-Funktion übergebene Datenwert kein req.from? Dies liegt daran, dass die unterste EVM-Ebene bei der Verarbeitung des Anrufs den erforderlichen Wert basierend auf dem Offset abschneidet. Der im vom Angreifer übergebenen Calldata-Wert festgelegte Offset beträgt 38 und die Wertlänge beträgt 1, sodass nur der Datenwert abgefangen wird 42966c68000000000000000000000000000000000000c9112ec16d958e8da8180000760dc1e043d99394a10605b2fa08f123d60faf84.

Einzelheiten finden Sie in der Beschreibung des Aufrufs im EVM-Opcode (https://www.evm.codes/?fork=shanghai).

Da 0x42966c68 die Funktionssignatur der Brennfunktion ist, wird die Brennfunktion des Token-Vertrags über einen Delegatecall basierend auf dem vom Angreifer erstellten Datenwert aufgerufen.

Die Funktion _msgSender() wird von der ERC-2771-Bibliothek überschrieben.

Da Multicall über Delegatecall aufgerufen wird, ist der von isTrustedForwarder übergebene msg.sender tatsächlich die Adresse des Forward-Vertrags, wodurch das Urteil gefällt wird, und letztendlich ist der von _msgSender() zurückgegebene Wert die letzten 20 Bytes der übergebenen Anrufdaten. Das Das heißt, die Adresse des Pools lautet 0x760dc1e043d99394a10605b2fa08f123d60faf84.
abschließend
Die Hauptursache dieses Angriffs besteht darin, dass der Vertrag sowohl auf Multicall als auch auf ERC2771Context verweist. Der Angreifer kann böswillige Anrufdaten in die Weiterleitungsanforderung einfügen, die Delegatecall-Funktion von Multicall verwenden, um das Urteil des vertrauenswürdigen Weiterleiters zu fällen, und _msgSender() im verarbeiten Unteraufruf. Analyse, sodass das Token jedes Benutzers manipuliert werden kann.
Das SlowMist-Sicherheitsteam empfiehlt den Projektparteien, Multicall und ERC2771Context beim Schreiben von Token-Verträgen nicht gleichzeitig zu verwenden. Wenn der erwartete Bedarf eine gleichzeitige Referenz erfordert, müssen Sie prüfen, ob die Calldata-Länge den Erwartungen entspricht, oder die neueste offizielle Version von Openzeppelins Multicall verwenden ERC2771Kontextverträge.
Referenz
Adresse des Angreifers: 0xfde0d1575ed8e06fbf36256bcdfa1f359281455a
Angriffsvertrag: 0x6980a47bee930a4584b09ee79ebe46484fbdbdd0
Verwandte Angriffstransaktionen: https://etherscan.io/tx/0xecdd111a60debfadc6533de30fb7f55dc5ceed01dfadd30e4a7ebdb416d2f6b6
Details zur betroffenen Version: https://blog.thirdweb.com/security-vulnerability/
Schadensbegrenzungstool: https://mitigate.thirdweb.com/
