TL, д-р
В период с 15.06.2026 по 16.06.2026 один издатель npm опубликовал... шесть пакетов — всего 26 версий. — которые запускают скрипт установки на каждом npm installКаждый пакет поставляется с файлом README, в котором объявляется, что это «безобидный» исследовательский артефакт HackerOne/GitHub Bug Bounty, который «никогда» не затрагивает значения учетных данных и «не обеспечивает сохранение данных». Код не соответствует условиям отказа от ответственности. В системах CI под Linux установочный хук определяет среду и проверяет конечную точку метаданных облачного экземпляра; в Windows он запрашивает повышение привилегий и запускается как SYSTEMи открывает канал связи с внешним хостом. Единственный индикатор, на который следует обратить внимание сейчас, — это хост управления (C2). 173.255.233[.]239Степень тяжести: высокаяЗатронутая экосистема: НПМНазвания сливаются с шумом зависимостей непрерывной интеграции (metrics-pipeline-d8k2, event-metrics-q3x7, pkg-telemetry-r4f9и трое братьев и сестер).
Атака: как она работает
Все пакеты в кластере собираются одинаково. пакет.json объединяет одну и ту же команду в два жизненных цикла. hooks:
{ "scripts": { "preinstall": "node run.js", "postinstall": "node run.js" } } Работает на обоих предустановка и послеустановка Это означает, что полезная нагрузка срабатывает независимо от того, завершаются ли последующие этапы установки с ошибкой. run.js Сам по себе это десятистрочный диспетчер платформы:
// Platform dispatcher — runs beaconNN.js on Windows, beacon_linux.js on Linux. // GitHub Bug Bounty authorized research. Contact: nicholas@curran.tech 'use strict'; const { execFileSync } = require('child_process'); const path = require('path'); const node = process.execPath; const script = process.platform === 'win32' ? path.join(__dirname, 'beacon34.js') : path.join(__dirname, 'beacon_linux.js'); try { execFileSync(node, [script], { stdio: 'inherit', timeout: 90000 }); } catch (e) {} Затем поведение зависит от операционной системы. Все шесть пакетов содержат одни и те же две части — run.js А платформы — это своего рода маяки, поэтому они представляют собой взаимозаменяемые инструменты для загрузки, а не шесть отдельных компонентов. Единственное существенное различие между ними — это периодичность публикации: четыре версии были выпущены один раз, а две переиздавались каждые 30–60 минут в течение нескольких часов, что позволяет поддерживать актуальность опубликованной версии перед установщиками и резолверами, даже когда старые версии удаляются.
В линуксе (beacon_linux.jsСкрипт профилирует место своего выполнения. Он перечисляет имена переменных окружения и читает файлы в папке. / Proc, проверяет docker.sock, и работает хоста и WhoamiЗатем он отправляет HTTP-запрос к конечной точке метаданных экземпляра контейнера AWS. 169.254.170[.]2 — Локальный адрес, по которому задача ECS запрашивает свою конфигурацию и учетные данные для кратковременной роли (IMDS, служба метаданных экземпляра). Результаты отправляются методом POST сборщику кампании по адресу 173.255.233[.]239.
В Windows (beacon34.js / beacon18.jsПакет делает гораздо больше, чем просто профилирует хост. Отмеченный код добавляет ключ реестра в раздел ms-настройки обработчик с DelegateExecute Значение — известный способ обхода контроля учетных записей пользователей, позволяющий запущенному процессу работать с повышенными правами без запроса подтверждения. Он вызывает PowerShell с помощью -ExecutionPolicy Bypass и Вызов-выражение, выполняется в NT AUTHORITY \ SYSTEM контекст и опрашивает внешний хост на наличие команд. Канал команд Windows работает поверх туннель Cloudflare, diameter-coins-limitations-parents.trycloudflare[.]com:443, возвращаясь к 173.255.233[.]239:443с использованием трех конечных точек: /c2/poll получить команду, /c2/out вернуть результат /c2/eof закрывать.
Что здесь нового: дисклеймер как камуфляж.
Новизна заключается не в полезной нагрузке — разведка с помощью хуков установки и повышение привилегий в Windows хорошо задокументированы. Новизна в прикрытии. Каждый пакет содержит файл README, который выглядит как документ, подтверждающий соблюдение принципов ответственного раскрытия информации:
# @ncurran/sandbox-recon-880538 — authorized npm-sandbox security research Это доброкачественный пакет, опубликованный в рамках собственной области видимости автора `@ncurran` как часть Уполномоченное участие в программе HackerOne / GitHub Bug Bounty (npm входит в сферу действия).
При установке выполняется проверка. собственная среда выполнения … переменная окружающей среды
только ключевые имена … проверяет, является ли он широко известным конечные точки метаданных облака доступен… Он сообщает только коды состояния, длительность ответов и хеши — “никогда не научится делать” Любые учетные данные, значения токенов или данные третьих лиц. Он не выполняет никаких действий. Настойчивость, отсутствие боковых перемещений и деструктивных действий.
Три утверждения в этом тексте противоречат поставляемому коду. В файле README говорится «отсутствие постоянного хранения данных», но маяк Windows записывает ключ повышения привилегий на основе реестра. Там говорится «никогда не используются учетные данные или значения токенов», но путь Windows выполняет произвольные полученные команды. СИСТЕМА, который не устанавливает никаких ограничений на то, что читается или возвращается. Он даже называет пакет — @ncurran/sandbox-recon-880538 — это не тот файл, в котором он поставляется, что указывает на то, что README — это повторно используемый шаблон, а не описание самого артефакта. Заявление о согласии в пакете, который жертва никогда не давала согласия на установку, не означает никакого согласия. Классификация здесь является злонамеренной, независимо от формулировки. У этого заявления о согласии также есть более скрытая цель: автоматизированный этап проверки, который считывает текст пакета на предмет обнадеживающих сигналов — «безопасный», «разрешенный», именованная программа, контактный адрес электронной почты — может быть скорректирован в сторону безопасного вердикта с помощью текста, который противоречит полезной нагрузке. Урок применим как к людям, так и к машинам-рецензентам: оценивайте поведение во время установки, а не самоописание в README.
Лента
Все пакеты появились в течение 24 часов. Первыми появились четыре пакета с одной версией, за ними последовали два пакета, которые переиздавались каждые 30–60 минут.
| Дата (UTC) | События |
|---|---|
| 2026-06-15 18:32 | Первый пакет опубликован — npm:pkg-telemetry-r4f9@1.0.0 |
| 2026-06-15 19:50 | npm:runtime-metrics-w7k2@1.0.0 опубликовала |
| 2026-06-15 20:14 | npm:build-tracker-n5p1@1.0.0 опубликовала |
| 2026-06-15 20:35 | npm:npm-sandbox-ping-r9t2@1.0.0 опубликовала |
| 2026-06-15 21:09–22:42 | npm:event-metrics-q3x7 опубликовала 1.0.0 → 1.0.8 (9 версии) |
| 2026-06-15 23:40 → 2026-06-16 04:40 | npm:metrics-pipeline-d8k2 опубликовала 1.0.0 → 1.0.10 (11 версии) |
| 2026-06-16 | Выявлен и классифицирован как вредоносный кластер; несколько архивов tar уже возвращают ошибку 404 в реестре (процесс продолжается). |
Кампания началась недавно, и процесс удаления еще не завершен: на момент анализа некоторые версии были распознаны реестром, а другие — нет. Все 26 версий следует считать скомпрометированными.
Показатели компромисса
Packages
| Экосистема | Упаковка | Версии | Статус |
|---|---|---|---|
| НПМ | metrics-pipeline-d8k2 | 1.0.0 – 1.0.10 | злонамеренный |
| НПМ | event-metrics-q3x7 | 1.0.0 – 1.0.8 | злонамеренный |
| НПМ | runtime-metrics-w7k2 | 1.0.0 | злонамеренный |
| НПМ | build-tracker-n5p1 | 1.0.0 | злонамеренный |
| НПМ | npm-sandbox-ping-r9t2 | 1.0.0 | злонамеренный |
| НПМ | pkg-telemetry-r4f9 | 1.0.0 | злонамеренный |
Cеть
| Тип | Индикаторные | Заметки |
|---|---|---|
| IP | 173.255.233[.]239 | Сборщик C2; POST-запрос для разведки в Linux и резервный вариант в Windows: 443 |
| Домен | diameter-coins-limitations-parents.trycloudflare[.]com | Канал команд Windows через туннель Cloudflare, :443 |
| URI-путь | /c2/poll, /c2/out, /c2/eof | Команда Windows: опрос / вывод / закрытие |
| IP | 169.254.170[.]2 | Конечная точка метаданных экземпляра AWS ECS проверяется из хука установки. |
Поведенческий
| сигнал | Описание |
|---|---|
| Установите hooks | preinstall и postinstall оба бегут node run.js |
| Отправка платформы | run.js работает beacon_linux.js в Linux, beacon34.js / beacon18.js в Windows |
| Разведка Linux | Перечисляет имена ключей переменных окружения, считывает данные. /proc, чеки docker.sockработает hostname / whoamiзонды IMDS |
| Фасад окон | ms-settings DelegateExecute Обход UAC через реестр; PowerShell -ExecutionPolicy Bypass + Invoke-Expression; работает как SYSTEM |
| Маскировать | В файле README утверждается, что исследование является «безопасным», «авторизованным» и «не содержит элементов, сохраняющих данные»; в нем упоминается название пакета, в котором он не поставляется. |
Атрибуция и наблюдаемое поведение
Мы описываем издателя исключительно на основе его данных и не утверждаем личность какого-либо лица, стоящего за этим аккаунтом.
- Каталог сигналов. Все шесть пакетов были опубликованы с одного и того же аккаунта npm. npmresearch8847с указанным адресом электронной почты. npmresearch8847@web-library.net (электронная почта и SCM Подтверждение отсутствует; мы не проверяли право собственности). Файлы README публикуются под определенным брендом. @ncurran определить объем работ и предоставить контактные данные nicholas@curran.tech и run.js точки в репозитории `github.com/ncurran/npm-sandbox-research`. Все шесть пакетов имеют идентичный интерфейс. run.js диспетчер, обычный beacon_linux.js этап разведки и единственный коллекторный хост 173.255.233[.]239`. Схема именования согласована: общий корень, звучащий как CI (метрика, телеметрия, build-tracker, песочница-пинг) плюс короткий случайный суффикс.
- Уверенность. Судя по общему диспетчерскому пункту, этапу разведки и центру управления и контроля, шесть пакетов, по-видимому, представляют собой одну кампанию. Формулировка «авторизованное исследование» последовательно встречается во всех шести файлах README. Нам не удалось подтвердить, что какая-либо программа вознаграждения за обнаружение ошибок санкционировала эту деятельность, и утверждения в дисклеймере не соответствуют выпущенному коду.
- Наблюдаемые возможности. Упражнение с полезной нагрузкойcisчетыре класса возможностей: выполнение кода через install-hook на обоих устройствах. предустановка и послеустановка; разведка хоста и среды CI с исходящим трафиком на внешний сборщик данных; проверка доступности метаданных облачного экземпляра из контекста установки; и, в Windows, локальное повышение привилегий, выполнение как СИСТЕМАа также цикл выполнения команд по внешнему каналу. Цикл команд Windows — это возможность удаленного управления: он опрашивает инструкции и возвращает их результат.
Влияние, тенденции и что должны делать защитники.
Влияние
Наибольший риск возникает в автоматизированных средах сборки. Команда `npm install` в CI запускает весь жизненный цикл сборки. hooks Независимо от того, какой идентификатор имеет исполнитель; в облачном исполнителе этот идентификатор часто включает в себя доступную конечную точку метаданных и учетные данные роли. Адрес, по которому зондируют маяки Linux, 169.254.170[.]2Это конечная точка метаданных задач AWS ECS: задача, которая может до неё добраться, обычно также может получить временные учетные данные своей роли задачи из той же локальной службы. Проверка доступности внутри скрипта установки — это шаг, предшествующий получению этих учетных данных, поэтому любой исполнитель, запустивший обработчик и имевший доступ к этой конечной точке, должен рассматриваться как имеющий доступ к своей роли задачи. На хосте разработчика или сборки Windows полезная нагрузка запрашивает повышение привилегий и открывает канал команд, что расширяет доступ от одного профиля и исходящего трафика до интерактивного удаленного управления.
Нам не удалось получить достоверные данные о количестве загрузок вредоносных версий до их удаления, поэтому мы не можем оценить число жертв. Быстрая повторная публикация двух пакетов — одиннадцати и девяти версий за несколько часов — позволила обеспечить наличие актуальных файлов установщикам и разработчикам, пока удалялись старые версии.
Новые модели
Этот пример показывает, как метка используется в качестве прикрытия. «Авторизованные исследования», «программа вознаграждения за обнаружение ошибок» и «тестирование в песочнице» всё чаще применяются к пакетам, чьи скрипты установки делают больше, чем просто профилирование хоста. Такая формулировка играет на нерешительности рецензента, не решающегося действовать против чего-либо, что позиционируется как санкционированное. Это сочетается со второй распространённой тактикой: названия пакетов, заимствованные под внутренние инструменты CI, чтобы их можно было легко проигнорировать при беглом взгляде на дерево зависимостей. Именно это сочетание делает данную тенденцию заслуживающей внимания — название, которое воспринимается как «инфраструктурная сантехника», обёрнуто в текст, который воспринимается как санкционированное тестирование, и прикрывает собой хук установки, который эскалирует проблему в одной операционной системе и проверяет облачные учётные данные в другой. Ни оговорка, ни безликое название не меняют того, что делает код при установке, и процесс сортировки, который рассматривает любой из этих факторов как смягчающие обстоятельства, приведёт к неверному вердикту.
Что должны делать защитники
- Просмотрите файлы блокировки и журналы установки на наличие шести названий пакетов; любое совпадение рассматривайте как инцидент, а не как предупреждение.
- Блокировка и оповещение об исходящем трафике 173.255.233[.]239 и *.trycloudflare[.]com хосты из инфраструктуры сборки.
- Поиск HTTP-запросов, отправляемых во время установки по адресам метаданных экземпляра (169.254.170.2, 169.254.169.254) возникли благодаря менеджерам пакетов в CI.
- Произведите ротацию всех учетных данных и токенов облачных ролей, доступных с помощью средства запуска, установившего затронутую версию.
- Аудит предустановка/послеустановка скрипты в вашем набор зависимостейСтоит ознакомиться с хуком жизненного цикла, который запускает второй скриптовый файл.
- На устройствах под управлением Windows выполните поиск новых устройств. DelegateExecute значения, записанные под ms-настройки key обработчика оболочки — примитив повышения привилегий, используемый этой полезной нагрузкой, и надежный сигнал, не зависящий от имени пакета.
- Закрепите и просмотрите файлы блокировки, а также отключите скрипты установки.npm install –ignore-scripts) в CI, где ваша сборка их не требует.
- Сообщения типа «разрешенное исследование» или «безвредные» в скрипте установки следует рассматривать как ненадежный текст, а не как причину для разрешения использования скрипта.
Пакет, который в прозе заявляет о благих намерениях и содержит просьбы. СИСТЕМА Оценка кода должна основываться на самом коде.




