30 июля неизвестный оператор за 41 минуту опустошил 1 196 биткоин-адресов, собрав 1 082,65 BTC стоимостью около $70,2 млн на тот момент. Galaxy Research составила карту переводов и связала их с ошибкой прошивки аппаратных биткоин-кошельков Coldcard, которые выпускает канадская компания Coinkite. Личность отправителя публично не установлена.

Связь строится на редком рисунке транзакций: 1 196 адресов, комиссия 30 sat/vB и перевод без сдачи. Galaxy Research не обнаружила за предшествующие 30 дней других биткоин-транзакций с таким же сочетанием признаков. Но этот рисунок позволяет опознать оператора, а не доказать кражу: подобная консолидация, по предупреждению исследователей, «выглядит точно так же, как если бы владелец монет сам решил их переместить». Пока никто публично не восстановил seed жертвы через уязвимость и не сопоставил его с одним из опустошённых адресов.
Ошибка появилась при интеграции прошивки в марте 2021 года. Генерация seed была направлена в детерминированный программный генератор псевдослучайных чисел PRNG, хотя должна была использовать аппаратный генератор RNG микроконтроллера STM32. Block проследила проблему до производственной конфигурации Coldcard, где макрос MICROPY_HW_ENABLE_RNG задавался равным нулю. Coinkite сделала это намеренно, поскольку использовала собственную обёртку для аппаратного RNG.
Библиотека libngu проверяла лишь существование макроса MICROPY_HW_ENABLE_RNG, но не выясняла, включён ли он в действительности. Поэтому сборка Coldcard привязывалась к детерминированному резервному генератору Yasmarang из MicroPython вместо аппаратного RNG. Начальное состояние Yasmarang формировалось из уникального идентификатора чипа UID и регистров таймера. После инициализации свежая энтропия больше не поступала, а значит, дальнейшая последовательность могла оказаться воспроизводимой.
По оценке Block, атакующий способен перебирать возможные потоки PRNG офлайн, если узнает или достаточно сузит UID устройства, состояние таймера и историю предыдущих обращений к RNG. Из каждого предполагаемого потока можно получить кандидатный seed, вывести соответствующие биткоин-адреса и сверить их с общедоступным блокчейном. Совпадение указывает на нужный кошелёк, после чего восстановленный seed даёт доступ к средствам. Физический доступ к Coldcard для такой атаки не обязателен, если неизвестные параметры устройства удаётся ограничить до практически перебираемого набора.
Обычная мнемоническая фраза BIP-39 из 12 слов рассчитана на 128 бит энтропии. Coinkite оценила эффективную энтропию затронутых Coldcard Mk3 примерно в 40 бит, а Mk4, Mk5 и Q — примерно в 72 бита. Block не назвала единую практическую стойкость, установив лишь условные верхние границы ниже 2^40,7 для раннего сценария и ниже 2^73,3 для позднего. Последнее число нельзя читать как полноценную 73-битную криптографическую защиту. Бенчмарков полного перебора Block не публиковала.
В более поздних моделях Coldcard выполняется дополнительный reseed, из-за чего число кандидатов возрастает. Реальная цена атаки всё равно зависит от объёма известных данных об UID, времени загрузки устройства, количества и порядка прежних вызовов RNG, а также затрат на вывод адресов и кошельков. Поэтому оценки Coinkite описывают масштаб ослабления, но сами по себе не сообщают, сколько часов, оборудования или денег потребовалось бы конкретному злоумышленнику.
Уязвимость определяется прошивкой, на которой seed был создан, а не версией, установленной сегодня. Coinkite прямо указывает для Mk3 версии 4.0.1–4.1.9; исправление появилось в 4.2.0. Mk2 компания отдельно в перечне не называет, тогда как Block относит Mk2 и Mk3 с прошивками 4.0.0–4.1.9 к уязвимому пути исполнения. Для Mk4 и Mk5 затронуты все обычные версии до 5.6.0, для Q — до 1.5.0Q.
Среди экспериментальных Edge-сборок для Mk4 и Mk5 опасными считаются версии до 6.6.0X, а для Q — до 6.6.0QX. 31 июля Coinkite выпустила экстренные прошивки для каждой затронутой модели и каждой ветки релизов. Обновление блокирует ошибочный способ генерации новых seed, но не исправляет уже созданную мнемоническую фразу: её недостаточная случайность записана, грубо говоря, в самих словах.
Владельцу потенциально затронутого кошелька нужно установить исправленную прошивку, создать на ней совершенно новый seed и перевести все монеты со старых адресов на адреса нового кошелька. Восстановление прежнего seed на обновлённом Coldcard, другом аппаратном устройстве или программном кошельке ничего не лечит. Слабость переносится вместе с мнемонической фразой, какой бы интерфейс потом её ни использовал.
Seed, созданный с помощью как минимум 50 честных, независимых и сохранённых в тайне бросков кубика, по заявлению Coinkite, сам по себе этой ошибке не подвержен. Все условия существенны: кубик не должен быть смещён, результаты бросков не должны зависеть друг от друга, а посторонний не должен их видеть. При сомнениях в числе бросков, их качестве или конфиденциальности Coinkite советует перейти на новый seed. Сильная уникальная парольная фраза BIP-39 создаёт отдельный кошелёк, недоступный по одним seed-словам, однако полагаться только на неё компания тоже не рекомендует.
Мультиподпись снижает риск лишь тогда, когда кворум нельзя собрать целиком из ключей, созданных уязвимыми прошивками Coldcard. Если все ключи, достаточные для подписи, получены на затронутых устройствах или из ослабленных seed, multisig может не спасти средства; в кворуме должно оставаться достаточно незатронутых ключей. Продукты Coinkite TAPSIGNER, OPENDIME и SATSCARD используют другие кодовые базы и этой ошибкой не затронуты. При этом перевод 1 082,65 BTC остаётся лишь вероятно связанным с дефектом: публичного восстановления seed и доказанного совпадения с опустошённым адресом до сих пор нет.

Изображение носит иллюстративный характер
Связь строится на редком рисунке транзакций: 1 196 адресов, комиссия 30 sat/vB и перевод без сдачи. Galaxy Research не обнаружила за предшествующие 30 дней других биткоин-транзакций с таким же сочетанием признаков. Но этот рисунок позволяет опознать оператора, а не доказать кражу: подобная консолидация, по предупреждению исследователей, «выглядит точно так же, как если бы владелец монет сам решил их переместить». Пока никто публично не восстановил seed жертвы через уязвимость и не сопоставил его с одним из опустошённых адресов.
Ошибка появилась при интеграции прошивки в марте 2021 года. Генерация seed была направлена в детерминированный программный генератор псевдослучайных чисел PRNG, хотя должна была использовать аппаратный генератор RNG микроконтроллера STM32. Block проследила проблему до производственной конфигурации Coldcard, где макрос MICROPY_HW_ENABLE_RNG задавался равным нулю. Coinkite сделала это намеренно, поскольку использовала собственную обёртку для аппаратного RNG.
Библиотека libngu проверяла лишь существование макроса MICROPY_HW_ENABLE_RNG, но не выясняла, включён ли он в действительности. Поэтому сборка Coldcard привязывалась к детерминированному резервному генератору Yasmarang из MicroPython вместо аппаратного RNG. Начальное состояние Yasmarang формировалось из уникального идентификатора чипа UID и регистров таймера. После инициализации свежая энтропия больше не поступала, а значит, дальнейшая последовательность могла оказаться воспроизводимой.
По оценке Block, атакующий способен перебирать возможные потоки PRNG офлайн, если узнает или достаточно сузит UID устройства, состояние таймера и историю предыдущих обращений к RNG. Из каждого предполагаемого потока можно получить кандидатный seed, вывести соответствующие биткоин-адреса и сверить их с общедоступным блокчейном. Совпадение указывает на нужный кошелёк, после чего восстановленный seed даёт доступ к средствам. Физический доступ к Coldcard для такой атаки не обязателен, если неизвестные параметры устройства удаётся ограничить до практически перебираемого набора.
Обычная мнемоническая фраза BIP-39 из 12 слов рассчитана на 128 бит энтропии. Coinkite оценила эффективную энтропию затронутых Coldcard Mk3 примерно в 40 бит, а Mk4, Mk5 и Q — примерно в 72 бита. Block не назвала единую практическую стойкость, установив лишь условные верхние границы ниже 2^40,7 для раннего сценария и ниже 2^73,3 для позднего. Последнее число нельзя читать как полноценную 73-битную криптографическую защиту. Бенчмарков полного перебора Block не публиковала.
В более поздних моделях Coldcard выполняется дополнительный reseed, из-за чего число кандидатов возрастает. Реальная цена атаки всё равно зависит от объёма известных данных об UID, времени загрузки устройства, количества и порядка прежних вызовов RNG, а также затрат на вывод адресов и кошельков. Поэтому оценки Coinkite описывают масштаб ослабления, но сами по себе не сообщают, сколько часов, оборудования или денег потребовалось бы конкретному злоумышленнику.
Уязвимость определяется прошивкой, на которой seed был создан, а не версией, установленной сегодня. Coinkite прямо указывает для Mk3 версии 4.0.1–4.1.9; исправление появилось в 4.2.0. Mk2 компания отдельно в перечне не называет, тогда как Block относит Mk2 и Mk3 с прошивками 4.0.0–4.1.9 к уязвимому пути исполнения. Для Mk4 и Mk5 затронуты все обычные версии до 5.6.0, для Q — до 1.5.0Q.
Среди экспериментальных Edge-сборок для Mk4 и Mk5 опасными считаются версии до 6.6.0X, а для Q — до 6.6.0QX. 31 июля Coinkite выпустила экстренные прошивки для каждой затронутой модели и каждой ветки релизов. Обновление блокирует ошибочный способ генерации новых seed, но не исправляет уже созданную мнемоническую фразу: её недостаточная случайность записана, грубо говоря, в самих словах.
Владельцу потенциально затронутого кошелька нужно установить исправленную прошивку, создать на ней совершенно новый seed и перевести все монеты со старых адресов на адреса нового кошелька. Восстановление прежнего seed на обновлённом Coldcard, другом аппаратном устройстве или программном кошельке ничего не лечит. Слабость переносится вместе с мнемонической фразой, какой бы интерфейс потом её ни использовал.
Seed, созданный с помощью как минимум 50 честных, независимых и сохранённых в тайне бросков кубика, по заявлению Coinkite, сам по себе этой ошибке не подвержен. Все условия существенны: кубик не должен быть смещён, результаты бросков не должны зависеть друг от друга, а посторонний не должен их видеть. При сомнениях в числе бросков, их качестве или конфиденциальности Coinkite советует перейти на новый seed. Сильная уникальная парольная фраза BIP-39 создаёт отдельный кошелёк, недоступный по одним seed-словам, однако полагаться только на неё компания тоже не рекомендует.
Мультиподпись снижает риск лишь тогда, когда кворум нельзя собрать целиком из ключей, созданных уязвимыми прошивками Coldcard. Если все ключи, достаточные для подписи, получены на затронутых устройствах или из ослабленных seed, multisig может не спасти средства; в кворуме должно оставаться достаточно незатронутых ключей. Продукты Coinkite TAPSIGNER, OPENDIME и SATSCARD используют другие кодовые базы и этой ошибкой не затронуты. При этом перевод 1 082,65 BTC остаётся лишь вероятно связанным с дефектом: публичного восстановления seed и доказанного совпадения с опустошённым адресом до сих пор нет.