Vulnérabilités de la blockchain EOS à ZeroNights 2018

image

Cet article examinera plusieurs vulnĂ©rabilitĂ©s rĂ©elles dans la blockchain EOS (l'un des concurrents d'Ethereum) et comment elles ont Ă©tĂ© intĂ©grĂ©es dans le concours de machines Ă  sous sĂ©curisĂ©es de nouvelle gĂ©nĂ©ration Ă  ZeroNights 2018. Si vous ĂȘtes intĂ©ressĂ© Ă  savoir comment se prĂ©sente la situation de sĂ©curitĂ© ce rĂ©seau blockchain, alors bienvenue sous cat.

Entrée


Tout a commencé avec le fait que récemment, lors d'un audit des contrats intelligents Etherium pour la sécurité, un de nos amis nous a publié un article sur les vulnérabilités des contrats intelligents sur le réseau EOS. Cela nous a beaucoup intéressé et nous avons décidé d'étudier plus en détail les vulnérabilités.

Tout cela a finalement conduit à la création d'un concours pour ZeroNights 2018 appelé «Bandit à un bras» avec des vulnérabilités dans un contrat intelligent.

Commençons directement par regarder le réseau de blockchain EOS, comment travailler avec lui et comment tout est organisé à l'intérieur. Il y a beaucoup d'articles décrivant la technologie sur Internet, donc il n'y aura probablement pas de détails techniques, mais nous essaierons de transmettre la signification générale afin que l'utilisateur moyen puisse avoir une idée élémentaire des mécanismes de travail de la blockchain EOS.

Description de la technologie EOS


EOS.io est une blockchain nouvelle génération de Block.one , basée sur le concept de PoS ( Proof of enjeu ).

D'aprĂšs la description des crĂ©ateurs du rĂ©seau eux-mĂȘmes: «EOS est un logiciel de rĂ©seau blockchain open source gratuit qui fournit aux dĂ©veloppeurs et aux entrepreneurs une plate-forme pour crĂ©er, dĂ©ployer et exĂ©cuter des applications dĂ©centralisĂ©es hautes performances (DAPP).»

Si en un mot essayez d'expliquer le concept, alors il est bien reflété dans un extrait de l'article de Wikipedia:
L'idée de la preuve de participation (PoS) est de résoudre le problÚme de la preuve de travail (PoW) associé à une forte consommation d'énergie. Au lieu de la puissance de calcul des participants, la quantité de crypto-monnaie qu'ils ont dans leur compte compte. Ainsi, au lieu d'utiliser une grande quantité d'électricité pour résoudre le problÚme PoW, le participant PoS dispose d'un pourcentage limité de vérifications de transactions possibles. La limite correspond au montant de crypto-monnaie dans le compte du participant
Le réseau est complÚtement nouveau et le premier lancement du réseau principal (mainnet) a eu lieu le 10 juin 2018. La crypto-monnaie principale est EOS, et le portail principal pour les développeurs est developers.eos.io

La blockchain EOS.io prend en charge les applications créées par les utilisateurs à l'aide du code WebAssembly (WASM), une nouvelle norme Web avec une large prise en charge pour les grandes entreprises telles que Google, Microsoft, Apple et autres.

À l'heure actuelle, la boĂźte Ă  outils la plus rĂ©cente pour crĂ©er des applications qui compilent du code dans WASM est clang / llvm avec leur compilateur C / C ++.

Pour une meilleure compatibilitĂ©, les dĂ©veloppeurs recommandent d'utiliser le CDT EOSIO (Contract Development Toolkit) - un ensemble d'utilitaires des dĂ©veloppeurs eux-mĂȘmes pour un travail pratique et correct sur la crĂ©ation de contrats intelligents.

Le compilateur eosiocpp précédent est déjà obsolÚte et non pris en charge, il est donc conseillé à tout le monde de passer au nouveau (au moment de la rédaction) EOSIO CDT 1.5.

Contrairement Ă  l'Ă©ther


Ether dans son concept utilise PoW (Proof of Work), qui nécessite des calculs coûteux et la récompense est donnée à la premiÚre personne à résoudre un problÚme mathématique. Autrement dit, ceux qui ont décidé en parallÚle, mais n'ont pas eu le temps de décider, ont gaspillé de l'énergie. Dans cette situation, les mineurs se battent entre eux pour des technologies et des équipements plus avancés. Pour générer des blocs plus rapidement et ainsi gagner.

Contrairement Ă  Ether, dans le rĂ©seau EOS, le systĂšme choisira le crĂ©ateur du nouveau bloc selon le concept PoS, et cela est dĂ©terminĂ© par le nombre de statuts personnels - une fraction du nombre total de crypto-monnaie. Ainsi, celui qui a plus de fortune a de meilleures chances d'ĂȘtre sĂ©lectionnĂ© par le systĂšme. Mais contrairement Ă  PoW (Ă©ther), il n'y a pas de rĂ©compense pour gĂ©nĂ©rer un nouveau bloc en principe, et le revenu des mineurs est uniquement la commission des transactions.

Conclusion - les crypto-monnaies basĂ©es sur PoW peuvent ĂȘtre 1000 fois plus Ă©conomes en Ă©nergie.

Nous développons l'environnement de développement


Donc, il semble que nous ayons terminĂ© la thĂ©orie, nous nous tournons vers la pratique. Mais en pratique, tout semble beaucoup plus intĂ©ressant. Avec la documentation au moment oĂč nous essayions de le comprendre en Ă©tĂ© et commençions Ă  faire quelque chose pour ZeroNights 2018, tout Ă©tait trĂšs mauvais, et le portail de dĂ©veloppement principal Ă©tait boguĂ©, Ă  moitiĂ© vide et parfois ne fonctionnait mĂȘme pas.

Les rĂ©seaux de test n'ont pas encore vraiment Ă©tĂ© lancĂ©s, j'ai donc dĂ» dĂ©ployer mon nƓud. Soit dit en passant, contrairement aux opinions sur Internet, il n'a pas Ă©tĂ© si difficile de l'obtenir. En utilisant la documentation officielle, nous l'avons lancĂ©e Ă  partir du docker developers.eos.io/eosio-nodeos/docs/docker-quickstart

Parlons des principaux utilitaires, des programmes pour travailler avec la blockchain EOS, que j'ai dû gérer au moment de travailler sur la compétition:

  • Nodeos - en fait, le service du nƓud EOSIO lui-mĂȘme; Vous pouvez configurer et configurer divers plugins, par exemple CORS, historique et autres.
  • Cleos est un utilitaire de console permettant de travailler avec un nƓud, d'appeler des mĂ©thodes de contrat et d'interagir avec un portefeuille, des clĂ©s et des accĂšs. L'outil le plus courant lorsque vous travaillez avec EOS.
  • Keosd est un portefeuille de console, ou plus prĂ©cisĂ©ment, un service de portefeuille, un magasin de clĂ©s privĂ©es.
  • Eosio.cdt - Contract Development Toolkit, le soi-disant ensemble d'outils de dĂ©veloppement pour le dĂ©bogage et la compilation de contrats, la gĂ©nĂ©ration de fichiers ABI et plus encore.
  • Eos.js - bibliothĂšque API Javascript pour un travail pratique avec le nƓud et les contrats via le Web, intĂ©grĂ©s dans le site.
  • Scatter est un portefeuille de bureau pour le stockage sĂ©curisĂ© de vos clĂ©s de compte. Il existe une bibliothĂšque Web scatter.js, qui interagit avec le portefeuille de bureau Scatter sur les sockets Web et aide ainsi Ă  travailler avec les applications DAPP dans le navigateur.

Uff! .. Oui, il y a beaucoup de programmes, les comprendre n'est pas non plus trĂšs simple. Une description de tout cela mĂ©rite un article sĂ©parĂ© et dĂ©passe le cadre de cet article. Mais imaginons que nous avons installĂ© un nƓud sur notre serveur et mĂȘme appris Ă  utiliser des mĂ©thodes contractuelles pour appeler des mĂ©thodes contractuelles si nous en avions un.

Oui, la chose la plus importante. Nous devons esquisser le contrat intelligent lui-mĂȘme. Nous allons l'Ă©crire en C ++ et, pour faire au moins quelque chose de sensĂ©, j'ai dĂ» lire beaucoup de documentation.

Pour comprendre les contrats, ils donnent un exemple de contrat Hello partout. Le fichier principal est hello.cpp et l'intégralité du contrat y est décrit.

#include <eosiolib/eosio.hpp> using namespace eosio; class hello : public eosio::contract { public: using contract::contract; /// @abi action void hi( account_name user ) { print( "Hello, ", name{user} ); } }; EOSIO_ABI( hello, (hi) ) 

Si en un mot essayez d'expliquer, alors ici - tout est simple . Nous chargeons la bibliothĂšque eosio.hpp, puis crĂ©ons la classe hello (Ă©galement connue sous le nom de contrat) et hĂ©ritons du contrat de classe. Nous crĂ©ons la mĂ©thode void hi et entrons la variable utilisateur de type account_name dans les paramĂštres, c'est aussi uint64_t. Dans la mĂ©thode, imprimez «Bonjour» et le nom que nous spĂ©cifions lors de l'appel de la mĂ©thode. La derniĂšre ligne oĂč se trouve EOSIO_ABI est une macro auxiliaire qui accepte notre classe et les mĂ©thodes publiques de cette classe, et participe Ă©galement Ă  la formation du fichier .abi, oĂč toutes les mĂ©thodes publiques du contrat sont indiquĂ©es.

Explorer les vulnérabilités


Ainsi, dans le cadre de cet article , plusieurs vulnérabilités ont été décrites - examinons-les maintenant plus en détail.

Débordement numérique - Débordement numérique


Lorsque le contrat est appelĂ©, le nƓud vĂ©rifie le type du paramĂštre, et si les donnĂ©es que nous essayons de l'alimenter ne correspondent pas, alors le nƓud commencera Ă  jurer et de telles atrocitĂ©s ne seront pas manquĂ©es. MAIS! Si Ă  l'intĂ©rieur du contrat il y a une sorte d'algorithme pour changer le nombre, la somme des nombres ou, disons, la multiplication, alors le nombre peut changer dĂ©jĂ  Ă  l'intĂ©rieur du contrat. Cela signifie que vous pouvez spĂ©cifier un nombre que le nƓud ignorera, mais multiplier le contrat, et le nombre dĂ©passera le type de donnĂ©es valide, ce qui entraĂźnera un dĂ©bordement.

Que peut-il donner? Par exemple, il existe une vérification pour certains paramÚtres numériques, disons int Number <0, et il est connu que int y est un nombre signé, et si un dépassement de capacité d'un nombre se produit, le signe du nombre pour les grandes valeurs passera à négatif. Ainsi, le chÚque sera débordé. Et ici, bien sûr, tout dépend de la criticité de ce contrÎle.

Par exemple, dans le mĂȘme article sur les vulnĂ©rabilitĂ©s, il existe un cas rĂ©el oĂč les attaquants ont pu influencer le paramĂštre d'Ă©quilibre, trompant ainsi le systĂšme. Les commentaires du code dĂ©crivent plus en dĂ©tail le mĂ©canisme d'interaction avec le contrat:

 //      typedef struct acnts { account_name name0; account_name name1; account_name name2; account_name name3; } account_names; //     (   1 EOS) //  ,     , //      «» void batchtransfer( symbol_name symbol, account_name from, account_names to, uint64_t balance ){ //    require_auth(from); //    account fromaccount; //      require_recipient(from); require_recipient(to.name0); require_recipient(to.name1); require_recipient(to.name2); require_recipient(to.name3); // ,       . //   is_balance_within_range   ( eosio_assert(is_balance_within_range(balance), "invalid balance"); // ,      «» //  , «» 1111111111111111  0,     eosio_assert(balance > 0, "must transfer positive balance"); //   amount    4 //     ,  amount   int64_t amount = balance * 4; //     from,    int itr = db_find_i64(_self, symbol, N(table), from); // ,    eosio_assert(itr >= 0, "wrong name"); //    fromaccount   db_get_i64(itr, &fromaccount, (account)); // ,       // ,    0.1 EOS //    ,    amount eosio_assert(fromaccount.balance >= amount, "overdrawn balance"); //   sub_balance(symbol, from, amount); //    4  add_balance(symbol, to.name0, balance); add_balance(symbol, to.name1, balance); add_balance(symbol, to.name2, balance); add_balance(symbol, to.name3, balance); } 

Le piratage a probablement été effectué comme suit. L'attaquant a pré-créé 4 comptes et a appelé directement la méthode batchtransfer , quelque chose comme ceci:

 cleos push action contractname batchtransfer \'{"symbol ":"EOS", "from":”attacker”, "to":{ “name0”:”acc0”, “name1”:”acc1”, “name2”:”acc2”, “name3”:”acc3”}, "balance":"111111111111111111 EOS"}' -p attacker@active 


image

Je ferai une réservation tout de suite, ce n'est qu'une hypothÚse; comment exactement ils ont fait le piratage - nous ne savons pas, et s'il y a d'autres réflexions à ce sujet ou des informations plus précises, écrivez dans les commentaires.

ContrĂŽle d'authentification


L'absence de vérification de la méthode contractuelle require_auth () pour l'autorisation de l'utilisateur entraßnera le fait que toute personne qui ne dispose pas des droits nécessaires peut utiliser les méthodes privilégiées du contrat, par exemple, retirer de l'argent du contrat.

Absence de vérification d'invocation de méthode


Lors de l'envoi d'argent vers un contrat (EOS), vous pouvez indiquer dans une macro spéciale ce qui se passera ensuite et ce qu'il faut faire. Disons que lorsque vous recevez de l'argent, un certain algorithme sera appelé, par exemple, pour démarrer la roulette ou autre chose, ainsi qu'un chÚque:

 if( code == self || code == N(eosio.token) || action == N(onerror) ) { \ TYPE thiscontract( self ); \ switch( action ) { \ EOSIO_API( TYPE, MEMBERS ) \ } } //    action == N(transfer) 

Dans cette vérification, il n'y a aucune restriction sur l'appel de la méthode de transfert, c'est pourquoi vous pouvez appeler la méthode de transfert directement, sans envoyer d'argent au contrat. Et cela signifie démarrer le mécanisme avec un gain supplémentaire, sans dépenser un centime.

Compétition ZeroNights 2018


L'idĂ©e du concours est nĂ©e d'elle-mĂȘme: puisque tout est liĂ© aux jeux et Ă  trois vulnĂ©rabilitĂ©s, nous allons donc faire le jeu sur le mĂ©canisme de contrat intelligent dans la blockchain EOS.io. Le jeu doit ĂȘtre aussi simple que possible, mais intĂ©ressant.

Machine à sous "Bandit manchot"! Les gens qui recherchent de l'argent facile m'ont toujours surpris - rappelez-vous, il n'y a pas de cadeaux au monde, ou presque. Ici, d'ailleurs, il est bien là, ou plutÎt, il apparaßtra lorsque des vulnérabilités seront utilisées.

Frontend


Ils ont décidé de rendre les jeux frontaux à la mode, beaux et tridimensionnels. Merci à vtornik23 de ne pas avoir refusé de participer et de nous avoir aidé à faire un frontend complet sur le moteur Unity3d.

image

Machine de jeu en trois dimensions "bandit manchot"; en envoyant 1 EOS dessus et en tirant sur un levier intelligent, le joueur a l'opportunité de démarrer la roue de la fortune et de remporter le jackpot!

Vulnérabilités des contrats


Selon l'idée du jeu, la victoire était considérée comme la perte de trois poupées ZeroNights, qui dans le coefficient numérique serait soit 777 ou 0. Les chances de gagner étaient égales à 0,02%, et certains programmeurs inattentifs ont essayé de compliquer l'algorithme aléatoire en n'y ajoutant que le débordement de multiplication. le montant d'argent envoyé, et était trop paresseux pour réfléchir plus en détail aux conditions, j'ai donc simplement écrit if (résultat == 777 || résultat <1), ce qui permet de glisser une valeur négative.

  int rnd = random(999); int result = rnd * price.amount; uint64_t prize = 0; print("Result:", result); // BINGO 777 or 000 !!! ~ 0.02% if(result == 777 || result < 1 ) { prize = 100; sendtokens(from); } 

Le contrat intelligent lui-mĂȘme est prĂ©sentĂ© sur le github , afin que tout le monde puisse y regarder de plus prĂšs et identifier d'autres vulnĂ©rabilitĂ©s. Ils ont dĂ©jĂ  Ă©tĂ© Ă©crits Ă  leur sujet un peu plus haut, donc il ne devrait pas y avoir de difficultĂ©s Ă  les trouver.

RĂšgles de participation


Les rÚgles de participation sont trÚs simples: il fallait essayer de gagner ou de pirater les mécanismes du systÚme. Quand 3 matryoshkas tombent - Jackpot !!! Le systÚme facture 100 unités de crypto-monnaie. Si un participant reçoit un jackpot 3 fois de suite, il devient un gagnant et reçoit des prix des organisateurs - des sweats à capuche de marque, des badges, une variété de produits.

Bien sûr, vous pouvez gagner en tirant longtemps sur le levier et en espérant avoir de la chance, mais la fortune est imprévisible et le pourcentage de gains est trÚs faible, il était donc plus facile de pirater.

RĂ©sultats du concours


En conséquence, la compétition, à notre avis, était parfaite. Des récompenses étaient prévues pour 3 personnes, et seulement trois ont réussi à faire face à la compétition avant la date de fin prévue. Le concours s'est déroulé sur 2 jours, au cours desquels les participants ont dû résoudre la tùche. La remise officielle et la remise des cadeaux ont eu lieu à la clÎture de la conférence sur la scÚne principale de ZeroNights 2018.

L'accent principal a été mis sur la connaissance de la technologie de la chaßne de blocs EOS, et nous avons laissé quelques conseils, dont personne n'a pu trouver. Nous laisserons cette énigme pour plus tard ...

Avis des participants


Alexey (1 place)
ZeroNights est l'une de mes confĂ©rences prĂ©fĂ©rĂ©es, Ă  commencer par la toute premiĂšre, Ă  Saint-PĂ©tersbourg, je n'en ai pas manquĂ© une seule. Ça donne toujours de l'enthousiasme depuis six mois c'est sĂ»r, et lĂ  au printemps PHDays :). Ces 3 derniĂšres annĂ©es, j'ai fait du dĂ©veloppement de blockchain. Cette annĂ©e, la blockchain est arrivĂ©e Ă  ZeroNights (dans le passĂ©, la vĂ©ritĂ© semble ĂȘtre la mĂȘme, c'Ă©tait sur le hackvest, mais je l'ai ratĂ©). Tout d'abord, aprĂšs m'ĂȘtre inscrit Ă  la confĂ©rence, je suis allĂ© voir quoi et comment il y avait avec la blockchain. Je pensais que ce serait quelque chose comme PHDays, une sorte de courbe alĂ©atoire ou une condition de course dans l'air. Mais voici EOS, avec qui j'avais une petite connaissance lors du premier hackathon EOS, mais ce n'Ă©tait pas long, et d'ailleurs, tous les paramĂštres de dĂ©veloppement ont Ă©tĂ© perdus. L'esprit de combat est tombĂ© et je suis allĂ© attendre le dĂ©but de la confĂ©rence. Mais la curiositĂ© l'a emportĂ©, aprĂšs tout, qu'est-ce qui ne va pas avec l'EOS!

Stanislav Povolotsky (2 place)
Pour moi, ce fut un concours long mais intéressant. Et ce fut une excellente occasion de découvrir l'architecture de la blockchain EOS. Le concours a commencé avec la surprise de ne pas pouvoir accéder au réseau EOS (mainnet) - uniquement pour $$$. AprÚs avoir demandé que le contrat soit déployé sur le réseau de test, s'enregistrer sur ce réseau, configurer la dispersion et afficher l'historique des transactions pour le contrat de jeu, il est devenu immédiatement clair comment tricher avec la machine à sous (l'auteur du contrat l'a fait plusieurs fois pendant les tests). Mais la confiance qu'il est si rapide et facile de gérer le concours a rapidement disparu dÚs que le réseau n'a pas approuvé toutes mes transactions avec des paramÚtres identiques à la transaction gagnante.

Irina (3e place)
Avant de participer au concours, elle a présenté le travail des contrats intelligents uniquement en théorie, il était donc trÚs intéressant de «les rencontrer en direct», voir le code source, essayer les outils (et encore une fois s'assurer que le python est le meilleur)). La tùche s'est avérée vraiment trÚs excitante. Je vous remercie!

Et en conclusion


Cela ne veut pas dire que tout le monde s'est débrouillé facilement. Pour certains, cela a été difficile 2 jours, et ce n'est qu'à la fin que les chanceux ont réussi à gagner en utilisant les lacunes de toute blockchain - si les informations sont entrées dans la blockchain, alors elles sont accessibles à tous, et si quelqu'un a déjà piraté quelque chose, l'autre peut le regarder le chemin.

Nous remercions tous les participants et ceux qui ont contribué à l'organisation du concours.
Rendez-vous Ă  ZeroNights 2019, de nouvelles aventures vous attendent!

Source: https://habr.com/ru/post/fr433552/


All Articles