Биткоин: работа продолжается. Глава 8
Технические инновации из окопов
Перевод NADO Book by Sjors Provoost.
Проект перевода организован HypeCoinNews.
Фейковые узлы
В этой главе рассказывается об атаке, имевшей место летом 2021 года. В ней обсуждается, что произошло, выдвигаются предположения, почему это могло произойти, и рассказывается об исправлении, которое предотвратит повторение этой атаки.
Случайные подключения
В середине 2021 года владельцы узлов начали замечать, что к ним подключаются случайные люди.
Для прочтения ветки, в которой упоминается об этой атаке, см. ссылку.
Это само по себе совершенно нормально. Как мы объясняли в главе @sec:dns, это часть механизма первоначальной загрузки узлов в сеть. Новые узлы случайным образом подключаются к существующим узлам и запрашивают адреса других узлов для подключения еще и к ним. Они также объявляют свой собственный IP-адрес, о котором начинают ходить сплетни, поэтому достаточно скоро узел будет получать входящие соединения.
Однако в данном случае было необычно то, что эти случайные люди подключались к ним, а затем отправляли 500 сообщений, и каждое из этих 500 сообщений содержало 10 IP-адресов, которые должны были представлять другие узлы в сети. После этого они просто отключались. Это, конечно, не казалось опасным, но это было не обычным поведением.
Хотя сообщения были абсолютно достоверными, их содержание было бессмысленным, потому что IP-адреса, отправляемые этими узлами, были просто случайно сгенерированными числами. Вы могли бы понять это, если бы нанесли их на карту; шаблон распределения будет соответствовать шаблону случайно сгенерированных чисел. Другой способ, которым вы могли бы это установить, состоит в том, что список содержал IP-адреса, которые просто не могут существовать по разным причинам, например. потому что они зарезервированы для частных сетей, таких как 192.168.0.1.
Проблема с этими случайно сгенерированными IP-адресами заключается в том, что, если вы перегружены ими, практически невозможно подключиться к реальному узлу. Существует менее ста тысяч узлов, к которым может подключиться ваш узел, но существует четыре миллиарда адресов IPv4. Цель протокола сплетен об адресах как раз и состоит в том, чтобы предотвратить подобное случайное угадывание. Но силы этой атаки было недостаточно, чтобы привести к сбоям отдельных узлов.
По мере изучения этого явления было обнаружено, что оно происходит в довольно больших масштабах, и такое поведение классифицировали как атаку. На самом деле такая атака не представляет большой проблемы для отдельного узла, особенно если у него уже есть много IP-адресов от честных нод. Он может подключаться к нескольким несуществующим узлам, но в основном это пустая трата времени и ресурсов, поскольку он подключается и сохраняет IP-адреса, которые не являются реальными IP-адресами биткоин-узлов. Так что на индивидуальном уровне это похоже по эффекту на то, как ребенок бросает в вас маленький камешек.
Кроме того, мы знаем, что все это не имело большого значения, просто потому что почти никто даже не заметил происходящего. Но все же явление заслуживает расследования.
Для чего проводилась атака?
Через пару недель после этой атаки Матиас Грундманн и Макс Баумстарк написали статью с описанием атаки и рассуждениями о ее причинах.
Они предполагают, что этот злоумышленник не столько пробовал разрушить сеть, сколько пытался составить карту сети, чтобы понять, насколько хорошо узлы связаны друг с другом. И причина, по которой это вполне реально сделать, заключается в том, что, получив 10 IP-адресов, вы перенаправляете каждый из них ровно двум своим одноранговым узлам.
Дальше процесс не распространится. Хотя вы получили эти спам-адреса аккуратными пакетами по 10, ваш узел будет пересылать их пакетами куда большего размера. Узлы не пересылают адреса в пакете, если он больше 10, поэтому атака прекращается уже после двух прыжков.
Если злоумышленник также подключается к вам, используя обычный (не рассылающий спам) узел, он получит некоторую часть спам-адресов, который вы пересылаете. Из этой доли он может рассчитать, сколько у вас подключений. В более общем смысле, при подобной атаке наблюдения атакующий как бы отслеживает эхо своей собственной атаки. Глядя на это эхо, он может частично понять, как выглядит сеть, включая ее форму, насколько у нее хорошая связность, насколько она надежна и т. д. Эта информация потенциально могла быть востребована для будущих атак или же могла просто собираться в исследовательских целях.
Защитные механизмы
У узлов существуют некоторые защитные механизмы, затрудняющие использование этой информации. Например, если вы сообщаете узлу множество IP-адресов, он не сможет сразу подключиться ко всем из них — не только потому, что это слишком упростило бы приглашение узла к подключению к ловушке, но и потому что в большинстве случаев узел уже имеет достаточно соединений. Он также не ретранслирует их все, а для тех адресов, которые ретранслируются, существует случайная временная задержка. Таким образом, очень сложно сказать конкретно, какой узел соединяется с каким узлом, соединенным с каким узлом.
Эти защитные механизмы добавляются в Bitcoin Core постепенно, часто в качестве защиты от атак затмения, как мы рассказывали в главе @sec:eclipse. По сути, когда люди совершают атаки такого типа — странным образом исследуют сеть — опытные разработчики и исследователи безопасности смотрят на них и видят, что они могли бы добавить для противодействия таким атакам.
В этом случае была предложена контрмера. Обычно, когда люди ведут себя корректно, они подключаются к вам и отправляют вам один IP-адрес — и именно свой. Время от времени они отправляют вам другие IP-адреса, но не очень часто — средний узел будет делиться IP-адресом с узлом примерно раз в 20 секунд.
Поскольку злоумышленник будет отправлять адреса с гораздо более высокой скоростью, контрмерой будет введение ограничителя скорости. Такой узел как бы говорит: «Хорошо, когда новый узел подключается ко мне, я разрешаю ему отправлять мне один адрес немедленно, а затем я разрешаю до одного адреса каждые 20 секунд». Он отслеживает, сколько секунд прошло, и если узел отправляет слишком много адресов, он будет игнорировать новые, которые превышают лимит частоты. Таким образом, «злоумышленников» не наказывают, а скорее игнорируют.
Чрезмерное наказание за плохое поведение может привести к разделению сети, что злоумышленник может даже использовать, обманывая обычные узлы, чтобы они «разозлили» своих пиров и отключились.
Конечно, бывают случаи, когда узлы действительно хотят получить от своих пиров много адресов. Например, если кто-то подключается к вам, и вы говорите: «Пожалуйста, сообщите мне адреса, до тысячи штук», то, конечно, ответ не нужно ограничивать по скорости. В таком сценарии вы будете уверены, что вы действительно сможете получить от них эти адреса, но если вы их не запрашиваете, то просто ограничиваете скорость.
Ответственное раскрытие информации
Что действительно интересно, так это то, что это исправление было опубликовано за несколько недель до того, как произошла атака. Правка еще не была включена в код Bitcoin Core, а существовала в статусе открытого предложения об изменении. Оно оставалось открытым еще некоторое время после атаки, но затем было включено в код и вошло в состав версии 22.0.
Так что все выглядит так, как будто кто-то увидел контрмеру и сообразил о возможности проведения этой конкретной атаки. Или, может быть, кто-то уже планировал эту атаку, а тут решил, что должен сделать это как можно скорее, пока это не стало невозможным.
Чтобы узнать больше об этой атаке и связанных с ней проблемах, можно также послушатье отличный эпизод подкаста Chaincode Labs. Начиная с 23:15 «Ограничение скорости госсипа об адресах».
Были и другие примеры ситуаций, когда публикация исправления сама по себе могла вызвать атаку. Когда-то существовала альтернативная реализация узла под названием Bitcoin Unlimited. В ней была ошибка, которую затем исправили, но до того, как исправление было развернуто, ошибка была кем-то использована. Эта атака вывела из строя все существовавшие на тот момент узлы Bitcoin Unlimited.
Кроме того, примерно в 2013 году нечто подобное не произошло, но могло произойти и с самим Биткоином, о чем мы говорили в главе @sec:libsecp. Проблема была связана с тем, что библиотека OpenSSL стала более строгой, наложив ограничения на подписи. Если бы это было обнаружено всего несколько месяцев спустя, после того как релиз Bitcoin Core уже был выпущен с ошибкой в нем, ситуация стала бы критической. Возможно, в этом случае исправление пришлось бы, например, маскировать под софт для очистки, а не выпускать как патч для уязвимости в системе безопасности. Ведь если бы кто-то узнал об этом, он мог бы опубликовать немного другую подпись и вызвать форк, потому что некоторые узлы приняли бы ее, а другие — нет.
Последний пример — исправление бага инфляции в 2018 году. Он был представлен как исправление бага, который может привести к сбою вашего узла. И это было правдой — баг действительно мог привести к краху вашего узла, но также мог вызвать инфляцию. Последний факт был немного важнее, и он, конечно, не был объявлен, потому что кто-то мог бы воспользоваться им в открывшемся окне возможностей.
Один из способов справиться с подобными сценариями — сделать вид, что нечто не имеет большого значения, пока люди не загрузят исправление и не воспользуются им, а затем показать, что на самом деле ппр этом решалась гораздо более серьезная проблема. Это снижает вероятность того, что злоумышленник обнаружит уязвимость, пока она еще может быть использована.
Но на самом деле это не идеальный подход, потому что при разработке софта с открытым исходным кодом хочется быть очень прозрачным в отношении вещей, которые вы меняете. Потому что если вы непрозрачны в отношении исправления критической ошибки, то, возможно, вы также непрозрачны в отношении добавления инфляции. Тут приходится соблюдать тонкий баланс.
Поддержите проект(ы) на цепочке
HCN имеет две активные краудфандинговые компании на TallyCoin, которые собирают средства ончейн:
https://tallycoin.app/@hypecoinnews/
Или centralviola51@walletofsatoshi.com
Например из @LightningTipBot в Телеграме
/send 100 centralviola51@walletofsatoshi.com
Или начните пользоваться LN кошельком типа Valet.