Attaque de prêt flash BSC : les trois copieurs

24.07.2021 / Actualites

Une série d’attaques a compromis plusieurs projets Binance Smart Chain (BSC) en mai. Après PancakeBunny, ses trois projets de fourches – AutoShark, Merlin Labs et PancakeHunny – ont également été attaqués à l’aide de techniques similaires. PancakeBunny a subi l’attaque la plus coûteuse des quatre, qui a causé des dommages totaux de près de 45 millions de dollars. Dans cet article, le Dr Chiachih Wu, chef de l’équipe de sécurité Blockchain du groupe Amber, explique les détails des attaques contre les trois imitateurs.

Copies

AutoShark a été attaqué cinq jours après PancakeBunny, suivi par Merlin Labs et PancakeHunny, respectivement. Ce qui suit est une analyse des problèmes et des techniques d’attaque possibles pour ces trois projets fourchus.

Dans la fonction SharkMinter.mintFor(), la quantité de jetons SHARK gratifiants à frapper (c’est-à-dire mintShark) est dérivée de sharkBNBAmount calculé par tokenToSharkBNB() à la ligne 1494. Cependant, tokenToSharkBNB() fait référence au solde actuel de flip , ce qui en fait un point vulnérable. On pourrait supposer que le montant de jetons reçus à la ligne 1492 est égal au montant du solde flip. Pourtant, un mauvais acteur pourrait manipuler le solde du flip simplement en envoyant des jetons flip juste avant l’appel getReward() et en brisant indirectement la logique de tokenToSharkBNB().

Dans l’implémentation sous-jacente de tokenToSharkBNB() , il existe une autre surface d’attaque. Comme indiqué dans l’extrait de code ci-dessus, _flipToSharkBNBFlip() supprime la liquidité d’ApeSwap (ligne 1243) ou de PantherSwap (ligne 1262) et convertit les jetons LP en SHARK+WBNB. Plus tard, generateFlipToken() est invoqué pour convertir SHARK+WBNB en jetons SHARK-BNB LP.

Dans generateFlipToken() , les soldes SHARK et WBNB actuels de SharkMinter (amountADesired, amountBDesired) sont utilisés pour générer des jetons LP et le montant des jetons LP est renvoyé à mintFor() en tant que sharkBNBAmount. Sur cette base, le mauvais acteur pourrait également transférer SHARK + WBNB dans SharkMinter pour manipuler la quantité de jetons SHARK à frapper.

La faille dans PancakeHunny est identique à celle trouvée dans AutoShark, en ce sens que le mauvais acteur peut manipuler la récompense HUNNY avec des jetons HUNNY et WBNB.

Comparé à AutoShark et PancakeHunny, _getReward() de Merlin Labs présente une vulnérabilité plus évidente.

L’extrait de code ci-dessus montre que les frais de performance pourraient être manipulés par le solde de CAKE, ce qui affecte indirectement la frappe des récompenses REMF. Cependant, le modificateur non Contract se débarrasse des prêts flash.

Même sans contrat d’exploitation, le mauvais acteur pourrait toujours profiter de plusieurs appels.

Reproduction de l’attaque AutoShark

Pour reproduire le piratage AutoShark, nous devons d’abord obtenir des jetons SHARK-BNB-LP de PantherSwap. Plus précisément, nous échangeons 0,5 WBNB en SHARK (ligne 58) et transférons le reste WBNB avec ces jetons SHARK dans PantherSwap pour frapper des jetons SHARK-BNB-LP (ligne 64). Plus tard, nous déposons ces jetons LP dans le contrat StrategyCompoundFLIP d’AutoShark (ligne 69) pour nous qualifier pour les récompenses. Notez que nous ne déposons volontairement que la moitié des jetons LP à la ligne 69.

La deuxième étape consiste à intégrer getReward() dans le contrat SharkMinter. Dans l’extrait de code ci-dessus, nous savons que la récompense peut être récupérée par la fonction won() (ligne 1658). En outre, 30 % de la récompense (c’est-à-dire les frais de performance) doivent être supérieurs à 1 000 (c’est-à-dire DUST) pour déclencher le SharkMinter.mintFor() à la ligne 1668.

Par conséquent, dans notre code d’exploitation, nous transférons certains jetons LP vers le contrat StrategyCompoundFLIP à la ligne 76 pour contourner la vérification performanceFee > DUST et déclencher l’appel mintFor(). Étant donné que nous avons besoin de beaucoup de WBNB+SHARK pour manipuler SharkMinter, nous exploitons le WBNB 100 000 de PantherSwap via un appel flash-swap à la ligne 81.

Dans le rappel d’échange flash, pancakeCall(), nous échangeons la moitié du WBNB en SHARK et envoyons le SHARK avec les 50 000 WBNB restants au contrat SharkMinter pour manipuler la frappe de récompense.

L’étape suivante consiste à déclencher getReward() lorsque le SharkMinter reçoit les jetons WBNB+SHARK pour envoyer une grande quantité de SHARK à l’appelant.

La dernière étape consiste à convertir SHARK en WBNB, à payer le prêt flash et à repartir avec les jetons WBNB restants.

Dans notre expérience, le mauvais acteur commence avec 1 WBNB. Avec l’aide de prêts flash, il bénéficie de plus de 1 000 WBNB retournés en une seule transaction.

Reproduire l’attaque PancakeHunny

La théorie derrière l’attaque PancakeHunny est similaire à l’attaque AutoShark. En bref, nous devons envoyer beaucoup de HUNNY+WBNB à HunnyMinter avant de déclencher getReward(). Cependant, le contrat de jeton HUNNY dispose d’un mécanisme de protection appelé antiWhale pour empêcher les transferts de gros montants. Par conséquent, les prêts flash ne fonctionnent pas ici.

Pour contourner antiWhale, nous créons plusieurs contrats enfants et initions plusieurs appels CakeFlipVault.deposit() via lesdits contrats.

Dans l’extrait de code d’exploitation ci-dessus, les jetons LP rassemblés à la ligne 116 sont divisés en 10 parties et transférés dans 10 contrats Lib à la ligne 122, suivis d’appels Lib.prepare() pour chacun d’eux.

Dans Lib.prepare(), nous approuvons() le CakeFlipVault pour dépenser les jetons LP et invoquons CakeFlipVault.deposit() pour activer les appels ultérieurs getReward() pour frapper des jetons HUNNY gratifiants.

Après avoir préparé 10 contrats Lib, le contrat principal réitère chacun d’eux pour : 1) échanger WBNB contre le montant maximum autorisé de HUNNY ; 2) transférer WBNB+HUNNY vers HunnyMinter ; 3) déclencher getReward() via lib.trigger(); et 4) échangez HUNNY contre WBNB.

Au final, le mauvais acteur avec 10 WBNB gagne environ 200 WBNB sur 10 exécutions de 10 opérations de contrats Lib.

Reproduire l’attaque de Merlin Labs

Comme mentionné précédemment, Merlin Labs dispose du modificateur noContract pour se débarrasser des attaques de prêt flash. Cependant, nous pourrions utiliser un script pour déclencher l’attaque avec plusieurs transactions initiées à partir d’une adresse EOA (Externally Owned Account). La seule différence est que quelqu’un peut diriger la transaction du mauvais acteur pour voler les bénéfices.

Comme pour l’attaque AutoShark, nous devons préparer suffisamment de LINK et de WBNB (ligne 23), les utiliser pour créer des jetons WBNB-LINK-LP (ligne 34) et déposer des jetons LP dans le contrat VaultFlipCake (ligne 38).

Les actions restantes sont :

  • Échanger WBNB contre CAKE (ligne 42).
  • Manipulation de la frappe MERL en envoyant CAKE au contrat VaultFlipToCake (ligne 50).
  • Déclenchement de getReward() à la ligne 55 (une grande quantité de jetons MERL sont créés).
  • Échanger MERL vers WBNB et répéter les étapes ci-dessus plusieurs fois.
  • Comme mentionné précédemment, si quelqu’un exécute l’étape 3 juste après l’étape 2, cette personne pourrait supprimer une grande quantité de REMF.

    Dans notre expérience, le mauvais acteur commence avec 10 WBNB et repart avec environ 165 WBNB en répétant les quatre étapes 10 fois.

    À propos du groupe Amber

    Amber Group est l’un des principaux fournisseurs mondiaux de services de crypto-finance opérant dans le monde entier et 24 heures sur 24, avec une présence à Hong Kong, Taipei, Séoul et Vancouver. Fondé en 2017, Amber Group dessert plus de 500 clients institutionnels et a négocié au total plus de 500 milliards de dollars sur plus de 100 bourses électroniques, avec plus de 1,5 milliard de dollars d’actifs sous gestion. En 2021, Amber Group a levé 100 millions de dollars en financement de série B et est devenu la dernière licorne FinTech évaluée à plus d’un milliard de dollars. Pour plus d’informations, veuillez visiter www.ambergroup.io.