Искривления времени, уязвимости майнинга, DOS-атака и многое другое.
Криптоэнтузиасты любят рассказывать обычным людям о надежности и безопасности блокчейн-протоколов, на которых работают их любимые коины. И действительно, крупнейшие криптовалюты, такие, как Биткойн или Ethereum, обеспечивают достойный уровень безопасности, и, возможно, делают это лучше, чем какой-либо другой цифровой актив или платежная система в истории. Это довольно большое достижение, учитывая, что эти криптовалюты ничем не обеспечены и никем не контролируются.
Многие, однако, осмеливаются утверждать, что упомянутые криптовалюты невозможно взломать в принципе. Это, по меньшей мере, тактический просчет, так как в некоторых случаях такие утверждения могут поставить человека в неловкое положение. Например, если валюту все-таки взломают.
В таких случаях, если ничего другого не остается, нужно, пожалуй, хотя бы объясниться.
В прошлом месяце хакер, личность которого до сих пор не установлена, взломал Verge – относительно небольшую криптовалюту с акцентом на анонимности пользователей. В промежутке между 4 и 6 апреля, неизвестному хакеру удалось трижды взять сеть Verge под контроль на несколько часов, в течение которых остальные пользователи не могли совершать платежи. Что еще хуже, в эти интервалы времени хакер выпускал поддельные коины Verge со скоростью 1 560 коинов (примерно 80$) в секунду. В результате хакер “начеканил” криптовалюты на сумму свыше 1 миллиона долларов.
Эту ситуацию можно без преувеличения назвать катастрофической. Verge взломали по-крупному.
Но кто виноват? Была ли это ошибка разработчиков Verge, фундаментальная уязвимость криптопротокола или что-то еще? Может ли подобное произойти с более крупными криптовалютами, и если да, то как этого избежать?
При такого рода взломах многие детали всегда остаются неясными. Однако в данном случае можно определить основные уязвимости:
Спуфинг временных меток: непреднамеренные ошибки или опасная ложь?
На первый взгляд эта уязвимость может показаться багом, однако на самом деле это специальная функция для создания “неточных” отметок времени. В блокчейн-протоколах отдельные транзакции (обычно это переводы между участниками сети) группируются в единый блок, который затем проходит верификацию. У каждого блока есть временная отметка о дате его формирования. Даже если блокчейн-протокол работает нормально, последовательность этих отметок может быть нарушена – например, у блока 100 может быть временная отметка, которая идет после блока 101. Это связано с тем, что в децентрализованных сетях, которые отказываются предоставлять права третьим сторонам, совсем непросто наладить правильную синхронизацию времени.
Учитывая непредсказуемое количество времени, которое требуется для распространения данных через одноранговую (peer-to-peer) сеть, блоки вполне могут появляться «не по порядку», даже если все стороны будут добросовестно проводить операции. Другими словами, в этом отношении приходится допускать хотя бы небольшую гибкость; в случае Verge (по крайней мере, до взлома) протокол позволял узлам «не соглашаться» насчет обозначенного в блоке текущего времени, и рассинхронизация могла составлять вплоть до двух часов.
Хакер начал свою атаку с подделки временных отметок. Он отправлял блоки как будто из прошлого, но не выходя за пределы допустимых 2 часов, а значит, эти блоки оставались приемлемыми для остальных узлов сети.
Причина, по которой это в конечном итоге могло повлиять на безопасность сети, кроется в характере майнинга для Proof-of-Work-сетей.
Трудность майнинга: стены защищают только если они высокие
Для децентрализации сети Verge необходимо убедиться, что небольшие устройства (например, макбуки) могут запускать ПО сети. Это, в свою очередь, ведет к ограничению объемов платежей в сети, т. е. к установке целевого времени для блока (и, как следствие, к ограничению количества транзакций в секунду). Сеть Verge работала со скоростью 1 блок в 30 секунд. Учитывая, что сеть децентрализована, можно задать резонный вопрос: а что мешает участникам отправлять блоки с гораздо большей скоростью? Это нетривиальная проблема: если каждый подтвержденный блок приносит награду тому, кто его сформировал, то майнеру выгодно подтверждать как можно больше блоков.
Если вкратце, то решением этой проблемы является решение протокола proof of work. Для того чтобы сеть подтвердила блок, тот должен содержать решение криптографически сложной вычислительной задачи, поступившей непосредственно из данных в самом блоке. Характер этой задачи таков, что ее сложность можно легко изменять. Verge стремилась к формированию 1 блока в 30 секунд, а сложность майнинга постоянно корректировалась на основе текущей скорости подтверждения блока; если пользователи решали выделить больше мощности для майнинга и генерации блоков Verge, и эти блоки генерировались быстрее, то протокол увеличивал сложность майнинга, и подтверждение блока замедлялось. И наоборот, по мере уменьшения мощности и увеличения времени на генерацию блока, майнинг становился проще. Таким образом, при корректной работе, при изменении внешних факторов даже в реальном мире – экономических колебаниях, в рыночных ценах криптовалют, на энергетических рынках, расцвете и падении империй и т. д. – сеть Verge постоянно реагировала на изменения и стремилась привести формирование блоков в единицу времени к целевому показателю.
Алгоритм, который Verge использует для вычисления текущей сложности задач, называется Dark Gravity Wave; он рассчитывает взвешенное среднее значение скорости подтверждения блока за период в 2 часа. Это сложный алгоритм, и подробности здесь не имеют особого значения. Важно то, что сложность майнинга зависит от скорости формирования последних блоков, а вычисление этой скорости, естественно, связано с временными отметками.
Именно в этом и заключается проблема: если создать достаточное количество ошибочных временных меток, баланс нарушается. Именно это хакер и сделал – данные из блокчейна показывают, что на протяжении всего времени взлома(-ов) каждый второй блок был отправлен с отметкой времени примерно за час до текущего времени, что сильно запутывало алгоритм настройки сложности майнинга. Если бы протокол обладал разумом и мог говорить, то сказал бы что-то вроде: «О нет! Что-то в последнее время формируется недостаточно блоков! Наверное, сложность майнинга слишком высока – надо ее снизить!»
Поскольку временные метки постоянно подделывались, протокол продолжал снижать сложность задач до тех пор, пока майнинг не стал смехотворно простым. Для общего понимания: средняя сложность задачи в часах была равна 1393093,39131 часам, а во время атаки она упала до 0,00024414, т. е. сложность майнинга снизилась на 99.999999%. Чем меньше сложность задачи – тем больше блоков можно сформировать и отправить в блокчейн; в результате атаки один блок отправлялся всего за 1 секунду.
Оригинальность атаки заключается в том, что хакер обошел ограничение на сложность майнинга, а не пробился сквозь него. Представьте, что система безопасности – это стена, которая окружает сеть, эта стена слишком высокая и крепкая, ее не сломать, и на нее не залезть. Хакер же нашел способ сделать ее ниже – и просто переступил через нее.
То, что эта уязвимость не была очевидной, вызывает тревогу. Столь открытая атака на протокол приведет к ухудшению репутации сети. Кроме того, увеличившийся темп создания блоков позволил создать куда больше коинов Verge, чем предусматривалось протоколом. Если вы экономист, который выступает за надёжную валюту с предсказуемым соотношением запасов и потоков, такая ситуация не может вас не взволновать.
Однако снижение сложности – это еще полбеды; само по себе, это фактически не давало бы злоумышленнику никакого преимущества. При сниженной сложности, формирование блоков действительно стало намного легче для хакера, но точно также оно стало легче и для всех остальных – майнеры продолжают конкурировать друг с другом, как и всегда. В этой ситуации мы предполагаем, что, хотя блоки и генерируются быстрее, но успешные майнеры должны оставаться распределенными и демократическими, как и раньше. Выражаясь иначе: независимо от сложности майнинга, для того, чтобы захватить сеть, злоумышленнику все равно понадобится контролировать не менее 51% мощности системы.
Однако этот хакер действительно захватил всю сеть и сумел сделать это с куда меньшими ресурсами, чем 51% от общего хэшрэйта. Он добился этого, воспользовавшись вторым компонентом этой уязвимости, связанным с использованием в Verge нескольких алгоритмов майнинга.
Продолжение следует…