Атака з помилками в DevTap npm

Атака з використанням типосквотингу в DevTap npm: шість шкідливих пакетів, спрямованих на робочі станції розробників

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 проти VBS-заглушки. Потім він породжує окремий агент Node.js, який об'єднує модулі для захоплення мікрофона, крадіжки історії браузера, створення скріншотів та симуляції миші/клавіатури.

Ми називаємо цей кластер DevTap, після того, як комплект залишиться запущеним на машині розробника.

На момент написання статті всі шість пакетів були доступні на npm. Ми надіслали їх до каналу зловживань реєстру. Захисникам слід видалити будь-які інсталяції від видавця, які очікують видалення.

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

Обліковий запис видавця user0001 не перевірено. Воно не має SCM верифікація, відсутність електронної пошти, прив’язаної до домену, та відсутність попередньої історії. Ідентифікатор Gmail tanvisoul9 не відображається в жодному іншому записі видавця npm, якого нам вдалося знайти.

Усі шість пакетів вказані одним і тим самим розробником, були опубліковані з одного й того ж облікового запису та мають однакові package.json шаблонний. Немає repositoryВ homepage, і немає description довше, ніж один рядок.

Найцікавіша частина — це стратегія найменування. На відміну від класичної кампанії з плутанини залежностей чи помилок у написанні текстів, жодне з цих назв не спрямоване на конкретну бібліотеку основного коду. Натомість вони налаштовані так, щоб зникнути в реальному світі. package.json or npm ls вихід.

пакетВперше опублікованоОстання версіяверсіїРоль у кластері
централоггер2026-04-01 12:46 UTC1.0.95, від 1.0.5 до 1.0.9Обкладинка кластера «утиліта реєстрації»; найперша публікація
dom-utils-lite2026-04-14 07:36 UTC1.0.33Загальне покриття DOM-допоміжного елемента
вузол-вибірка-lite2026-04-19 10:22 UTC1.0.23Імітує сімейство вибірки вузлів
агент-з'єднувач2026-04-25 05:12 UTC1.0.01«Агент» із загальною назвою
node-gyp-runtime2026-04-25 05:17 UTC1.0.01Імітує інструменти збірки нативних модулів
вирішення вузла-середовища-вирішення2026-04-25 05:21 UTC1.0.910, від 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, підписаний бінарний файл 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 можна налаштувати для кожного розгортання окремо, а не вбудувати в пакет. Цей невеликий, але навмисний вибір перешкоджає більшості статичних IOC-сканувань.

Також, породжений дочірній об'єкт успадковує повне батьківське середовище. Тому будь-який 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
admin-zipПакування зібраних артефактів перед вивезенням
гострийЗміна розміру/стиснення скріншотів та артефактів зображення
socket.io-клієнтПостійний двонаправлений канал C2
ідентифікатор-машини-вузлаСтабільний відбиток пальця для кожного хоста для відстеження жертви

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 є загальним. Небезпечно робити висновок про географію лише з локальної частини електронної пошти.

Стиль коду 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. Ми не знайшли жодного: спільних шаблонів C2, спільних макетів файлів та спільних ідіом.

Чого ми б не сказали: що це державний суб'єкт, відома група або географічно пов'язана з якоюсь конкретною країною.

Операційний профіль відповідає невеликій команді середньої кваліфікації, яка займається спостереженням за робочими місцями розробників. Це, ймовірно, фінансово мотивовано через подальше використання доступу, але, можливо, також розвідка як послуга для окремого покупця.

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

Індикатори компрометації та виявлення

Пакети та видавець
Полезначення
видавець npmuser0001
Електронна адреса видавцяtanvisoul9@gmail.com, неперевірено
Пакетиcentralogger, dom-utils-lite, node-fetch-lite, агент-з'єднувача, середовище виконання node-gyp, node-env-resolve
Підтверджено шкідливевузол-env-resolve@1.0.7, вузол-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 під час встановлення
Мережа
типзначення
Транспорт С2socket.io-client, постійний двонаправлений канал
Кінцева точка C2Надається агенту через змінну середовища SERVER_URL; не вбудовано в опубліковані артефакти

Примітки щодо виявлення

Два правила перехоплюють цю родину без потреби в кінцевій точці C2.

Спочатку позначте постінсталяційні скрипти, які виконують внутрішню npm install у шлях за межами власного каталогу пакета. Будь-який легітимний завантажувач попередньої збірки, такий як node-gyp перебудовує або завантажує попередньо зібрані бінарні файли, записує всередину пакета або в платформу-standard шляхи кешу з перевіреними хешами. Він не записує у щойно створений INSTALL_DIR в іншому місці на диску.

По-друге, позначте постінсталяційні скрипти, які викликають проблеми reg add HKCU\…\Run з wscript.exe як засіб запуску. Це по суті ніколи не є легітимним з npm-пакета. Позначте та помістіть це в карантин.

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

Повідомлено до реєстру npm. Ми оновимо цю публікацію, коли обліковий запис видавця буде видалено.

інструменти-для-аналізу-складу-програмного-засобу-sca
Визначте пріоритети, усуньте та захистіть ризики, пов'язані з програмним забезпеченням
Отримайте свій безкоштовний обліковий запис.
Не потрібна кредитна картка.

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

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