Как многие, вероятно, уже знают, 12 июля произошел крайне неприятный инцидент, в ходе которого неизвестным злоумышленником было украдено более 80% BTC, хранившихся на кошельках RuDEX в блокчейне Bitcoin.
Ниже будут описаны детали инцидента, а также предложения по дальнейшим действиям для пользователей, пострадавшим в ходе произошедшего.
Инцидент 12.07.2023
Днём 12 июля в ходе обычной ежедневной проверки балансов на странице RuDEX Audit было выявлено несоответствие балансов BTC в блокчейне Graphene и блокчейне Bitcoin.
Расхождение в балансах составляло более 6 BTC. Это выглядело максимально странно, и мы немедленно стали выяснять, в чём может быть причина такой разницы.
Впрочем, это оказалось не так просто, как можно было бы подумать, т.к. шлюз работает в автоматическом режиме, мы не хранили весь пул адресов, используемых кошельком: они получались по API при каждом обращении к ноде на сервере.
Первоначально было подозрение, что просто на кошелёк ещё не вернулась сдача с одной из предыдущих операций по выводу (из-за типичной загруженности блокчейна Bitcoin). В пользу этого предположения говорил тот факт, что на кошельке остался баланс 1.05 BTC, а в случае кражи злоумышленник очевидно вывел бы все доступные средства (спойлер: выяснилось, что не всё так просто, как казалось на первый взгляд).
При обращении к кошельку напрямую через Cli wallet отображался тот же баланс, что и на странице аудита (1.053 BTC), неподтвержденный баланс отсутствовал.
Появилось предположение, что сдача могла вернуться на адрес нового формата, который не читается кошельком на ноде. Для его проверки мы решили экспортировать ключи в Bitcoin core на другом устройстве и синхронизировать его с нуля.
Параллельно мы выгрузили весь пул используемых адресов и стали проверять их на исходящие транзакции. Однако ничего интересного в исходящих транзакциях с известных адресов из пула обнаружено не было, неприятные новости пришли после того как синхронизировался Bitcoin Core.
В списке последних операций присутствовало две исходящие транзакции, которые не были инициированы шлюзом (на сумму 6.02 и 0.25 BTC).
Транзакция на 6.02 BTC была осуществлена на данный адрес, проведена она была 12 июля в 10:41(UTC).
С этого момента стало ясно, что биткоины с кошелька никуда не завалились, а были так или иначе украдены.
Когда факт кражи стал очевиден, мы вывели имеющийся баланс BTC на безопасный адрес и решили тщательнее проанализировать ситуацию и выявить возможные векторы атаки, чтобы понять, имеется ли угроза для остальных средств и как защититься от подобного в будущем.
Вариант с компрометацией сервера отпал сам собой, т.к. на данном сервере были ноды и кошельки с другими активами, из которых к счастью ничего не пострадало. Вариант с компрометацией сид фразы/ключей также сочли маловероятным, т.к. они использовались только один раз при импорте в ноду и затем надёжно хранились в зашифрованном виде.
Кроме того, имелся тот странный факт, что 1.05 BTC остались лежать на пострадавшем кошельке нетронутыми.
При более детальном рассмотрении мы выяснили, что все биткоины были выведены с Bech-32-адресов, которые создавались кошельком автоматически, как адреса для поступления сдачи после осуществлённых исходящих транзакций. При этом все адреса, созданные кошельком в ходе его эксплуатации шлюзом (адреса для депозитов пользователей) остались нетронутыми. По несчастливому стечению обстоятельств большая часть средств находилась на адресе Bech-32, поступив туда в виде сдачи.
Тот факт, что во второй транзакции на 0.25 BTC помимо наших адресов в числе отправителей было ещё более 1200 адресов на общую сумму более 14,8 BTC, наводил на мысль о том, что вероятно для осуществления данной кражи злоумышленник использовал уязвимость в какой-либо библиотеке (уязвимость нулевого дня) или закладку.
Увидев, что кража затронула множество адресов, мы создали темы о данном инциденте на Reddit и на Bitcointalk с целью поиска других пострадавших и выяснения возможных причин случившегося.
Некоторое время спустя с нами связался пользователь Reddit, который являлся сотрудником организации, занимающейся информационной безопасностью — по странному стечению обстоятельств он и его друг тоже пострадали в ходе данной атаки. Мы поделились всей имевшейся у нас информацией, и через непродолжительное время появились первые результаты расследования. Сбылись наши самые худшие опасения: в библиотеке Libbitcoin обнаружилась уязвимость нулевого дня, связанная со слабой энтропией при генерации seed. К слову, опенсорс библиотека Libbitcoin существует с 2011 года, пользуется немалой популярностью, и её использование даже описано в книге "Mastering Bitcoin".
Вы можете ознакомиться с переводом технического отчёта об уязвимости от расследовавшей её команды более подробно по ссылкам: часть 1, часть 2.
ВЫВОДЫ
Как ни соблюдай безопасность, всего не предусмотришь, и уязвимость может обнаружиться даже в софте, который существует десятилетиями.
Предложения
Мы подготовили ряд предложений для пострадавших в результате кражи BTC:
- Мы продали BTC за USDT на Binance по курсу 34000 (24.10.2023)
- Сделали депозит USDT на RuDEX на специальный аккаунт для выкупа, btc-return1
- Поставили лимитный ордер на откуп rudex.BTC за 4890.6168 USDT
- Те пользователи, кого устраивает вариант с возвратом части средств, могут продать свои rudex.BTC за USDT и вывести их прямо сейчас
- Те пользователи, кого данный вариант не устраивает, могут отправить свои rudex.BTC на аккаунт btc-return2
- Срок принятия решения до 1 марта 2024 года. После этой даты все Rudex.BTC будут сожжены.
- Пользователи, отправившие rudex.BTC на аккаунт btc-return2, в марте получат с этого аккаунта ваучеры (специальный токен 1:1) на возврат реальных BTC в будущем.
Благодарим за внимание и ещё раз приносим извинения за случившееся.
@rudex, блять. Жестко.
@rudex, можно вопрос(ы)? я так понял, что накосячил именно сам bitcoin core? и если это он сам, то получается что генерация адресов для сдачи и генерация новых адресов (для клиентов) идет внутри самого кошелька разными функциями? или генерация адресов для клиентов у вас была отдельным вызовом из нескомпроментированной библиотеки.
или у вас скрипты были написаны используя библиотеку libbitcoin, а не через json-rpc к bitcoin-core?
@rudex, Спасибо значит до первого Марта можно еще подумать ? и не продавать со скидкой и вывод откроется в следующем году ?