Маленькая опечатка названии пакета — и StubMaker забирает пароли, кошельки и сеансы Telegram

loadashjs, typescirpt-cli, axois-http — выглядит знакомо? Именно на это и рассчитан StubMaker.


01nkm83ultgo9nuxhgyb3kad5dxi5sg3.jpg

Разработчиков атаковали через поддельные пакеты сразу в двух популярных репозиториях. Злоумышленники разместили 16 вредоносных библиотек в RubyGems и ещё 37 в npm, подбирая названия с опечатками под известные зависимости. Установка приманки на Windows запускала StubMaker, похититель данных, который собирал пароли и активные сеансы браузеров, сведения о банковских картах, криптовалютные кошельки, сид-фразы и файлы Telegram Desktop. Анализ обеих серий показал общую инфраструктуру, одинаковый загрузчик и один и тот же основной вредоносный модуль.

Первую часть кампании обнаружили 15 августа в RubyGems. Для распространения использовали тайпсквоттинг : злоумышленник регистрирует пакет с именем, очень похожим на название популярной библиотеки, и рассчитывает на ошибку разработчика при вводе команды установки или выборе зависимости. С StubMaker связали 16 имён: ubnuler, ubnlder, ri18nr, reaker, rakier, orakw, joxn, ise18n, ioe18n, ie18u, iai8n, i1l8n, i18om, activesupmport, brumdler и brundlef. Названия имитировали в том числе Bundler, i18n, Rake и Active Support.

Авторы кампании использовали и особенность RubyGems, позволяющую повторно занять освободившееся имя пакета. Как минимум brumdler и brundlef сначала опубликовали из одной учётной записи, затем удалили, после чего названия перешли к другим аккаунтам злоумышленников. Если все версии gem удалены и имя снова доступно для регистрации, другой пользователь вправе его занять. Поэтому удаление вредоносной библиотеки не обязательно навсегда закрывает прежнее название.

Ещё один приём помогал маскировать связь между пакетами. В спецификации RubyGem поле authors содержит обычный текст и не служит подтверждённой идентификационной записью владельца. Автор пакета может указать там имя, которое не совпадает с учётной записью, использованной для публикации. Злоумышленники прописывали разные имена авторов у нескольких библиотек, хотя загружали пакеты через одни и те же аккаунты. Официальная документация RubyGems действительно описывает authors как поле метаданных в спецификации gem, наряду с названием, версией, описанием и адресом электронной почты.

Вредоносный код запускался уже во время установки Ruby-пакета. Для запуска использовали файл extconf.rb, предназначенный для подготовки нативных расширений. Обычно RubyGems выполняет extconf.rb, чтобы проверить наличие необходимых функций и библиотек и сформировать Makefile для последующей сборки расширения. Официальное руководство RubyGems прямо описывает такую схему работы.

StubMaker подменял нормальную сборку фиктивной. extconf.rb создавал Makefile с пустыми целями all, install и clean, а также заглушки для Unix и Windows. Скрипты не компилировали полезный компонент, а просто завершались без ошибки, поэтому RubyGems получал сообщение об успешной сборке. Параллельно установщик определял операционную систему и запускал вредоносную цепочку. Название StubMaker связано именно с созданием таких заглушек, которые скрывали настоящую работу установочного сценария.

На Windows Ruby-код загружал с GitHub файл размером около 22 МБ. Адрес предварительно прятали с помощью Base64. Полученный main.exe содержал загрузчик на Rust, внутри которого находился зашифрованный исполняемый модуль размером примерно 11 МБ, написанный на Go. Отдельно скачивать основной стилер не требовалось: загрузчик расшифровывал встроенный PE-файл, проверял сигнатуру MZ, находил необходимые функции Windows и размещал программу в памяти.

Основной модуль, обозначенный как wincfg, охотился прежде всего за данными браузеров на базе Chromium. В список целей входили Google Chrome, Microsoft Edge, Brave, Opera, Opera GX, Vivaldi, Yandex Browser, Avast Secure Browser, AVG Secure Browser и CCleaner Browser. Вредонос искал сохранённые учётные данные, файлы cookie и токены активных сеансов, историю посещений, сведения расширений и номера платёжных карт.

Для доступа к защищённым данным браузеров StubMaker использовал DLL abe_payload.dll. Библиотека помогала обходить защиту App-Bound Encryption, по-русски её можно назвать шифрованием с привязкой к приложению. Google применяет механизм ABE в Chrome, чтобы усложнить кражу локальных секретов другим процессом Windows. Защищённые ключи связываются с приложением, которому разрешено выполнять расшифровку. StubMaker внедрял собственную DLL в браузерный процесс и пытался получить нужные данные уже из доверенного контекста. Google подтверждает применение App-Bound Encryption как средства защиты от похищения данных браузера вредоносными программами.

Криптовалютные данные собирал отдельный набор функций. Код искал программные кошельки и браузерные расширения MetaMask, Coinbase Wallet, Phantom, Solflare, Exodus, Electrum, Bitcoin, Litecoin, Dogecoin, Monero, Atomic, Guarda и Trezor Suite. Дополнительно стилер просматривал текстовые и JSON-файлы в поисках последовательностей, похожих на фразы восстановления, и сверял найденные слова со словарём BIP-39. Результаты записывались в файлы wallets.txt и seeds.txt. Механизма автоматического перевода криптовалюты исследователи в образцах не нашли. StubMaker похищал данные, которые позволяли получить доступ к кошельку позднее.

Telegram Desktop тоже входил в список целей. Стилер искал каталог tdata, где клиент хранит локальные данные сеансов, и проверял стандартные пути установки программы. Одновременно вредонос собирал имя пользователя Windows, имя компьютера, версию операционной системы, сведения о процессоре и видеокарте, объём оперативной памяти и публичный IP-адрес. Для определения внешнего адреса использовался сервис api.ipify.org.

Собранные файлы StubMaker упаковывал в ZIP-архив с паролем и отправлял на Gofile. После загрузки вредонос получал ссылку на архив и передавал адрес оператору через dresslee.com по незашифрованному HTTP. Вместе со ссылкой уходила сводка о заражённом компьютере и количестве найденных паролей, файлов cookie, записей истории и криптовалютных данных. Исследованные образцы не пытались закрепиться через службы Windows, планировщик заданий, ключи автозапуска или папку Startup. Кампания была рассчитана на кражу информации непосредственно после установки заражённой зависимости.

На следующий день обнаружилась вторая часть StubMaker. 16 августа в npm появились 37 пакетов с названиями, похожими на Axios, Chalk, Commander, Lodash, TypeScript и React. Легитимные проекты не взламывали: злоумышленники публиковали самостоятельные пакеты-двойники . Среди примеров — axois-http, chalk-core, comander-cli, loadashjs, typescirpt-cli и raectjs. Авторы меняли порядок букв, пропускали символы и добавляли окончания -core, -lib или -cli, чтобы имя можно было принять за вспомогательную библиотеку известного проекта.

Все 37 npm-пакетов получили версию 1.0.0 и содержали практически одинаковый вредоносный сценарий postinstall.js. npm автоматически выполняет сценарии postinstall после установки пакета, поэтому разработчику не требовалось импортировать библиотеку или запускать отдельную функцию. Достаточно было установить зависимость.

Начальные этапы для RubyGems и npm различались. Ruby-вариант использовал extconf.rb и хранил адрес загрузчика в строке Base64. npm-вариант запускался через postinstall и скрывал адрес с помощью XOR с повторяющимся жёстко заданным ключом. После расшифровки адреса обе цепочки переходили к одному и тому же загрузчику для Windows.

npm-пакеты учитывали и Windows Subsystem for Linux. Обычные Linux и macOS не могли запустить предназначенный для Windows PE-файл, однако WSL обрабатывался отдельно. Установочный сценарий обращался из Linux-среды к Windows powershell.exe, скачивал main.exe и запускал загрузчик уже на основной системе. Поэтому работа внутри WSL не защищала разработчика от Windows-версии StubMaker.

RubyGems и npm заметно различались по скорости публикации вредоносных пакетов. Ruby-библиотеки появлялись последовательно в течение двух дней: после удаления одной партии оператор менял учётную запись и продолжал публикацию. Основную группу npm загрузили примерно за восемь минут через пять аккаунтов. Распределение пакетов между несколькими временными профилями снижало зависимость кампании от одной учётной записи, хотя npm быстро обнаружил и удалил всю группу.

Общий сервер окончательно связал две серии атак. RubyGems и npm отправляли данные на 193.70.34.101:20099/vote, обращались к одному GitHub Release за main.exe и получали файл с одинаковым хешем SHA-256. Внутри загрузчика находился идентичный Go-стилер. Один оператор, таким образом, одновременно распространял одну вредоносную программу через две экосистемы пакетов.

Самораспространения в StubMaker не обнаружили. Вредонос не заражал легитимные библиотеки, не захватывал учётные записи их разработчиков и не публиковал копии самостоятельно. Для компрометации требовалась установка одного из пакетов-приманок на Windows или в WSL.

К моменту публикации обнаруженные пакеты удалили из RubyGems и npm, а GitHub-аккаунт, с которого скачивался загрузчик, оказался недоступен. Компьютеры, где вредоносная зависимость успела установиться, рекомендуется изолировать, завершить активные браузерные и Telegram-сеансы и сменить пароли с другого доверенного устройства. При хранении сид-фраз на заражённом компьютере безопаснее считать соответствующие криптовалютные кошельки скомпрометированными и перевести средства на новые адреса, созданные в чистой среде.