Атака на Zcash-кошельки: вредоносный crate вместо полезного исправления

Атака на Zcash-кошельки: вредоносный crate вместо полезного исправления

Целевая атака на цепочку поставок задела разработчиков кошельков Zcash. Инструментами стали pull request под видом полезной автоматизации, вредоносный Rust-пакет и фишинг сопровождающих. Злоумышленника интересовали ключи подписи обновлений, токены GitHub и облачных сервисов, материалы подписи Android и зашифрованные хранилища Keplr MCP на рабочих машинах и сборочных серверах.

Описание

По данным OpenSourceMalware, за кампанией стоит аккаунт sapho11, созданный 10 ноября 2026 года. Через полчаса он сделал форк репозитория vizor-wallet, а за следующие шесть часов открыл шесть pull request в проектах chainapsis и Zingo Labs. Тогда же двое сопровождающих Vizor получили поддельное уведомление об уязвимости.

Первые pull request выдавали себя за доработку релизного конвейера: проверку источников данных о сети и диагностику ошибок подписи. В одном из изменений появился код, собиравший переменные окружения с ключами и токенами и отправлявший их на внешний адрес. Автоматическая проверка Codex это заметила. Автор прислал правку: сбор данных исчез, но обращение к серверу злоумышленника осталось в настройках по умолчанию. В слитом виде конвейер обращался бы к этому серверу регулярно, а ответ влиял бы на публикуемые таблицы сети.

Следом пришёл pull request только с правкой документации. Он добавлял в файл AGENTS.md, который читают ИИ-агенты при проверке кода, раздел о «диагностике автоматизации». Раздел предлагал не считать выгрузку переменных окружения утечкой и просил проверяющих, включая автоматических, реагировать только на отклонения от описанного порядка. Бот-аудитор пропустил изменение: исходного кода в нём не было.

Основную работу выполнял пакет lwd-uri-util, восемь версий которого ушли в реестр пакетов Rust. Библиотечная часть в нём безобидна: она приводит строки адресов lightwalletd к единому виду. Вся вредоносная логика жила в сборочном скрипте, который Cargo запускает при каждой компиляции, до первого вызова функций пакета. Из окружения скрипт забирал переменные с ключами и токенами и файлы с учётными данными, читал хранилища Keplr MCP и обращался к системному хранилищу паролей macOS за ключом расшифровки. С версии 0.1.4 он сверял окружение со словами-маркерами, которыми песочницы и сканеры помечают приманки, и при совпадении отказывался от отправки. Собранные данные при этом оставались в открытом файле в каталоге сборки.

В проектах Zingo Labs те же 25 строк полезной правки спрятали внутри переписанных файлов. Смена окончаний строк превратила изменение в полную замену файла, где рабочие строки теряются среди тысяч правок. Ни один из двух pull request не обновлял файл блокировки зависимостей, а требование версии допускало любые будущие выпуски 0.1.x. Оба оставались открытыми и без отзывов.

Четвёртым приёмом стал фишинг. В своём форке злоумышленник открыл issue про обход проверки подписи обновлений и упомянул двух сопровождающих Vizor. По ссылке их ждала копия страницы входа GitHub на узле, поднятом на Cloudflare Workers: логин и пароль уходили на тот же узел. Захваченная сессия позволила бы слить закрытые pull request или добавить зависимость напрямую. Домен из ранних pull request зарегистрировали за два месяца до появления аккаунта. Загрузчика, второго этапа и механизма закрепления в пакете не обнаружено: урон ограничен тем, что успели забрать.

Индикаторы компрометации

Комментарии: 0