Слабый генератор случайных чисел в CryptoJS привёл к краже $5,7 млн из криптокошельков
Компания 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
Комментарии
Войдите, чтобы комментировать.