Analyse du principe de la vulnérabilité de substitution d'adresse arbitraire dans ERC2771 Multicall de SharkTeam

robot
Création du résumé en cours

Le 8 décembre 2023, OpenZeppelin a publié un avertissement important concernant la sécurité. Il s'avère qu'en utilisant le standard ERC-2771 et des fonctions de type Multicall, il existe un risque de substitution d'adresse ! J'ai profondément étudié cette vulnérabilité et je souhaite partager mes découvertes.

Analyse de l'attaque

Considérons l'une des attaques :

  • Attaquant : 0xFDe0d1575Ed8E06FBf36256bcdfA1F359281455A
  • Transaction : 0xecdd111a60debfadc6533de30fb7f55dc5ceed01dfadd30e4a7ebdb416d2f6b6

Le schéma de l'attaque est brillamment simple :

  1. L'attaquant a échangé 5 WETH contre environ 3,455,399,346 TIME
  2. Ensuite, j'ai construit des paramètres calldata astucieux et j'ai appelé [Forwarder].execute
  3. Cette fonction a lancé multicall dans le contrat TIME, et le reste de calldata a été utilisé pour burn() - destruction de tokens dans le pool!

Comment ça fonctionne ?

Dans cette attaque, les étoiles se sont alignées : ERC-2771, Multicall et des données soigneusement élaborées. Le contrat TOKEN hérite de ERC2771Context, et c'est ici que les choses deviennent vraiment intéressantes !

ERC-2771 donne un msg.sender virtuel, permettant de déléguer des transactions à un tiers. L'adresse réelle est ajoutée dans le calldata. Lorsque [Forwarder] appelle le contrat, _msgSender() vérifie ces données et coupe les 20 derniers octets comme "vrai" msg.sender.

Multicall transforme un appel en plusieurs, économisant du gaz. Il prend un tableau d'appels et les exécute via deleGatecall().

Et là, c'est le piège ! L'attaquant décale le calldata de sorte que les 4 premiers octets des nouvelles données correspondent à la fonction burn(), et le paramètre est une énorme somme de tokens. À la ligne 0x20, l'adresse de la piscine de liquidité TIME-ETH est ajoutée, ce qui devient le msg.sender "attendu" !

Racine du problème

Dans ERC-2771, [Forwarder] n'était jamais prévu pour fonctionner avec multicall ! L'attaquant a ajouté les paramètres _msgSender() à l'appel externe multicall. À l'intérieur de la fonction multicall, certaines fonctions ont également ajouté ces paramètres, ce qui a permis de simuler un appel depuis N'IMPORTE QUEL adresse !

Mesures de protection

  1. La nouvelle version d'OpenZeppelin Multicall conserve désormais la longueur du contexte ERC-2771 et en tient compte à chaque appel enfant.

  2. ThirdWeb est allé plus loin en interdisant à tout contrat d'appeler multicall, empêchant l'utilisation de [Forwarder].

Cette vulnérabilité est un exemple frappant de la manière dont une combinaison de composants sûrs séparément peut créer une faille catastrophique ! Tous les développeurs doivent se rappeler : vérifiez toujours l'interaction entre les différents standards.

ETH1.02%
Voir l'original
Cette page peut inclure du contenu de tiers fourni à des fins d'information uniquement. Gate ne garantit ni l'exactitude ni la validité de ces contenus, n’endosse pas les opinions exprimées, et ne fournit aucun conseil financier ou professionnel à travers ces informations. Voir la section Avertissement pour plus de détails.
  • Récompense
  • Commentaire
  • Reposter
  • Partager
Commentaire
0/400
Aucun commentaire
  • Épingler
Trader les cryptos partout et à tout moment
qrCode
Scan pour télécharger Gate app
Communauté
Français (Afrique)
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)