В npm-пакете node-ipc обнаружена новая вредоносная нагрузка: кража ключей разработчиков через DNS-канал

security

Экосистема JavaScript вновь столкнулась с угрозой цепочки поставок, способной скомпрометировать инфраструктуру разработчиков по всему миру. Исследователи компании Socket выявили три новые вредоносные версии популярного npm-пакета node-ipc (версии 9.1.6, 9.2.3 и 12.0.1), которые ворут учётные данные, ключи доступа к облачным сервисам, SSH-ключи и конфиденциальные файлы, после чего передают их злоумышленникам через DNS-запросы. Этот инцидент повторяет схему атаки 2022 года, когда тот же самый пакет использовался для деструктивного воздействия на системы в России и Беларуси. Теперь же речь идёт о скрытом хищении информации, нацеленном на любые машины, загружающие библиотеку через CommonJS.

Описание

Пакет node-ipc - это инструмент для межпроцессного взаимодействия в приложениях на Node.js. Он насчитывает двенадцать мейнтейнеров, но один из них, atiertant, долгое время был неактивен. Именно эта учётная запись, как выяснили аналитики, была использована для публикации опасных версий. Независимый исследователь Ян Аль (CTO компании Permiso) первым указал на вероятный вектор компрометации: злоумышленник восстановил доступ к учётной записи через истёкший домен электронной почты. Почтовый домен atlantis-software.net, на котором когда-то была зарегистрирована учётная запись atiertant, перестал продлеваться, и новый владелец домена смог инициировать стандартный сброс пароля npm, получить письмо на подконтрольный ему адрес и таким образом получить права на публикацию. Никакого взлома инфраструктуры самого разработчика не потребовалось - атака основывалась на простой невнимательности: неактивный мейнтейнер не обновил контактный email.

Вредоносный код содержится в файле node-ipc.cjs, который загружается при использовании CommonJS (команда require("node-ipc")). Для тех, кто использует ESM-импорт (import), опасная нагрузка не активируется, если только какой-либо другой модуль не загрузит cjs-файл. Злоумышленник внедрил обфусцированную функцию, которая выполняется сразу после загрузки модуля. Она запускает дочерний процесс в фоновом режиме, используя переменную окружения __ntw, и в этом процессе начинается сбор информации. Анализаторы Socket обнаружили эту активность уже через три минуты после публикации пакетов, классифицировав её как вредоносную.

С технической точки зрения нагрузка выполняет несколько этапов. Сначала она собирает отпечаток хоста: использует функции Node.js для получения платформы, версии ядра, архитектуры, имени хоста. После этого запускает команду uname -a и, если та отрабатывает успешно, сохраняет её вывод. Затем читает файл /etc/hosts и, самое главное, извлекает все переменные окружения процесса - KEY=value. В окружении разработчиков и CI-систем нередко хранятся токены доступа к облачным провайдерам (AWS, Azure, GCP), ключи SSH, токены npm, GitHub, GitLab, пароли к базам данных. Кроме того, нагрузка сканирует домашнюю директорию и текущую рабочую папку на наличие конфигурационных файлов: .env, .aws/credentials, .kube/config, .docker/config.json, файлов Terraform, macOS Keychain и многих других. Список включает 127 целей для Linux и 113 для macOS. При этом она обходит каталоги node_modules и .git, чтобы не тратить время на лишние файлы, и пропускает файлы крупнее 4 мегабайт.

Собранные данные архивируются в формате tar.gz и временно сохраняются в системной временной папке под именем вида nt-<pid>/<machineHex>.tar.gz. После попытки эксфильтрации архив удаляется, но если процесс был прерван аномально, он может остаться на диске.

Самое примечательное - способ передачи данных. Нагрузка не использует HTTP или HTTPS, что позволило бы легко обнаружить подозрительные соединения. Вместо этого она применяет DNS-запросы типа TXT. Сначала она разрешает домен sh[.]azurestaticprovider[.]net - это имитация легитимного домена Microsoft Azure Static Web Apps (azurestaticapps.net). Для разрешения используются публичные DNS-серверы 1.1.1.1 и 8.8.8.8. Затем полученный IP-адрес (на момент обнаружения 37.16.75.69) становится сервером для отправки DNS-запросов с эксфильтрацией в зону bt[.]node[.]js. Данные разбиваются на фрагменты и передаются в виде меток DNS-запросов с префиксами xh (заголовок), xd (данные), xf (окончание). Каждый запрос содержит до 63 шестнадцатеричных символов для заголовка и 31 закодированный символ для данных. Для архива объёмом 500 килобайт может потребоваться около 29 400 таких DNS-запросов, что представляет собой аномально высокий объём DNS-трафика и является хорошим индикатором для систем обнаружения.

Полезная нагрузка перед эксфильтрацией шифруется. После gzip-сжатия данные превращаются в base64, затем XOR-ятся с ключом, полученным из SHA-256, снова кодируются в base64 со специальной перестановкой символов, разбиваются на куски и преобразуются в шестнадцатеричный формат для DNS-меток. Аутентификация запросов выполняется с помощью HMAC-SHA256.

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

Для организаций, использующих node-ipc, немедленные меры включают проверку файлов package-lock, yarn.lock и кэша npm на наличие указанных вредоносных версий. Любые переменные окружения, которые были доступны на поражённых хостах, следует считать скомпрометированными. Рекомендуется ротация ключей SSH, токенов npm, ключей облачных провайдеров, Kubernetes-учётных записей и всего, что хранится в .env. Администраторам безопасности стоит настроить мониторинг DNS-запросов к домену bt[.]node[.]js с префиксами xh, xd, xf, а также обращать внимание на необычно высокий объём TXT-запросов. Также полезно искать временные файлы с маской nt-*.tar.gz.

Этот инцидент вновь демонстрирует, насколько уязвимой остаётся экосистема npm. Компрометация через истёкший домен электронной почты мейнтейнера - простой и эффективный приём. Разработчикам стоит регулярно проверять активность своих учётных записей на npm, использовать двухфакторную аутентификацию и избегать хранения долгоживущих секретов в переменных окружения. Для команд безопасности критически важно анализировать не только скрипты установки, но и точки входа пакетов - как в данном случае вредоносный код был скрыт в CommonJS-файле, не используя стандартный postinstall-скрипт. Своевременное обнаружение стало возможным благодаря автоматическому анализу поведения, а не только статическим сигнатурам.

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

Malicious Packages

  • node-ipc@9.1.6
  • node-ipc@9.2.3
  • node-ipc@12.0.1

SHA256

  • 449e4265979b5fdb2d3446c021af437e815debd66de7da2fe54f1ad93cbcc75e
  • 78a82d93b4f580835f5823b85a3d9ee1f03a15ee6f0e01b4eac86252a7002981
  • 96097e0612d9575cb133021017fb1a5c68a03b60f9f3d24ebdc0e628d9034144
  • c2f4dc64aec4631540a568e88932b61daebbfb7e8281b812fa01b7215f9be9ea

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