С 23 июня 2026 года семейство загрузчиков PolinRider ищет адреса своих командно-контрольных серверов в публичном блокчейне Ethereum. Так называют C2-серверы: через них злоумышленник управляет заражёнными компьютерами. Адрес очередного сервера лежит в получателе крошечной транзакции. Оператор отправляет её со своего кошелька, а загрузчик читает блокчейн через публичные узлы сети. Затем он извлекает адрес и скачивает следующий этап вредоносного кода. Смена сервера не требует правок в программе: хватает одного перевода на доли цента. Стоимость такой инфраструктуры почти незаметна для бюджета атакующего.
Описание
Схему заметили при разборе инцидента в открытом проекте oxc. Сопровождающий опубликовал снимок экрана со сторонним запросом на слияние. Автор запроса добавил в двадцать скриптов сборки и тестов обфусцированный код, то есть намеренно запутанный. Заметным он стал случайно: автоматический форматтер разбил одну длинную строку на сто шесть строк, и они попали в окно сравнения. Запрос отклонили, а учётную запись автора удалила администрация GitHub. Коммиты остались доступны в сети репозитория по идентификатору.
Подделка коснулась и метаданных. В поле автора коммита стояло имя и почта настоящего сопровождающего проекта. Дата авторства оказалась на десять недель старше даты самого коммита. Сообщение описывало реальное изменение в тестах, а полезная нагрузка пряталась в остальных двадцати файлах. Git позволяет тому, кто создаёт коммит, указать любое имя и любую дату. Поэтому строка авторства сама по себе ничего не доказывает. Запрос открыли 14 сентября, а ветку переписали 25 сентября.
По данным SafeDep, к 30 сентября 2026 года вредоносная нагрузка сохранялась в 35 публичных репозиториях. Вместе они собрали 7 578 звёзд и 2 884 форка. Значит, проекты копировали и запускали тысячи разработчиков. Второй кошелёк нашёлся ещё в семидесяти записях базы вредоносных пакетов Open Source Security Foundation (OpenSSF). Шестьдесят восемь относились к менеджеру пакетов npm (инструмент установки библиотек для JavaScript), два - к хранилищу PyPI для Python. Большинство пакетов маскировались под плагины для Tailwind CSS и PostCSS. Проверка шла только по файлам, где расшифрованный код содержал кошельки операторов; исследовательские наборы с тестовыми метками в список не попали.
Первый кошелёк оператора виден целиком: история переводов открыта. С 23 июня по 30 сентября он отправил около трёх тысяч транзакций. В среднем одна приходилась на каждые 51 минуту. Второй кошелёк начал работу 25 июля и пишет примерно раз в 3,3 часа. На двоих они сменили одиннадцать серверов, восемь из них работают у одного хостинг-провайдера. Отслеживать переключения теперь может любой исследователь. Для злоумышленника это плата за устойчивость схемы.
Срабатывает загрузчик в самый обычный момент. Он запускается при сборке проекта, старте сервера разработки или прогоне тестов. Нагрузка прячется в скриптах, которые вызывают чаще всего. Затем устанавливается вредоносное ПО для Node.js (среда выполнения JavaScript) и Python. Оно собирает переменные окружения, а вместе с ними облачные ключи и токены реестров. Дальше в дело идут пароли и файлы cookie браузеров, данные криптовалютных кошельков и расширений. Список из 153 идентификаторов включает MetaMask, Phantom, Coinbase Wallet, 1Password и Bitwarden. Отдельная цель - сохранённые учётные данные git.
Собранные файлы уходят архивом на сервер. Если отправка не удалась, программа обращается к Telegram Bot API. Токен для него оператор передаёт во время сеанса, поэтому в образце его нет. Песочницы и сборочные системы легко узнать по спискам имён: такие хосты программа помечает как заблокированные. На машине без сохранённых паролей, расширений и профиля Firefox она стирает свои файлы и завершает работу. Если сборка идёт в подсистеме Windows Subsystem for Linux 2 (WSL2), загрузчик запускает процесс и в среде Windows. Заражение выходит за пределы гостевой системы.
Распространяется инфекция от разработчика к его проектам. Заражённый компьютер добавляет загрузчик в конфигурации и скрипты. Затем изменения уходят в репозитории с поддельными датами, самая старая относится к 2017 году. Метки в коде, судя по всему, указывают на конкретного разработчика или организацию, а не на версию вредоносной программы. В одном проекте оказались сразу два загрузчика: один читает Ethereum, второй - сеть Tron. Случай с oxc отличается тем, что чужой проект атакующему не принадлежал. Код пришёл туда через запрос на слияние.
Среди пострадавших - панели администрирования, стартовые наборы, шаблоны и учебные примеры. Инфицированные проекты выглядят безобидно, поэтому их копируют для быстрого старта. Четыре шаблона Creative Tim вместе имеют 1 773 форка. Копии быстро разошлись по чужим репозиториям. Часть кода прячется в файле, который выдаёт себя за шрифт в публичной папке. Проверка содержимого показывает, что это сценарий, а не шрифт.
Если проект из списка запускали на рабочей машине, её стоит считать заражённой. Сменить нужно всё, что было доступно из командной строки: облачные ключи, токены реестров, пароли от внутренних сервисов. Отдельно стоит сменить пароли и сессии браузеров. Средства лучше вывести из кошельков, установленных в расширениях. Владельцам репозиториев мало удалить посторонний код. Важно проверить компьютеры, с которых отправлялись коммиты, иначе чистая копия заразится снова.
Для сетевого мониторинга признаком служит процесс сборки, который обращается к публичным узлам Ethereum. Следом он подключается к серверу по прямому адресу. В коде стоит искать необычно длинные строки в конфигурациях и сценариях сборки. Разработчикам полезно проверять сценарии сборки после каждого обновления зависимостей. Блокчейн оказался удобной заменой доменным именам: его нельзя отозвать, а записи не зависят от инфраструктуры злоумышленника. Проверка сторонних правок и свежих зависимостей остаётся основной линией защиты.