Слабый генератор случайных чисел в CryptoJS привёл к краже $5,7 млн из криптокошельков

· Безопасность
Компания Coinspect установила, что источником серии краж из криптокошельков стала функция CryptoJS.lib.WordArray.random(), выдававшая предсказуемые seed-фразы. Пострадали пять приложений, а измеренные потери превысили 5,7 миллиона долларов.

cover.svg

Компания Coinspect, специализирующаяся на безопасности блокчейна, назвала виновника серии опустошений криптокошельков, которую сама же окрестила «Ill Bloom» в июле. Им оказалась функция CryptoJS.lib.WordArray.random() из популярной JavaScript-библиотеки криптографии. Появившаяся 12 лет назад, она выдавала слишком слабую энтропию — и именно на её основе некоторые кошельки генерировали recovery-фразы.

Масштаб проблемы наглядно виден в цифрах. Для 128- и 256-битной энтропии пространство перебора должно составлять 2^128 и 2^256 вариантов. Уязвимый генератор сокращал его примерно до 2^39 и 2^47 — то есть до величин, которые перебираются на обычном компьютере. Исследователи воспроизвели атаку: перебрали выходные значения, превратили их в BIP39-фразы, вычислили адреса и сверили с публичными данными блокчейна.

Пять приложений и деньги двумя волнами

Coinspect подтвердила пять затронутых приложений: RRWallet (заброшено, исправлений нет), Bexo Wallet (исправлено в 20.1.0, но обновлённые сборки ещё не выложены), NanChat (исправлено в 1.3.0), Bitcoin Libre (исправлено в версии 4 ещё в июле 2024 года) и Milo (заброшено). При этом фирма честно оговаривается: полный список пострадавших кошельков установить невозможно — часть из них уже удалена из магазинов приложений.

По оценке Coinspect, кражи прошли двумя волнами. 27 мая было выведено около $3,14 млн с 431 счёта, а с 30 мая по 13 июля — ещё $2,55 млн с адресов, связанных с 522 seed-фразами, включая примерно 2,18 млн USDT с одного Tron-аккаунта 4 июля. Суммарно измеренные потери составили $5 690 922, и это, подчёркивают исследователи, лишь нижняя граница. Анализ охватил 2114 seed-фраз и адреса в сетях Bitcoin, Ethereum, Tron, Rootstock и Polygon.

Ирония истории: исправление, которое откатили

Отдельного упоминания заслуживает судьба самой уязвимости. Слабый генератор Multiply-With-Carry, инициализируемый через Math.random(), пришёл в библиотеку в июне 2014 года. Версии 3.2.0 и 3.2.1 перешли на нативную криптографическую случайность — но в 3.3.0 старый код вернули обратно, посчитав изменение ломающим совместимость. В результате обновление в пределах ветки 3.x могло увести проект от исправленной версии к уязвимой. Окончательно проблему закрыли лишь в версии 4.0.0 в феврале 2020 года.

5 августа сопровождающий CryptoJS Эван Восберг опубликовал бюллетень GHSA-rg76-677x-56q9 с критическим рейтингом и оценкой CVSS 9.0. Важная оговорка: наличие зависимости само по себе не делает приложение уязвимым — опасна лишь генерация чувствительных значений этой функцией.

Главное для пользователей: обновление приложения не чинит уже созданную фразу. Recovery-фраза, сгенерированная уязвимой версией, остаётся угадываемой везде, куда её импортируют, — в том числе в аппаратный кошелёк. Тем, чьи фразы могли пройти этот путь, придётся создать новую и перевести средства. Публичный чекер Coinspect принимает адреса, но не сами фразы или ключи.


Источник: The Hacker News

Комментарии

Войдите, чтобы комментировать.

  • Пока нет комментариев.