Ένας χάκερ έκλεψε 31 εκατομμύρια δολάρια Ether - πώς συνέβη και τι σημαίνει για το Ethereum

Χθες, ένας χάκερ έβγαλε τη δεύτερη μεγαλύτερη ληστεία στην ιστορία των ψηφιακών νομισμάτων.

Γύρω στις 12:00 PST, ένας άγνωστος εισβολέας εκμεταλλεύτηκε ένα κρίσιμο ελάττωμα στο πορτοφόλι Parity multi-signature στο δίκτυο Ethereum, αποστραγγίζοντας τρία τεράστια πορτοφόλια αξίας άνω των 31.000.000 $ Ether σε λίγα λεπτά. Δεδομένων δύο ακόμη ωρών, ο χάκερ θα μπορούσε να είχε αποφέρει περισσότερα από 180.000.000 $ από ευάλωτα πορτοφόλια.

Αλλά κάποιος τους σταμάτησε.

Έχοντας ακούσει τις καμπάνες συναγερμού, μια ομάδα καλοπροαίρετων λευκών καπέλων από την κοινότητα Ethereum οργάνωσε γρήγορα. Ανέλυσαν την επίθεση και συνειδητοποίησαν ότι δεν υπήρχε τρόπος να αντιστραφούν οι κλοπές, αλλά πολλά άλλα πορτοφόλια ήταν ευάλωτα. Ο χρόνος ήταν ουσιαστικός, οπότε είδαν μόνο μία διαθέσιμη επιλογή: χαράξτε τα υπόλοιπα πορτοφόλια πριν το κάνει ο εισβολέας.

Εκμεταλλευόμενοι την ίδια ευπάθεια, τα λευκά καπέλα χάραξαν όλα τα υπόλοιπα πορτοφόλια σε κίνδυνο και εξαντλούσαν τους λογαριασμούς τους, εμποδίζοντας αποτελεσματικά τον εισβολέα να φτάσει σε οποιοδήποτε από τα υπόλοιπα 150.000.000 $.

Ναι, το διάβασες σωστά.

Για να αποτρέψει τον χάκερ να ληστεύει άλλες τράπεζες, τα λευκά καπέλα έγραψαν λογισμικό για να κλέψουν όλες τις υπόλοιπες τράπεζες στον κόσμο. Μόλις τα χρήματα κλαπεί με ασφάλεια, ξεκίνησαν τη διαδικασία επιστροφής των χρημάτων στους αντίστοιχους κατόχους λογαριασμού τους. Οι άνθρωποι που είχαν σώσει τα χρήματά τους από αυτό το ηρωικό κατόρθωμα βρίσκονται τώρα στη διαδικασία ανάκτησης των κεφαλαίων τους.

Είναι μια εξαιρετική ιστορία και έχει σημαντικές επιπτώσεις στον κόσμο των κρυπτονομισμάτων.

Είναι σημαντικό να καταλάβουμε ότι αυτή η εκμετάλλευση δεν ήταν ευπάθεια στο Ethereum ή στο ίδιο το Parity. Αντίθετα, ήταν ένα θέμα ευπάθειας στον προεπιλεγμένο έξυπνο κώδικα συμβολαίου που ο πελάτης Parity δίνει στον χρήστη για την ανάπτυξη πορτοφολιών πολλαπλών υπογραφών.

Όλα αυτά είναι πολύ περίπλοκα, οπότε για να καταστήσουμε σαφείς τις λεπτομέρειες αυτού για όλους, αυτή η ανάρτηση χωρίζεται σε τρία μέρη:

  1. Τι ακριβώς συνέβη; Μια εξήγηση για το Ethereum, τα έξυπνα συμβόλαια και τα πορτοφόλια πολλαπλών υπογραφών.
  2. Πώς το έκαναν; Μια τεχνική εξήγηση της επίθεσης (ειδικά για προγραμματιστές).
  3. Τώρα τι? Οι επιπτώσεις της επίθεσης για το μέλλον και την ασφάλεια έξυπνων συμβάσεων.

Εάν είστε εξοικειωμένοι με το Ethereum και τον κόσμο της κρυπτογράφησης, μπορείτε να μεταβείτε στη δεύτερη ενότητα.

1. Τι ακριβώς συνέβη;

Υπάρχουν τρία δομικά στοιχεία σε αυτήν την ιστορία: Ethereum, έξυπνα συμβόλαια και ψηφιακά πορτοφόλια.

Το Ethereum είναι ένα ψηφιακό νόμισμα που εφευρέθηκε το 2013 - 4 ολόκληρα χρόνια μετά την κυκλοφορία του Bitcoin. Από τότε έχει εξελιχθεί στο δεύτερο μεγαλύτερο ψηφιακό νόμισμα στον κόσμο με όριο αγοράς - 20 δισεκατομμύρια δολάρια, σε σύγκριση με τα 40 δισεκατομμύρια δολάρια του Bitcoin.

Όπως όλα τα κρυπτονομίσματα, το Ethereum είναι απόγονος του πρωτοκόλλου Bitcoin και βελτιώνεται στο σχεδιασμό του Bitcoin. Αλλά μην ξεγελιέστε: αν και είναι ψηφιακό νόμισμα όπως το Bitcoin, το Ethereum είναι πολύ πιο ισχυρό.

Ενώ το Bitcoin χρησιμοποιεί το blockchain για να εφαρμόσει ένα καθολικό χρηματικών συναλλαγών, το Ethereum χρησιμοποιεί το blockchain του για να καταγράφει μεταβάσεις κατάστασης σε έναν γιγαντιαίο κατανεμημένο υπολογιστή. Το αντίστοιχο ψηφιακό νόμισμα της Ethereum, ο αιθέρας, είναι ουσιαστικά μια παρενέργεια της τροφοδοσίας αυτού του τεράστιου υπολογιστή.

Με άλλα λόγια, το Ethereum είναι κυριολεκτικά ένας υπολογιστής που εκτείνεται σε ολόκληρο τον κόσμο. Όποιος χρησιμοποιεί το λογισμικό Ethereum στον υπολογιστή του συμμετέχει στις λειτουργίες αυτού του παγκόσμιου υπολογιστή, του Ethereum Virtual Machine (EVM). Επειδή το EVM σχεδιάστηκε για να είναι πλήρες Turing (αγνοώντας τα όρια αερίου), μπορεί να κάνει σχεδόν οτιδήποτε μπορεί να εκφραστεί σε ένα πρόγραμμα υπολογιστή.

Επιτρέψτε μου να είμαι εμφατικός: αυτό είναι τρελό. Ο κόσμος της κρυπτογράφησης είναι αόριστος σχετικά με τις δυνατότητες του Ethereum, το οποίο έχει δει την άνοδο του στους τελευταίους 6 μήνες.

Η κοινότητα προγραμματιστών έχει συσσωρευτεί πίσω της και υπάρχει πολύ ενθουσιασμός για το τι μπορεί να οικοδομηθεί πάνω από το EVM - και αυτό μας φέρνει σε έξυπνα συμβόλαια.

Τα έξυπνα συμβόλαια είναι απλά προγράμματα υπολογιστών που λειτουργούν στο EVM. Με πολλούς τρόπους, είναι σαν κανονικές συμβάσεις, εκτός από το ότι δεν χρειάζονται δικηγόρους ή δικαστές για να τις ερμηνεύσουν. Αντ 'αυτού, καταρτίζονται σε bytecode και ερμηνεύονται αναμφίβολα από την EVM. Με αυτά τα προγράμματα, μπορείτε (μεταξύ άλλων) να μεταφέρετε μέσω προγραμματισμού ψηφιακό νόμισμα βάσει μόνο των κανόνων του κώδικα σύμβασης.

Φυσικά, υπάρχουν πράγματα που κάνουν τα κανονικά συμβόλαια που δεν μπορούν τα έξυπνα συμβόλαια - τα έξυπνα συμβόλαια δεν μπορούν εύκολα να αλληλεπιδράσουν με πράγματα που δεν βρίσκονται στο blockchain. Όμως, τα έξυπνα συμβόλαια μπορούν επίσης να κάνουν πράγματα που τα κανονικά συμβόλαια δεν μπορούν, όπως η επιβολή ενός συνόλου κανόνων εντελώς μέσω της άθραυστης κρυπτογραφίας.

Αυτό μας οδηγεί στην έννοια των πορτοφολιών. Στον κόσμο των ψηφιακών νομισμάτων, τα πορτοφόλια είναι ο τρόπος αποθήκευσης των στοιχείων σας. Αποκτάτε πρόσβαση στο πορτοφόλι σας χρησιμοποιώντας ουσιαστικά έναν μυστικό κωδικό πρόσβασης, επίσης γνωστό ως ιδιωτικό κλειδί σας (απλοποιημένο λίγο).

Υπάρχουν πολλοί διαφορετικοί τύποι πορτοφολιών που παρέχουν διαφορετικές ιδιότητες ασφαλείας, όπως όρια ανάληψης. Ένας από τους πιο δημοφιλείς τύπους είναι το πορτοφόλι πολλαπλών υπογραφών.

Σε ένα πορτοφόλι πολλαπλών υπογραφών, υπάρχουν πολλά ιδιωτικά κλειδιά που μπορούν να ξεκλειδώσουν το πορτοφόλι, αλλά μόνο ένα κλειδί δεν αρκεί για να το ξεκλειδώσετε. Εάν το πορτοφόλι πολλαπλών υπογραφών σας διαθέτει 3 πλήκτρα, για παράδειγμα, μπορείτε να καθορίσετε ότι τουλάχιστον 2 από τα 3 κλειδιά πρέπει να παρέχονται για να το ξεκλειδώσετε με επιτυχία.

Αυτό σημαίνει ότι εάν εσείς, ο πατέρας σας και η μητέρα σας είστε όλοι υπογράφοντες σε αυτό το πορτοφόλι, ακόμα κι αν ένας εγκληματίας παραβίασε τη μητέρα σας και έκλεψε το ιδιωτικό της κλειδί, δεν θα μπορούσε να έχει πρόσβαση στα χρήματά σας. Αυτό οδηγεί σε πολύ ισχυρότερες εγγυήσεις ασφαλείας, οπότε τα multi-sigs είναι ένα πρότυπο στην ασφάλεια του πορτοφολιού.

Αυτός είναι ο τύπος του πορτοφολιού που επιτέθηκε ο χάκερ.

Λοιπόν, τι πήγε στραβά; Έσπασαν τα ιδιωτικά κλειδιά; Χρησιμοποίησαν έναν κβαντικό υπολογιστή ή κάποιον αλγόριθμο πρωτοποριακού factoring;

Όχι, όλη η κρυπτογραφία ήταν καλή. Η εκμετάλλευση ήταν σχεδόν γελοία απλή: βρήκαν ένα σφάλμα που εισήγαγε προγραμματιστής στον κώδικα που τους επέτρεψε να αρχικοποιήσουν εκ νέου το πορτοφόλι, σχεδόν σαν να το επαναφέρουν στις εργοστασιακές ρυθμίσεις. Μόλις το έκαναν αυτό, ήταν ελεύθεροι να αυτοπροσδιοριστούν ως νέοι ιδιοκτήτες και στη συνέχεια να φύγουν με τα πάντα.

2. Πώς συνέβη αυτό;

Αυτό που ακολουθεί είναι μια τεχνική εξήγηση του τι ακριβώς συνέβη. Εάν δεν είστε προγραμματιστής, μη διστάσετε να μεταβείτε στην επόμενη ενότητα, καθώς πρόκειται να προγραμματιστεί πολύ.

Το Ethereum έχει ένα αρκετά μοναδικό μοντέλο προγραμματισμού. Στο Ethereum, γράφετε κώδικα δημοσιεύοντας συμβόλαια (τα οποία μπορείτε να σκεφτείτε ως αντικείμενα) και οι συναλλαγές εκτελούνται καλώντας μεθόδους σε αυτά τα αντικείμενα για να μεταλλάξετε την κατάστασή τους.

Για να εκτελέσετε κώδικα στο Ethereum, πρέπει πρώτα να αναπτύξετε τη σύμβαση (η ανάπτυξη είναι η ίδια μια συναλλαγή), η οποία κοστίζει ένα μικρό ποσό Ether. Στη συνέχεια, πρέπει να καλέσετε μεθόδους στη σύμβαση για να αλληλεπιδράσετε με αυτήν, η οποία κοστίζει περισσότερο τον Ether. Όπως μπορείτε να φανταστείτε, αυτό δίνει κίνητρο σε έναν προγραμματιστή να βελτιστοποιήσει τον κώδικά του, τόσο για την ελαχιστοποίηση των συναλλαγών όσο και για την ελαχιστοποίηση του κόστους υπολογισμού.

Ένας τρόπος για να μειώσετε το κόστος είναι να χρησιμοποιήσετε βιβλιοθήκες. Κάνοντας το συμβόλαιό σας να καλέσει σε μια κοινόχρηστη βιβλιοθήκη που είχε αναπτυχθεί σε προηγούμενη ώρα, δεν χρειάζεται να επαναπροσδιορίσετε κοινόχρηστο κώδικα. Στο Ethereum, η διατήρηση του κωδικού σας DRY θα σας εξοικονομήσει άμεσα χρήματα.

Το προεπιλεγμένο πορτοφόλι multi-sig στο Parity έκανε ακριβώς αυτό. Κρατούσε μια αναφορά σε μια κοινόχρηστη εξωτερική βιβλιοθήκη που περιείχε λογική προετοιμασίας πορτοφολιού. Αυτή η κοινόχρηστη βιβλιοθήκη αναφέρεται από το δημόσιο κλειδί της σύμβασης βιβλιοθήκης.

// Σταθερή διεύθυνση FIELDS _walletLibrary = 0xa657491c1e7f16adb39b9b60e87bbb8d93988bc3;

Η βιβλιοθήκη καλείται σε πολλά μέρη, μέσω μιας εντολής EVM που ονομάζεται DELEGATECALL, η οποία κάνει τα εξής: για οποιαδήποτε μέθοδο που καλεί DELEGATECALL, θα καλέσει την ίδια μέθοδο στη σύμβαση στην οποία αναθέτετε, αλλά χρησιμοποιώντας το πλαίσιο της τρέχουσας σύμβασης . Είναι ουσιαστικά σαν σούπερ κλήση, εκτός από το μέρος της κληρονομιάς. (Το ισοδύναμο στο JavaScript θα είναι OtherClass.functionName.apply (αυτό, υποστηρίζει).)

Ακολουθεί ένα παράδειγμα αυτού στο πορτοφόλι πολλαπλών sig: η μέθοδος isOwner μεταβιβάζει μόνο τη μέθοδο isOwner της κοινόχρηστης βιβλιοθήκης πορτοφολιών, χρησιμοποιώντας την κατάσταση της τρέχουσας σύμβασης:

συνάρτηση isOwner (διεύθυνση _addr) σταθερές επιστροφές (bool) {return _walletLibrary.delegatecall (msg.data); }

Όλα αυτά είναι αρκετά αθώα. Το ίδιο το πορτοφόλι multi-sig περιείχε όλους τους σωστούς ελέγχους άδειας και ήταν βέβαιο ότι θα επιβάλλει αυστηρά την εξουσιοδότηση σε όλες τις ευαίσθητες ενέργειες που σχετίζονται με την κατάσταση του πορτοφολιού.

Έκαναν όμως ένα κρίσιμο λάθος.

Η σταθερότητα σάς επιτρέπει να ορίσετε μια «εναλλακτική μέθοδο». Αυτή είναι η μέθοδος που καλείται όταν δεν υπάρχει μέθοδος που να ταιριάζει με ένα δεδομένο όνομα μεθόδου. Το ορίζετε δίνοντάς του ένα όνομα:

function () {// κάντε πράγματα εδώ για όλες τις άγνωστες μεθόδους}

Η ομάδα Parity αποφάσισε να αφήσει οποιαδήποτε άγνωστη μέθοδο που έστειλε τον Ether στο συμβόλαιο απλώς προεπιλογή στην κατάθεση του απεσταλμένου Ether.

function () payable {// payable είναι απλώς μια λέξη-κλειδί που σημαίνει ότι αυτή η μέθοδος μπορεί να λάβει / πληρώσει Ether
αν (msg.value> 0) {// μόλις σταλούν κάποια μετρητά; Κατάθεση (msg.sender, msg.value); } αλλιώς {ρίξτε; }}

Αλλά το πήγαν ένα βήμα παραπέρα, και εδώ ήταν το κρίσιμο λάθος τους. Παρακάτω είναι ο πραγματικός κώδικας που δέχθηκε επίθεση.

Λειτουργία () πληρωτέα {// μόλις σταλούν κάποια μετρητά; εάν (msg.value> 0) Κατάθεση (msg.sender, msg.value); αλλιώς εάν (msg.data.length> 0) _walletLibrary.delegatecall (msg.data); }

Βασικα:

  • Εάν το όνομα της μεθόδου δεν καθορίζεται σε αυτό το συμβόλαιο…
  • Και δεν στέλνεται αιθέρας στη συναλλαγή…
  • Και υπάρχουν ορισμένα δεδομένα στο ωφέλιμο φορτίο του μηνύματος…

Στη συνέχεια, θα καλέσει την ίδια ακριβώς μέθοδο εάν ορίζεται στο _walletLibrary, αλλά στο πλαίσιο αυτής της σύμβασης.

Χρησιμοποιώντας αυτό, ο εισβολέας κάλεσε μια μέθοδο που ονομάζεται initWallet (), η οποία δεν καθορίστηκε στο συμβόλαιο πολλαπλών σειρών, αλλά καθορίστηκε στην κοινόχρηστη βιβλιοθήκη πορτοφολιών:

συνάρτηση initWallet (διεύθυνση [] _owners, uint _required, uint _daylimit) {initDaylimit (_daylimit); initMultiowned (_owners, _required); }

Που καλεί τη μέθοδο initMultiowned ...

συνάρτηση initMultiowned (διεύθυνση [] _owners, uint _required) {m_numOwners = _owners.length + 1; m_owners [1] = uint (msg.sender); m_ownerIndex [uint (msg.sender)] = 1; για (uint i = 0; i <_owners.length; ++ i) {m_owners [2 + i] = uint (_owners [i]); m_ownerIndex [uint (_owners [i])] = 2 + i; } m_required = _required; }

Βλέπετε τι συνέβη εκεί; Ο εισβολέας ουσιαστικά επανεκκίνησε τη σύμβαση εκχωρώντας μέσω της μεθόδου βιβλιοθήκης, αντικαθιστώντας τους ιδιοκτήτες στο αρχικό συμβόλαιο. Αυτοί και όποια σειρά ιδιοκτητών παρέχουν ως επιχειρήματα θα είναι οι νέοι κάτοχοι.

Δεδομένου ότι τώρα ελέγχουν ολόκληρο το πορτοφόλι, μπορούν να εξαγάγουν ασήμαντα το υπόλοιπο του υπολοίπου. Και αυτό ακριβώς έκαναν.

Το initWallet: https://etherscan.io/tx/0x707aabc2f24d756480330b75fb4890ef6b8a26ce0554ec80e3d8ab105e63db07

Η μεταφορά: https://etherscan.io/tx/0x9654a93939e98ce84f09038b9855b099da38863b3c2e0e04fd59a540de1cb1e5

Λοιπόν, ποια ήταν τελικά η ευπάθεια; Θα μπορούσατε να υποστηρίξετε ότι υπήρχαν δύο. Πρώτον, το initWallet και το initMultiowned στη βιβλιοθήκη του πορτοφολιού δεν επισημάνθηκαν ως εσωτερικά (αυτό είναι σαν μια ιδιωτική μέθοδος, η οποία θα απέτρεπε αυτήν την κατ 'εξουσιοδότηση κλήση) και αυτές οι μέθοδοι δεν έλεγξαν ότι το πορτοφόλι δεν είχε ήδη αρχικοποιηθεί. Οποιοσδήποτε έλεγχος θα έκανε αδύνατο αυτό το hack.

Η δεύτερη ευπάθεια ήταν το raw delegateCall. Μπορείτε να το θεωρήσετε αυτό ισοδύναμο με μια δήλωση ακατέργαστου eval, που εκτελείται σε μια συμβολοσειρά που παρέχεται από χρήστη. Σε μια προσπάθεια να είμαστε σύντομοι, αυτό το συμβόλαιο χρησιμοποίησε μεταπρογραμματισμό για τη μεσολάβηση πιθανών μεθόδων κλήσεων σε μια υποκείμενη βιβλιοθήκη. Η ασφαλέστερη προσέγγιση εδώ θα ήταν να επιτρέψετε συγκεκριμένες μεθόδους στις οποίες επιτρέπεται να καλεί ο χρήστης.

Το πρόβλημα, φυσικά, είναι ότι αυτό είναι ακριβότερο στο κόστος του φυσικού αερίου (δεδομένου ότι πρέπει να αξιολογήσει περισσότερους όρους). Όμως, όσον αφορά την ασφάλεια, μάλλον πρέπει να ξεπεράσουμε αυτήν την ανησυχία όταν γράφουμε έξυπνα συμβόλαια που μεταφέρουν τεράστια χρηματικά ποσά.

Αυτή ήταν η επίθεση.

Ήταν ένα έξυπνο αλίευμα, αλλά μόλις το επισημάνετε, φαίνεται σχεδόν στοιχειώδες. Ο επιτιθέμενος στη συνέχεια πήδηξε σε αυτήν την ευπάθεια για τρία από τα μεγαλύτερα πορτοφόλια που μπορούσαν να βρουν - αλλά κρίνοντας από τους χρόνους συναλλαγών, το έκαναν εντελώς χειροκίνητα.

Η ομάδα των λευκών καπέλων το έκανε αυτό σε κλίμακα χρησιμοποιώντας σενάρια και γι 'αυτό κατάφεραν να νικήσουν τον επιτιθέμενο στη γροθιά. Δεδομένου αυτού, είναι απίθανο ο επιτιθέμενος να ήταν πολύ εξελιγμένος στο πώς σχεδίαζαν την επίθεσή τους.

Ίσως να θέσετε την ερώτηση - γιατί δεν απλώς επαναφέρουν αυτό το hack, όπως έκανε με το hack DAO;

Δυστυχώς αυτό δεν είναι πραγματικά δυνατό. Το hack του DAO ήταν μοναδικό στο ότι όταν ο εισβολέας στραγγίζει το DAO σε ένα παιδί DAO, τα χρήματα παγώθηκαν για πολλές ημέρες μέσα σε ένα έξυπνο συμβόλαιο προτού να μπορέσουν να απελευθερωθούν στον εισβολέα.

Αυτό εμπόδισε την κυκλοφορία οποιουδήποτε κλεμμένου κεφαλαίου, οπότε ο κλεμμένος Ether σιγήθηκε αποτελεσματικά. Αυτό έδωσε στην κοινότητα Ethereum αρκετό χρόνο για να διεξαγάγει δημόσια απαρτία σχετικά με τον τρόπο αντιμετώπισης της επίθεσης.

Σε αυτήν την επίθεση, ο εισβολέας έκλεψε αμέσως τα χρήματα και θα μπορούσε να αρχίσει να τα ξοδεύει. Ένα σκληρό πιρούνι δεν θα ήταν πρακτικό - τι κάνετε για όλες τις συναλλαγές που πραγματοποιούνται κατάντη; Τι γίνεται με τους ανθρώπους που διαπραγματεύτηκαν αθώα περιουσιακά στοιχεία με τον εισβολέα; Μόλις ο αιθέρας που έχουν κλέψει ξεπλυθεί και τεθεί σε γενική κυκλοφορία, μοιάζει με πλαστά χαρτονομίσματα που κυκλοφορούν στην οικονομία - είναι εύκολο να σταματήσετε όταν είναι όλα σε έναν χαρτοφύλακα, αλλά όταν όλοι έχουν δυνητικά ένα πλαστό λογαριασμό, δεν μπορείτε πραγματικά να γυρίσετε πίσω το ρολόι πια.

Έτσι, η συναλλαγή δεν θα αντιστραφεί. Η απώλεια 31 εκατομμυρίων δολαρίων ανέρχεται. Είναι ένα δαπανηρό, αλλά απαραίτητο μάθημα.

Τι πρέπει λοιπόν να απομακρύνουμε από αυτό;

3. Τι σημαίνει αυτή η επίθεση για το Ethereum;

Υπάρχουν πολλά σημαντικά πράγματα εδώ.

Πρώτον, θυμηθείτε, αυτό δεν ήταν ελάττωμα στο Ethereum ή γενικά σε έξυπνα συμβόλαια. Αντίθετα, ήταν ένα σφάλμα προγραμματιστή σε μια συγκεκριμένη σύμβαση.

Ποιοι ήταν λοιπόν οι προγραμματιστές crackpot που το έγραψαν; Θα έπρεπε να γνωρίζουν καλύτερα, σωστά;

Οι προγραμματιστές εδώ ήταν μια διασταυρούμενη συνεργασία μεταξύ του ιδρύματος Ethereum (κυριολεκτικά οι δημιουργοί του Ethereum), της βασικής ομάδας Parity και των μελών της κοινότητας ανοιχτού κώδικα. Υποβλήθηκε σε εκτενή αξιολόγηση από ομοτίμους. Αυτό είναι βασικά το υψηλότερο επίπεδο προγραμματισμού που υπάρχει στο οικοσύστημα Ethereum.

Αυτοί οι προγραμματιστές ήταν άνθρωποι. Έκαναν λάθος. Το ίδιο και οι αναθεωρητές που έλεγξαν αυτόν τον κώδικα.

Έχω διαβάσει μερικά σχόλια για το Reddit και το HackerNews σύμφωνα με τα εξής: «Τι προφανές λάθος! Πώς ήταν δυνατόν να το χάσουν; " (Αγνοώντας ότι η «προφανής» ευπάθεια εισήχθη τον Ιανουάριο και ανακαλύφθηκε μόνο τώρα.)

Όταν βλέπω τέτοιες απαντήσεις, γνωρίζω ότι τα άτομα που σχολιάζουν δεν είναι επαγγελματίες προγραμματιστές. Για έναν σοβαρό προγραμματιστή, η αντίδραση είναι αντ 'αυτού: γαμώτο, αυτό ήταν ένα χαζό λάθος. Χαίρομαι που δεν ήμουν αυτός που το κατάφερε.

Λάθη αυτού του είδους γίνονται συνήθως στον προγραμματισμό. Όλα τα προγράμματα φέρουν τον κίνδυνο σφάλματος προγραμματιστή. Πρέπει να απορρίψουμε τη νοοτροπία «εάν ήταν λίγο πιο προσεκτικοί, αυτό δεν θα είχε συμβεί». Σε μια συγκεκριμένη κλίμακα, η προσοχή δεν είναι αρκετή.

Καθώς τα προγράμματα κλιμακώνονται σε μη ασήμαντη πολυπλοκότητα, πρέπει να αρχίσετε να το λαμβάνετε δεδομένου ότι τα προγράμματα πιθανώς δεν είναι σωστά. Δεν επαρκεί ανθρώπινη επιμέλεια ή δοκιμή για την πρόληψη όλων των πιθανών σφαλμάτων. Ακόμη και οργανισμοί όπως η Google ή η NASA κάνουν λάθη προγραμματισμού, παρά την υπερβολική αυστηρότητα που εφαρμόζουν στον πιο κρίσιμο κώδικα τους.

Θα ήταν καλό να πάρουμε μια σελίδα από πρακτικές αξιοπιστίας ιστότοπων σε εταιρείες όπως η Google και η Airbnb. Όποτε υπάρχει σφάλμα παραγωγής ή διακοπή λειτουργίας, πραγματοποιούν ανάλυση μετά τη σφαγή και τη διανέμουν εντός της εταιρείας. Σε αυτά τα μεταθανάτια, υπάρχει πάντα μια αρχή να μην κατηγορούμε ποτέ τα άτομα.

Το να κατηγορούμε λάθη σε άτομα είναι άσκοπο, διότι όλοι οι προγραμματιστές, ανεξάρτητα από το πόσο έμπειροι, έχουν πιθανότητα να κάνουν λάθος. Αντίθετα, ο σκοπός μιας νεκρού είναι να προσδιοριστεί τι στη διαδικασία επέτρεψε να αναπτυχθεί αυτό το λάθος.

Το πρόβλημα δεν ήταν ότι ο προγραμματιστής ξέχασε να προσθέσει εσωτερικό στη βιβλιοθήκη του πορτοφολιού ή ότι έκανε μια πρώτη delegateCall χωρίς να ελέγξει ποια μέθοδο κλήθηκε.

Το πρόβλημα είναι ότι η αλυσίδα εργαλείων προγραμματισμού τους επέτρεψε να κάνουν αυτά τα λάθη.

Καθώς το έξυπνο οικοσύστημα συμβάσεων εξελίσσεται, πρέπει να εξελιχθεί προς την κατεύθυνση της δυσκολίας αυτών των λαθών, και αυτό σημαίνει ότι οι συμβάσεις θα είναι ασφαλείς από προεπιλογή.

Αυτό με οδηγεί στο επόμενο σημείο μου.

Η δύναμη είναι μια αδυναμία όσον αφορά τις γλώσσες προγραμματισμού. Όσο πιο ισχυρή και πιο εκφραστική είναι μια γλώσσα προγραμματισμού, τόσο πιο περίπλοκος γίνεται ο κώδικάς του. Η στερεότητα είναι μια πολύ περίπλοκη γλώσσα, που μοιάζει με την Java.

Η πολυπλοκότητα είναι ο εχθρός της ασφάλειας. Τα σύνθετα προγράμματα είναι πιο δύσκολο να σκεφτούν και είναι πιο δύσκολο να εντοπιστούν αιχμές. Νομίζω ότι οι γλώσσες όπως η Viper (που διατηρείται από τον Vitalik Buterin) είναι ένα πολλά υποσχόμενο βήμα προς αυτήν την κατεύθυνση. Το Viper περιλαμβάνει από προεπιλογή βασικούς μηχανισμούς ασφαλείας, όπως οριακές κατασκευές βρόχου, χωρίς ακέραιες υπερχείλιση και αποτρέπει άλλα βασικά σφάλματα για τα οποία οι προγραμματιστές δεν πρέπει να έχουν λόγο.

Όσο λιγότερο σας επιτρέπει η γλώσσα, τόσο πιο εύκολο είναι να αναλύσετε και να αποδείξετε τις ιδιότητες ενός συμβολαίου. Η ασφάλεια είναι δύσκολη, γιατί ο μόνος τρόπος για να αποδείξουμε μια θετική δήλωση όπως «αυτή η σύμβαση είναι ασφαλής» είναι να διαψεύσουμε κάθε πιθανό φορέα επίθεσης: «αυτό το συμβόλαιο δεν μπορεί να αρχικοποιηθεί εκ νέου», «δεν είναι δυνατή η πρόσβαση στα χρήματά του εκτός από τους ιδιοκτήτες» κ.λπ. Όσο λιγότεροι πιθανοί φορείς επίθεσης πρέπει να λάβετε υπόψη, τόσο πιο εύκολο είναι να αναπτύξετε ένα ασφαλές συμβόλαιο.

Ένα απλούστερο μοντέλο προγραμματισμού επιτρέπει επίσης πράγματα όπως επίσημη επαλήθευση και αυτόματη δημιουργία δοκιμών. Αυτοί είναι τομείς που βρίσκονται υπό ενεργό έρευνα, αλλά όπως τα έξυπνα συμβόλαια έχουν ενσωματώσει την αιχμή της κρυπτογραφίας, θα πρέπει επίσης να αρχίσουν να ενσωματώνουν το κορυφαίο πλεονέκτημα του σχεδιασμού της γλώσσας προγραμματισμού.

Υπάρχει και ένα μεγαλύτερο μάθημα εδώ.

Οι περισσότεροι από τους προγραμματιστές που μπαίνουν σε αυτόν τον χώρο, συμπεριλαμβανομένου του εαυτού μου, προέρχονται από ένα ιστορικό ανάπτυξης ιστού και η αλυσίδα εργαλείων blockchain έχει σχεδιαστεί για να είναι οικεία για τους προγραμματιστές ιστού. Το Solidity έχει επιτύχει τεράστια υιοθέτηση στην κοινότητα των προγραμματιστών λόγω της εξοικείωσής του με άλλες μορφές προγραμματισμού. Κατά κάποιο τρόπο, αυτό μπορεί να καταλήξει να είναι η πτώση του.

Το πρόβλημα είναι ότι ο προγραμματισμός blockchain διαφέρει ουσιαστικά από την ανάπτυξη ιστού.

ΑΣΕ με να εξηγήσω.

Πριν από την ηλικία του μοντέλου Ιστού πελάτη-διακομιστή, ο περισσότερος προγραμματισμός έγινε για συσκευασμένο λογισμικό καταναλωτή ή σε ενσωματωμένα συστήματα. Αυτό ήταν πριν από την ημέρα των αυτόματων ενημερώσεων λογισμικού. Σε αυτά τα προγράμματα, ένα προϊόν που στάλθηκε ήταν τελικό - απελευθερώνατε μια μορφή του λογισμικού σας κάθε 6 μήνες και αν υπήρχε ένα σφάλμα, αυτό το σφάλμα θα έπρεπε να παραμείνει μέχρι την επόμενη κυκλοφορία. Λόγω αυτού του μεγαλύτερου κύκλου ανάπτυξης, όλες οι εκδόσεις λογισμικού δοκιμάστηκαν αυστηρά κάτω από όλες τις πιθανές συνθήκες.

Η ανάπτυξη Ιστού είναι πολύ πιο συγχωρητική. Όταν σπρώχνετε κακό κώδικα σε έναν διακομιστή ιστού, δεν είναι μεγάλη υπόθεση εάν υπάρχει ένα κρίσιμο λάθος - μπορείτε απλώς να επαναφέρετε τον κώδικα ή να προχωρήσετε με μια επιδιόρθωση και όλα είναι καλά επειδή ελέγχετε τον διακομιστή. Ή εάν συμβεί το χειρότερο και υπάρχει ενεργή παραβίαση ή διαρροή δεδομένων, μπορείτε πάντα να σταματήσετε την αιμορραγία κλείνοντας τους διακομιστές σας και αποσυνδέοντας τον εαυτό σας από το δίκτυο.

Αυτά τα δύο μοντέλα ανάπτυξης είναι θεμελιωδώς διαφορετικά. Μόνο από κάτι σαν την ανάπτυξη ιστού μπορείτε να πάρετε το σύνθημα «να κινηθείτε γρήγορα και να σπάσετε τα πράγματα».

Οι περισσότεροι προγραμματιστές σήμερα εκπαιδεύονται στο μοντέλο ανάπτυξης διαδικτύου. Δυστυχώς, το μοντέλο ασφαλείας blockchain μοιάζει περισσότερο με το παλαιότερο μοντέλο.

Στο blockchain, ο κώδικας είναι εγγενώς μη αναστρέψιμος. Μόλις αναπτύξετε ένα κακό έξυπνο συμβόλαιο, ο καθένας είναι ελεύθερος να το επιτεθεί όσο το δυνατόν περισσότερο και σκληρά και δεν υπάρχει τρόπος να το πάρετε πίσω αν φτάσουν πρώτα. Αν δεν ενσωματώσετε έξυπνους μηχανισμούς ασφαλείας στα συμβόλαιά σας, εάν υπάρχει σφάλμα ή επιτυχημένη επίθεση, δεν υπάρχει τρόπος να κλείσετε τους διακομιστές σας και να διορθώσετε το λάθος. Όντας εξ ορισμού στο Ethereum σημαίνει ότι όλοι κατέχουν τον διακομιστή σας.

Ένα κοινό ρητό στην ασφάλεια στον κυβερνοχώρο είναι «η επίθεση είναι πάντα πιο εύκολη από την άμυνα». Το Blockchain πολλαπλασιάζει απότομα αυτήν την ανισορροπία. Είναι πολύ πιο εύκολο να επιτεθείς επειδή έχεις πρόσβαση στον κώδικα κάθε συμβολαίου, ξέρεις πόσα χρήματα είναι σε αυτό και μπορεί να διαρκέσει όσο θέλεις να προσπαθήσεις να το επιτεθείς. Και όταν η επίθεσή σας είναι επιτυχής, μπορείτε ενδεχομένως να κλέψετε όλα τα χρήματα στο συμβόλαιο.

Φανταστείτε ότι χρησιμοποιούσατε λογισμικό για μηχανήματα αυτόματης πώλησης. Αλλά αντί για ένα σφάλμα που σας επιτρέπει να κλέψετε απλά καραμέλα από ένα μηχάνημα, το σφάλμα σας επέτρεψε να κλέψετε ταυτόχρονα καραμέλα από κάθε μηχανή στον κόσμο που χρησιμοποίησε αυτό το λογισμικό. Ναι, έτσι λειτουργεί το blockchain.

Σε περίπτωση επιτυχούς επίθεσης, η άμυνα είναι εξαιρετικά δύσκολη. Τα λευκά καπέλα στο Parity hack έδειξαν πόσο περιορισμένες ήταν οι επιλογές άμυνας τους - δεν υπήρχε τρόπος να ασφαλιστούν ή να διαλύσουν τα συμβόλαια, ή ακόμη και να χαράξουν τα κλεμμένα χρήματα. το μόνο που μπορούσαν να κάνουν ήταν να χαράξουν τα υπόλοιπα ευάλωτα συμβόλαια πριν το κάνει ο εισβολέας.

Αυτό μπορεί να φαίνεται να καταγράφει ένα σκοτεινό μέλλον.

Αλλά δεν νομίζω ότι αυτό είναι θάνατο για προγραμματισμό blockchain. Αντίθετα, επιβεβαιώνει αυτό που όλοι γνωρίζουν ήδη: αυτό το οικοσύστημα είναι νέο και ανώριμο. Θα χρειαστεί πολλή δουλειά για να αναπτυχθεί η εκπαίδευση και η πειθαρχία για τη διαχείριση έξυπνων συμβάσεων με τον τρόπο που οι τράπεζες αντιμετωπίζουν το λογισμικό ATM τους. Αλλά θα πρέπει να φτάσουμε εκεί για να είναι επιτυχημένο το blockchain μακροπρόθεσμα.

Αυτό σημαίνει ότι όχι μόνο οι προγραμματιστές ωριμάζουν και λαμβάνουν περισσότερη εκπαίδευση. Σημαίνει επίσης την ανάπτυξη εργαλείων και γλωσσών που κάνουν όλα αυτά ευκολότερα και μας παρέχουν αυστηρές εγγυήσεις σχετικά με τον κώδικά μας.

Ειναι νωρις ακομα. Το Ethereum είναι ένα έργο σε εξέλιξη και αλλάζει γρήγορα. Δεν πρέπει να αντιμετωπίζετε το Ethereum ως τράπεζα ή ως υποκατάστατο χρηματοοικονομικής υποδομής. Και σίγουρα δεν πρέπει να αποθηκεύετε χρήματα σε ένα ζεστό πορτοφόλι που δεν αισθάνεστε άνετα να χάσετε.

Παρ 'όλα αυτά, εξακολουθώ να πιστεύω ότι η Ethereum θα κερδίσει μακροπρόθεσμα. Και εδώ γιατί: η κοινότητα προγραμματιστών στο Ethereum είναι αυτό που την κάνει τόσο ισχυρή.

Το Ethereum δεν θα ζήσει ούτε θα πεθάνει λόγω των χρημάτων που περιέχει. Θα ζήσει ή θα πεθάνει με βάση τους προγραμματιστές που αγωνίζονται για αυτό.

Το πρωτάθλημα λευκών καπέλων που ενώθηκαν και υπερασπίστηκαν τα ευάλωτα πορτοφόλια δεν το έκαναν για χρήματα. Το έκαναν επειδή πιστεύουν σε αυτό το οικοσύστημα. Θέλουν το Ethereum να ευδοκιμήσει. Θέλουν να δουν το όραμά τους για το μέλλον να γίνεται πραγματικότητα. Και μετά από όλες τις εικασίες και την κερδοφορία, είναι τελικά αυτοί οι άνθρωποι που θα οδηγήσουν την κοινότητα στο μέλλον της. Είναι βασικά γιατί το Ethereum θα κερδίσει μακροπρόθεσμα - ή εάν εγκαταλείψουν το Ethereum, η εγκατάλειψή τους θα είναι ο λόγος που χάνει.

Αυτή η επίθεση είναι σημαντική. Θα ταρακουνήσει τους ανθρώπους. Θα αναγκάσει την κοινότητα να εξετάσει πολύ καλά τις βέλτιστες πρακτικές ασφάλειας. Θα αναγκάσει τους προγραμματιστές να αντιμετωπίσουν τον έξυπνο προγραμματισμό συμβολαίων με πολύ μεγαλύτερη αυστηρότητα από ό, τι σήμερα.

Αλλά αυτή η επίθεση δεν έχει κλονίσει τη δύναμη των κατασκευαστών που εργάζονται σε αυτά τα πράγματα. Έτσι με αυτή την έννοια είναι μια προσωρινή οπισθοδρόμηση.

Στο τέλος, τέτοιες επιθέσεις είναι καλές για να μεγαλώσει η κοινότητα. Σας καλούν στις αισθήσεις σας και σας αναγκάζουν να κρατήσετε τα μάτια σας ανοιχτά. Πονάει, και ο τύπος πιθανότατα θα χάσει την ιστορία. Αλλά κάθε τραύμα κάνει την κοινότητα πιο δυνατή και μας φέρνει πιο κοντά για να κατανοήσουμε βαθιά την τεχνολογία του blockchain - τόσο τους κινδύνους όσο και τις εκπληκτικές δυνατότητές του.

PS Εάν είστε προγραμματιστής και θέλετε να μάθετε περισσότερα σχετικά με την έξυπνη ασφάλεια συμβολαίου, αυτός είναι ένας πολύ καλός πόρος.

Errata: Αυτό το άρθρο είπε αρχικά ότι ο Gavin Wood ήταν ο προγραμματιστής του συμβολαίου, κάτι που είναι λανθασμένο. Ο Gavin είναι ο ιδρυτής της Parity και έδωσε ώθηση στη σύμβαση, αλλά δεν ήταν ο αρχικός προγραμματιστής. Αρχικά ισχυρίστηκε επίσης ότι τα πρόσθετα κεφάλαια 77 εκατομμυρίων δολαρίων ήταν ευάλωτα, αλλά αυτό δεν μετρά όλα τα διακριτικά ERC20 (ICO) που ήταν ευάλωτα. Το συνολικό ποσό είναι στην πραγματικότητα 150.000.000 $ + εάν συμπεριλάβετε όλα τα διακριτικά ERC20. Από τη στιγμή της σύνταξης αυτού (21 Ιουλίου 4:00 EST), η συνολική αξία των περιουσιακών στοιχείων που αποθηκεύτηκαν από τα λευκά καπέλα ήταν 179.704.659 $.