Содержание статьи
17 июня 2016 года неизвестный злоумышленник перекачал на свои счета около трети фондов проекта DAO. Атака продолжалась несколько часов. За это время он успел захватить более 3,6 миллиона эфиров — сумму, эквивалентную примерно 50 миллионам долларов.
- Сегодня в эфире. Краткий экскурс в Ethereum
- Интервью: Виталик Бутерин о себе и о создании Ethereum
- Внимание, это розыгрыш! Пишем простой смарт-контракт
- Ставим Ethereum на Raspberry Pi
- Распределенное автономное ограбление. Как хакер разорил автоматическую корпорацию DAO
Что такое DAO
Когда речь идет о DAO, путаница неизбежна. Помимо проекта DAO (The DAO), который стал жертвой атаки, есть еще и просто DAO — термин, которым обозначают распределенные автономные организации (Distributed Autonomous Organization). Такие организации отличаются от обычных примерно тем же, чем умные контракты от традиционных: и в том и в другом случае люди остаются за кадром. Структуру, цели и внутренние процессы такой организации определяют не ее менеджеры и сотрудники, а программный код.
Самый очевидный пример распределенных автономных организаций — это сами криптовалюты. Они никому не принадлежат и никому не подчиняются. В их деятельности участвуют тысячи человек, но они не контролируют Bitcoin или Ethereum. Никто не контролирует. Устройство и принцип действия криптовалюты зависят не от людей, а от ее протокола. Люди лишь следуют ему.
Все эти качества в полной мере описывают и злополучный проект DAO. Он должен был стать чем-то вроде криптовалютного «Кикстартера» — прозрачного, децентрализованного и свято чтущего волю каждого участника. Проект придумали и реализовали в немецком стартапе Slock.it, который разрабатывает электронные дверные замки. Его основатели надеялись с помощью DAO найти инвестиции под свои идеи.
С технической точки зрения проект DAO представляет собой умный контракт Ethereum. И это очень непростой контракт. Он описывает все аспекты функционирования этой организации. После создания DAO следует стадия первоначального накопления капитала — 27 дней, в течение которых любой желающий может купить токены организации и стать его полноправным участником. Затем начинается работа: желающие выставляют свои идеи на суд публики, а обладатели токенов голосуют. Победители получают финансирование. И голосование, и финансирование, и распределение прибыли происходит автоматически.
Распродажа токенов проекта DAO началась 30 апреля 2016 года. Спустя 27 дней их приобрели более 11 тысяч человек. В результате под управлением единственного умного контракта оказалась сконцентрирована огромная сумма — больше 150 миллионов долларов. Таких денег при помощи краудфандинга не собирал никто и никогда.
В Slock.it определенно не ждали подобного развития событий, но к тому моменту их ожидания и планы уже не играли роли. Судьба 150 миллионов долларов теперь зависела не от них, а от кода контракта.
Распределенное автономное ограбление
Спустя всего три недели после открытия DAO участники сообщества Ethereum растерянно смотрели на уплывающие от них миллионы долларов и ничего не могли поделать. На счет организации одного из участников проекта уходили деньги, которые никак не могли ему принадлежать. При этом придраться было не к чему. Ethereum работал именно так, как должен. Код проекта DAO делал именно то, что в него заложено. Все было правильно, кроме результата.
Причину утечки нашли почти сразу. Организатор атаки заметил интересную особенность функции splitDAO, предназначенной для выхода из состава проекта DAO. Она создает дочернюю организацию, отправляет на ее счет долю основателя и только затем, в самом конце, обновляет баланс. Если рекурсивно вызвать ту же функцию еще раз, пока баланс не пересчитан, ничто не помешает ей повторно отправить дочернему DAO уже потраченные деньги.
Рекурсивный процесс разделения продолжается до тех пор, пока не упрется в технические ограничения Ethereum. В результате оказывается переведено в 20–30 раз больше средств, чем положено. Другая ошибка в функции withdrawRewardFor позволяет повторять такой трюк столько, сколько потребуется. Организатор атаки проделал его сотни раз.
Тут нужно осознавать все безумие происходящего. Это вовсе не обыкновенное ограбление. Строго говоря, это вообще не ограбление. И это не повторение истории Mt. Gox. Тогда пропало еще больше денег, но в данном случае интерес не в деньгах. Организация, которую затронул этот инцидент, настолько необычна, что и проблема, и ее решения имеют совершенно фантастическую окраску.
У проекта DAO нет серверов, которые можно выключить. У него нет банковских счетов, которые можно заморозить. У него нет даже владельца, который будет нести ответственность. На балансе — 150 миллионов долларов, которыми управляет обезумевшая программа на языке, похожем на JavaScript. Она убеждена, что эти деньги следует отправить злоумышленнику, — и отправляет, отправляет, отправляет.
Машинерия Ethereum гарантирует, что умные контракты не будут нарушены. Она не дает гарантии, что в них нет ошибок. Более того, само понятие «ошибка» чуждо его логике. Для Ethereum важнее, что разрешено и что запрещено. А это целиком и полностью определяет код контракта. Код контракта DAO пусть непреднамеренно, но разрешает выкачивать чужие миллионы. Следовательно, с точки зрения Ethereum, действия организатора атаки совершенно законны.
Тысячи майнерских узлов, исполняющих ошибочный контракт, автоматически проверяют каждую транзакцию, которую он инициирует. Они видят, что все верно, все законно, все условия соблюдены. В результате чужие деньги уходят организатору атаки, а информация об этом необратимо сохраняется в блокчейне. Вернуть их без согласия нового владельца невозможно.
Это первое автономное распределенное преступление. Одна неконтролируемая программа обманывает другую, а третья проверяет законность, следуя своей, совсем не человеческой логике, и считает деньги. Люди и хотели бы вмешаться, но для них тут места нет.
Выхода нет
Если бы речь шла об обычной программе и обычном взломе, дальнейшая тактика была бы ясна. Для начала нужно исправить уязвимость. Пропавшие деньги так не вернуть, но хотя бы остаток будет в безопасности. Затем следует любыми способами вывести его из-под удара.
Но умный контракт — это не простая программа. Умный контракт — это контракт, а контракты нельзя просто так взять и поменять. Их заключают для того, чтобы раз и навсегда закрепить условия сделки и обязательства сторон. Они неизменны — в этом весь смысл. Исправления или отмены ошибочного контракта можно добиться через суд, но в Ethereum это по понятной причине невозможно.
Ни Ethereum, ни сам контракт DAO не предусматривают механизма, который позволил бы обновить код контракта. Перевести проект с одной версии программы на другую и сохранить его внутреннее состояние невозможно. Это, среди прочего, означает неизбежную утрату содержимого переменной extraBalance. У проекта DAO на ней записано несколько миллионов долларов.
Участники DAO могут в любой момент покинуть проект и забрать свою долю с собой. В разгар атаки многие пытались воспользоваться этой возможностью и обнаружили, что в сложившейся ситуации она ни на что не годится. Дело в том, что деньги со счета DAO нельзя конвертировать в эфир напрямую. Сначала они будут переданы дочерней организации при помощи той самой функции splitDAO, которая использована в атаке. Это долго и к тому же бессмысленно, потому что новорожденными DAO управляет тот же самый уязвимый код. Увели деньги из родительского DAO — уведут и с них.
Чем меньше денег оставалось на счетах DAO, тем очевиднее становилось, что простого выхода нет. Ошибку в контракте нельзя исправить — во всяком случае, быстро и без потерь. Деньги тоже не спасти — во всяком случае, быстро и без потерь. Созданная система не приспособлена ни для того ни для другого.
Что делать дальше? Основатели проекта DAO призвали своих сторонников ломать систему. Они опубликовали код, массовое исполнение которого перегрузит сеть Ethereum. DDoS не остановит атаку на DAO, но замедлит ее и даст время на поиск решения.
Экстраординарные меры
Спустя несколько часов в события вмешался создатель Ethereum Виталик Бутерин. Через официальный блог криптовалюты Бутерин предложил провести так называемое мягкое ветвление (soft fork) программного обеспечения Ethereum и заблокировать похищенные деньги.
Речь, в сущности, идет о внесении поправок в правила криптовалюты, в результате которых отдельные виды сделок окажутся под запретом. После мягкого ветвления в Ethereum появится черный список, мешающий вывести средства со счетов любых дочерних DAO, которые принадлежат организатору атаки. Изменения софта затронут лишь майнеров. Остальные пользователи Ethereum смогут работать с старым софтом.
Дело в том, что для Ethereum проект DAO слишком важен, чтобы пустить все на самотек. До атаки на его балансе находилось около 15% существующего эфира. Неконтролируемый развал DAO вполне способен нанести ущерб Ethereum и временно испортить репутацию самой концепции умных контрактов.
Однако никто, даже сам создатель криптовалюты, не может вмешаться в ее работу по собственной воле. Чтобы мягкое ветвление состоялось, предложение должно поддержать большинство майнеров. Поскольку они кровно заинтересованы в будущем Ethereum, это, очень вероятно, произойдет. А колеблющихся, скорее всего, подтолкнет риск потери эфира в том случае, если они окажутся в меньшинстве.
Дальше, согласно предложению, которое поддержал Бутерин, может последовать жесткое ветвление. В этом случае весь эфир, вырученный в результате атаки, вернется на счета проекта DAO. Затем DAO, по всей видимости, распустят, а его фонды поделят между обладателями токенов, причем не согласно контракту, а так, будто его и не было.
Жесткое ветвление потребует всеобщей замены софта — почти как при переходе на новую криптовалюту. Проапгрейдиться придется не только майнерам, но и остальным.
Раскол
Если мягкое ветвление станет экстраординарным событием, то жесткое просто не имеет прецедентов. Контракты будут нарушены. Результаты сделок будут обращены вспять. Это вещи, которые противоречат всем законам криптовалют. Но жесткое ветвление позволяет поменять любые законы и сделать немыслимое возможным.
Это опасный прецедент. Считается, что невозможность нарушения правил заложена в самой механике криптовалюты и подкреплена тем, что все следят за всеми. Чтобы обмануть систему и протащить незаконную транзакцию, понадобится сговор, который объединит больше половины майнеров. Это, если майнеров достаточно много, очень маловероятно.
Необходимость и даже сама допустимость ветвления вызывает бурные дебаты. По своей сути они до боли похожи на споры по поводу компенсаций обманутым вкладчикам или держателям валютных ипотек. Одна сторона напирает на то, что людей жалко. Другая отвечает, что люди сами виноваты и должны отвечать за свои решения.
Насколько можно судить, многие видные участники сообщества Ethereum склоняются к мысли, что ветвление необходимо. Согласно одному из распространенных аргументов, оно убедит пользователей, что они защищены от уязвимостей и убытков. Есть, впрочем, и другое объяснение популярности этой позиции: многие видные деятели сообщества имеют те или иные связи с проектом DAO и просто хотят вернуть свои деньги.
Противники ветвления выступают, скорее, с идеологических позиций. Они утверждают, что не видят ничего предосудительного в действиях организатора атаки. Он не нарушил ни одного правила и по праву получил деньги. А пострадавшие пусть терпят. Когда невидимая рука рынка бьет по морде, это неприятно, но поучительно. В следующий раз будут думать, какие контракты подписывают.
По дискуссиям в Reddit и на форумах трудно определить, кто победит. Вполне возможно, никто, и тогда блокчейн раздвоится. Один хвост блокчейна достанется сторонникам ветвления, другой — раскольникам, которые не желают менять правила ради проекта DAO.
Игра на понижение
Договориться о ветвлении и провести его нужно в течение четырех недель, пока DAO злоумышленника находится в стадии накопления капитала и не начал работу в нормальном режиме. Однако предложение Виталика повлияло на развитие событий почти немедленно: атака остановилась.
Есть несколько теорий, объясняющих, почему это произошло. Вполне правдоподобным кажется предположение, что таким образом организатор атаки надеется уменьшить вероятность ветвления. В этом есть логика. Чем меньше ущерб от атаки, тем меньше людей, которые стали жертвой атаки и материально заинтересованы в ветвлении. Это повышает шансы на то, что награбленное удастся обналичить. Согласно другой теории, у злоумышленника кончились деньги на «горючее».
Спустя пару дней на Pastebin появилось открытое письмо, написанное от имени организатора атаки. Его автор заявлял, что считает ветвление посягательством на свое имущество и намерен защищать свои права на полученные деньги в суде. Подтверждений тому, что автор этого заявления действительно имеет отношение к украденным миллионам, нет.
![Послание от нового владельца миллионов The DAO](https://xakep.ru/wp-content/uploads/2016/07/1468478745_524c_pastebin.png)
![](https://xakep.ru/wp-content/uploads/2016/07/ipad_v-210x280.jpg)
Xakep #210. Краткий экскурс в Ethereum
Но и других зацепок, указывающих на личность организатора атаки, обнаружить не удалось. Организация, которой он воспользовался, была создана 8 июня. Забавная деталь: заявку на создание дочернего DAO сопровождал комментарий «Ах, как я одинок» («lonely, so lonely»). Впрочем, не факт, что ее подал злоумышленник. Он вполне мог присоединиться к уже существующей организации. Пара основных контрактов с токенами и кодом, эксплуатирующим дыру в коде проекта DAO, появились за два дня до атаки. Что касается аккаунтов, то до атаки они не светились.
Во время атаки курс эфира рухнул почти вдвое. 16 июня за один эфир давали 20,5 доллара. Спустя два дня он продавался по 11,2 доллара за штуку. К 24 июня криптовалюта немного оправилась, и теперь ее курс колеблется в районе 14 долларов за эфир. Такие перепады открывают богатые возможности для игры на понижение. Нельзя исключать, что атака была затеяна в первую очередь для того, чтобы сбить стоимость эфира. Если это так, то злоумышленник уже заработал свое и ветвление ему не повредит.
Техника безопасности
Пока одни пытались разобраться, кто увел деньги, а другие думали о причинах, третьи искали виноватых. Как вышло, что в коде DAO оказалась такая вопиющая дыра? Почему никто не заметил ее раньше? Куда смотрел Виталик, слывущий среди любителей Ethereum чуть ли не гением? И кто поручится, что аналогичных, а то и похуже, ошибок нет в других умных контрактах? На эти вопросы есть ответы, но они неприятны.
Можно сомневаться в квалификации программистов Slock.it (в конце концов, между программированием электронных замков и умных контрактов есть определенная разница), но код DAO изучали не только они. Его проверяли и перепроверяли специально приглашенные специалисты по информационной безопасности. Кроме того, исходники DAO были опубликованы на Гитхабе. Ошибку пропустили не только авторы контракта. Ее пропустили все.
Уже после атаки выяснилось, что в первой половине июня об уязвимости, которой затем воспользовался организатор атаки, независимо друг от друга узнали несколько исследователей и разработчиков, причастных к сообществам DAO и Ethereum. Речь, в частности, идет об одном из руководителей «Инициативы по криптовалютам и контрактам» Эмине Гюне Сирере и о предпринимателе Питере Вессенесе. Но к тому моменту проект DAO уже открылся, и чинить его было поздно.
Есть мнение, что и язык описания контрактов, выбранный Ethereum, и среда исполнения принципиально не подходят для решения задачи, которая перед ними стоит. Один из критиков ехидно заметил, что документация Solidity с гордостью сообщает, что этот язык похож на JavaScript, «как будто это достоинство».
В этом есть логика. Разные языки программирования порождают разные проблемы. Например, уязвимости, связанные с исполнением произвольного кода из-за переполнения буфера, — это неизбежный побочный эффект использования языков, которые поддерживают адресную арифметику. Отсутствие автоматической сборки мусора ведет к утечкам памяти и другим нарушениям безопасности памяти. Нельзя программировать, скажем, на C или C++ и надеяться, что таких ошибок не будет.
Проблема Solidity заключается в том, что язык не позволяет четко и недвусмысленно описать, какого результата пытается достичь автор умного контракта. На процесс исполнения может повлиять множество трудно контролируемых факторов, в том числе работа чужих скриптов, данные, поступившие извне или сохраненные ранее, а также наличие «горючего» или глубина использованного стека.
Потенциальные угрозы еще в 2015 году перечисляла работа «Шаги к созданию безопасных умных контрактов», опубликованная исследователями из университета Мэриленда. «Программирование умных контрактов требует экономического мышления, которое традиционному программисту может быть и не привито», — указывает она. Простейшая и очень распространенная ошибка, возникающая в результате, — утечка денег в крайних случаях, о которых программист не подумал.
Известна масса способов достичь большей надежности. Для разработки критически важных программ нередко используют языки, позволяющие описывать не только алгоритм, но и формальные спецификации компонентов (вспомните ADA или Eiffel). Программы на таких языках заведомо более предсказуемы и контролируемы. Чистые функциональные языки позволяют избегать «побочных эффектов». Результат работы такой программы может зависеть только от исходных данных и стопроцентно предопределен. Программирование умных контрактов зачастую сводится к построению сложных конечных автоматов. Это тоже хорошо изученная проблема, которую регулярно решают разработчики встроенных систем.
Контратака Робин Гудов
Прекращение атаки после выступления Бутерина не решило проблему. Уязвимость, которой воспользовался злоумышленник, никуда не делась. Она по-прежнему оставалась в контракте проекта DAO и других организаций, базирующихся на том же коде. Просто теперь о ней узнали все.
Повторные атаки были неизбежны, и они последовали. Ни одна из них не была сравнима по масштабам с первой, однако угрозу трудно было недооценивать. На счетах проекта DAO по-прежнему лежали более 100 миллионов долларов, совершенно не защищенные от посягательств злоумышленников.
Спустя четыре дня разработчики Ethereum и DAO выработали план спасения оставшихся денег. Условия контракта не предусматривают средств для вывода денег со счета проекта DAO, поэтому они решили вынести их через ту же дыру, которой пользовался организатор первой атаки. Иными словами, похитить — но на этот раз с добродетельными целями.
«С пятницы я находился в контакте с группой очень умных людей, намеренных повторить атаку, чтобы избежать новых утечек эфира. Назовем их, всех вместе, „Робин Гуд“, — написал на Reddit ведущий дизайнер фонда Ethereum Алекс ван де Санде. — Все они действуют от собственного лица и не представляют своих работодателей».
Робин Гуды сумели воспроизвести атаку на тестовой сети Ethereum. Следующий шаг — найти подходящее предложение о выделении дочернего DAO, к которому можно примкнуть, чтобы использовать в качестве плацдарма для контратаки (создавать собственное — слишком долго). Это удалось не сразу, но в итоге они внедрились во все открытые предложения и выбрали лучшие.
Пока Робин Гуды собирались, к проекту DAO присосался еще один злоумышленник. «Деньги утекали медленно, считаные эфиры за раунд, но в сумме набежало уже несколько тысяч долларов, — рассказывал потом ван де Санде. — Складывалось впечатление, что кто-то примеривается и смотрит, нельзя ли выкачать еще». И действительно, темп скоро вырос. Кроме того, стали присоединяться другие. Самые эффективные взломщики делали до 30 рекурсий за раз и перемещали по 200 эфиров в каждой. Тянуть с контратакой было больше нельзя.
Чтобы ускорить процесс, Робин Гуды решили привлечь побольше токенов DAO. Чем больше у контракта токенов, тем быстрее он может выкачивать деньги. Для этого они скинулись сами и вышли на крупных «инвесторов», готовых пожертвовать средства на благое дело. В сумме набралось около шести миллионов токенов.
21 июня они запустили контратаку и успешно выкачали 7,3 миллиона эфира в одно дочернее DAO и еще 353 тысячи эфира в другое дочернее DAO. Таким образом, они получили контроль над средствами, эквивалентными примерно 105,7 миллиона долларов. Это соответствует примерно 70% фондов проекта DAO. Около 4,8 миллиона долларов, лежавших на extraBalance, извлечь не удалось.
Увы, вскоре выяснилось, что ликование было преждевременным. В DAO Робин Гудов уже просочился организатор одной из атак на проект DAO, и это значит, что через 27 дней история может повториться.
В общем, если нам придется жить в мире умных контрактов, то скучать ни специалистам по безопасности, ни хакерам не придется.