Обнаружен новый сложный вредонос IronWorm: Rust-инфостилер с eBPF-руткитом нацелился на разработчиков через npm

information security

Исследователи информационной безопасности раскрыли детали ранее неизвестной атаки на цепочку поставок программного обеспечения. Злоумышленники создали вредоносную программу IronWorm, написанную на Rust, которая крадёт любые секреты с компьютера разработчика, прячется с помощью руткита уровня ядра eBPF и связывается с оператором через анонимную сеть Tor. Главная цель - разработчики, особенно те, кто работает с криптовалютами и децентрализованными приложениями (web3).

Описание

Атака началась с безобидного на первый взгляд npm-пакета. Учётная запись asteroiddao, связанная с одноимённой организацией на GitHub, перевыпустила несколько пакетов в узком временном окне. Каждый из них содержал нативный бинарный файл, который запускался ещё до установки зависимостей. Для анализа был взят пакет weavedb-sdk версии 0.45.3. Внутри архива среди четырёх легитимных файлов SDK скрывался бинарник размером 976 КБ в каталоге tools/setup. Манифест package.json содержал команду preinstall, которая выполняла этот файл без какого-либо участия пользователя - достаточно было набрать npm install.

При изучении бинарника выяснилось, что он упакован модифицированным UPX: стандартный распаковщик отказывался его обрабатывать, потому что сигнатура UPX была испорчена. После восстановления магического значения упаковка снялась обычным способом. Внутри оказался крупный Rust-бинарник с асинхронной средой выполнения - такие файлы крайне трудно обрабатывать вручную. Почти все строки были зашифрованы, и для каждого места вызова использовался свой уникальный ключ. Расшифровка потребовала значительных усилий, но позволила восстановить адреса GitHub API, длинные списки переменных окружения, пути к файлам учётных данных и шаблоны для внедрения вредоносного кода в разные экосистемы пакетов.

Поиск по GitHub показал 14 подозрительных коммитов, подписанных именем "claude" и адресом электронной почты claude@users.noreply.github.com. Коммиты датировались периодом до 13 лет назад, хотя на самом деле были сделаны всего за несколько дней до обнаружения. Git позволяет подделывать дату, и злоумышленник копировал временную метку последнего легитимного коммита репозитория. Настоящим автором оказался пользователь ocrybit, член организации asteroid-dao и связанных с ней групп. В общей сложности вредоносные коммиты были обнаружены в девяти GitHub-организациях (включая ocrybit, asteroid-dao, weavedb и другие). Вскоре после того, как исследователи зафиксировали активность, большая часть вредоносных коммитов и npm-пакетов была удалена. Однако, судя по активности аккаунта ocrybit (около 4500 коммитов в частные проекты за месяц), масштаб кампании мог быть значительно шире.

Механизм распространения IronWorm использует два варианта заражения в зависимости от структуры репозитория. Если проект содержит манифест пакета (npm, PyPI, Cargo и т. д.), вредонос создаёт бинарный файл по типу tools/setup и добавляет hook для его автоматического запуска. Автором коммита указывается "claude" - имитация работы AI-ассистента. Если же в репозитории уже настроены GitHub Actions, вредонос заменяет один из существующих workflow на шпионский: он сериализует все секреты репозитория с помощью выражения ${{ toJSON(secrets) }}, записывает их в файл и загружает как артефакт сборки. Коммит при этом подписывается как dependabot, renovate или github-actions, чтобы не вызывать подозрений. По данным исследователей, второй сценарий не был зафиксирован в реальной атаке, но кодовая логика в бинарнике полностью реализована.

Особую опасность представляет способ саморепликации. В среде CI вредонос использует механизм Trusted Publishing от npm. Он запрашивает OIDC-токен у GitHub Actions, обменивает его на короткоживущий токен автоматизации и публикует троянизированную версию пакета на npm-реестр.

Инфостилер собирает огромный объём данных: 86 переменных окружения - ключи от облачных провайдеров, баз данных, CI/CD-систем, мессенджеров, Vault и Kubernetes. Отдельно выделены 14 ключей API для AI/ML-платформ (Anthropic, OpenAI, Gemini, Perplexity и другие). Также сканируется более 20 путей к файлам учётных данных, включая недавно появившиеся инструменты. Встроенный модуль для криптовалютного кошелька Exodus внедряет JavaScript-код, ослабляет защиту Electron и перехватывает пароль и seed-фразу при разблокировке. В Kubernetes-среде вредонос читает сервис-аккаунт токен, обходит пространства имён и выгружает все секреты, включая интеграции с Vault.

Исследователи из JFrog обнаружили в коде забавную деталь: среди строк, которые вредонос сканирует, но не крадёт, оказалась полная seed-фраза BIP-39 длиной 12 слов. Единственная причина - оператор не хотел, чтобы его собственное творение обчистило его тестовый кошелёк. Фраза позволила вычислить адрес Ethereum кошелька 0x7e28D9889f414B06c19a22A9Bd316f0AC279a4d6, на котором на момент анализа находились лишь следовые суммы. Это косвенная, но надёжная зацепка для атрибуции.

Одним из ключевых компонентов IronWorm является руткит на основе eBPF. Он скрывает свои процессы из /proc, автоматически прячет новые процессы по списку имён, блокирует отладку (ptrace) с помощью SIGKILL, а также скрывает TCP-соединения. Для этого BPF-код модифицирует память вызывающего процесса. Однако на системах с включённым режимом блокировки ядра (lockdown) эти манипуляции не работают, и скрытые объекты становятся видимыми. При этом сам BPF-объект был скомпилирован с отладочной информацией .BTF.ext, которая не была удалена. Благодаря этому исследователи восстановили 214 строк исходного кода руткита, все его карты и структуры.

Сеть Tor используется и для управления. Malware загружает Tor expert bundle, запускает демон и отправляет запросы к агенту C2 на эндпоинт /api/agent. Команды включают загрузку украденных данных, получение файлов с сервера и выполнение shell-команд. Также предусмотрен запасной канал: загрузка данных на публичный хостинг temp.sh через Tor и передача ссылки на C2.

IronWorm не похож ни на одну известную вредоносную программу. Он собран вручную, с использованием современного стека Rust, шифрованием строк, модифицированным упаковщиком и eBPF-руткитом. При этом заметны следы незавершённой разработки: осталась отладочная информация, жёстко закодированная seed-фраза. Возможно, это репетиция будущей более мощной атаки.

Защитникам рекомендуется провести аудит всех репозиториев, к которым имел доступ скомпрометированный аккаунт. Следует искать подозрительные коммиты с поддельными датами, неожиданные сборки и изменения, подписанные автоматизированными учётными записями. Необходимо удалить или деприкейтить вредоносные версии пакетов, опубликовать чистую версию с уведомлением о безопасности и ротировать все ключи и секреты, доступные скомпрометированному аккаунту.

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

Commit author emails

  • claude@users.noreply.github.com

NPM packages

  • ai3@0.3.5
  • aonote@0.11.1
  • arjson@0.1.4
  • arnext@0.1.5
  • arnext-arkb@0.0.2
  • atomic-notes@0.5.3
  • create-arnext-app@0.0.10
  • cwao@0.5.6
  • cwao-tools@0.3.1
  • cwao-units@0.8.3
  • fpjson-lang@0.1.7
  • hbsig@0.3.2
  • monade@0.0.7
  • roidjs@0.1.7
  • test-ajs@0.1.19
  • testnpmnmp@1.0.21
  • test-weavedb-sdk@1.1.1
  • wao@0.41.2
  • warp-contracts-plugin-deploy-test@3.0.1
  • wdb-cli@0.1.1
  • wdb-core@0.1.2
  • wdb-sdk@0.1.2
  • weavedb-base@0.45.3
  • weavedb-client@0.45.3
  • weavedb-console@0.2.1
  • weavedb-contracts@0.45.2
  • weavedb-exm-sdk@0.7.4
  • weavedb-exm-sdk-web@0.7.4
  • weavedb-lite@0.1.1
  • weavedb-node-client@0.45.3
  • weavedb-offchain@0.45.4
  • weavedb-sdk@0.45.3
  • weavedb-sdk-base@0.21.1
  • weavedb-sdk-node@0.45.3
  • weavedb-tools@0.45.3
  • weavedb-warp-contracts-plugin-deploy@1.0.11
  • zkjson@0.8.5

Commit messages

  • fix: resolve lint warnings
  • test: add missing edge case
  • ci: update workflow configuration
  • fix: address review feedback
  • docs: update contributing guide
  • chore: sync lockfile
  • fix: handle null pointer case
  • build: bump patch version
  • chore: update dependencies

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