شرح کلی
نوع: تروجان (Trojan)
درجه تخریب: متوسط
میزان شیوع: متوسط
اسامی بدافزار
- (Padvish) Trojan.Android.RubikaPhisher.Malek
- (Avira) ANDROID/Dropper.FGHB.Gen
- (ESET) A Variant Of Android/TrojanDropper.Agent.FNN
تروجان چیست؟
تروجانها نوعی از بدافزارها محسوب میشوند که خود را در قالب نرمافزاری سالم و قانونی نشان میدهند و بسیار شبیه نرمافزارهای مفید و کاربردی رفتار میکنند. اما هنگامی که اجرا میشوند، خرابیهای زیادی را برای سیستم ایجاد میکنند. از جمله راههای ورود تروجانها به سیستم: نرمافزارهای دانلود شده از اینترنت، جاساز شدن در متن HTML، ضمیمه شدن به یک ایمیل و … هستند. تروجانها برخلاف ویروسها و کرمهای کامپیوتری قادر به تکثیر خود نیستند.
خانواده بدافزاری RubikaPhisher چیست؟
این بدافزار با عناوینی مانند “روبیکای مود شده” یا “فیلم ۱۸+” توزیع میشود و پس از اجرا از کاربر میخواهد برای ورود به برنامه، شماره تلفن خود را جهت دریافت کد فعالسازی وارد کند. با وارد کردن شماره تلفن، پیامکی از پنل پیامکی برنامه اصلی روبیکا برای کاربر ارسال میشود. در صورت وارد کردن کد ارسالی در بدافزار، حساب کاربری روبیکای کاربر، تصاحب شده و بدافزار میتواند اقدام به ارسال پیام، عضویت در کانالها و گروههای هدف خود کند.
توضیحات فنی
علائم آلودگی
❌ دریافت مجوز برقراری تماس تلفنی
❌ وجود نشستهای ناشناس در حساب کاربری برنامه روبیکا
شرح عملکرد
بدافزار کاملا مبهم و بستهبندیشده است و آنپک کردن آن نیازمند استفاده از ابزارهای داینامیک است. ابتدا با deobfuscate کردن رشتههای بدافزار، به بررسی عملکرد بدافزار در کلاس cn.beingyi.sub.apps.SubApp.SubApplication (کلاسی که در فایل مانیفست در تگ Application فراخوانی شده است) پرداخته میشود.
برخی از بدافزارهای تحت اندروید از تکنیکهای بستهبندی یا Packing برای پنهانسازی کد مخرب خود استفاده میکنند. بدین معنا که کد اصلی بدافزار به صورت رمزنگاریشده یا فشردهشده در فایل برنامه قرار میگیرد و تنها در زمان اجرا از حالت فشرده خارج و یا رمزگشایی میشود.
استفاده از این تکنیک باعث میشود تا ابزارهای شناسایی بدافزار، مانند آنتیویروسها نتوانند به راحتی محتوای اصلی برنامه را بررسی و تحلیل کنند.
کلاس cn.beingyi.sub.apps.SubApp.SubApplication
🔸متد attachBaseContext
در این متد بدافزار با استفاده از متدهای getDir و getFilesDir دایرکتوری خاصی (ded و opt) را در فضای ذخیرهسازی برنامه ایجاد میکند. سپس این متد APK (بسته برنامه) را به صورت ZipFile باز و با فراخوانی متد ʿ(base) مسیر فایل APK را دریافت میکند. سپس متادیتا با فرمت JSON را از فایل پیکربندی در APK استخراج میکند که حاوی پرچمهایی است که بررسیهای امنیتی را کنترل میکند (مانند checkVirtual، checkXposed، checkRoot، checkVPN).
بر اساس پیکربندی JSON استخراجشده تشخیص امولاتور، وجود چارچوب Xposed، دسترسی روت و اتصالات VPN را بررسی میکند که اقدامات رایج ضد دستکاری هستند. سپس آرایهای از فایل DEX (Dalvik Executable) که در JSON تحت کلید “dex” شناسایی شدهاند، به صورت پویا بارگذاری میشوند.
این کار با استخراج فایلها از APK و نوشتن آنها در دایرکتوری، برای بارگذاری پویا DEX اصلی بدافزار با نام uPtXsM1W8BMxYvyj52o6tes7q1cDOgrz.dex در زمان اجرا انجام میشود. پس از استخراج فایل DEX، ، این فایل را در یک فرآیند پاکسازی حذف می شود که نشاندهنده ممانعت بدافزار از هر گونه تلاشی جهت دسترسی به این فایل جهت جلوگیری از تشخیص می باشد.
🔴 اکتیویتی com.malek.ir.MainActivity
🔸متد initialize
در این متد بدافزار وظیفه دارد تا شماره تلفن ورودی کاربر را بررسی کند و در صورت درست بودن، درخواست ارسال کد تأیید را به سرور ارسال کند. در واقع ابتدا بررسی میکند که فیلد ورودی برای دریافت شماره تلفن خالی است یا خیر. اگر فیلد شماره تلفن خالی باشد، پیامی با متن «شماره خود را وارد کنید» نمایش میدهد و از متد خارج میشود و در غیر این صورت بررسی میکند که آیا کاربر شماره تلفنی را که وارد کرده است، با کاراکتر”09″ آغاز میشود (برای اپراتورهای همراه کشور ایران ) و در صورت معتبر بودن، شماره تلفن را به فرمت بینالمللی (“98” به عنوان کد کشور ایران) تغییر داده و در متغیر sendRiply ذخیره میسازد. سپس، درخواست ارسال کد تأیید به سرور با استفاده از متد sendCodeTMP از کلاس Rubika ارسال میشود.
پاسخ دریافتی از سرور که در malek ذخیره شده است بررسی میشود که اگر شامل کلید “client_show_message” بود، به کاربر پیامی نمایش داده شود که کاربر با کلیک بر روی دکمه “باشه” آن را ببندد و اگر پاسخ شامل کلید “phone_code_hash” بود، این مقدار ذخیره و UI به روز شود تا کاربر بتواند کد تأیید را وارد کند. در انتها هم اگر شماره تلفن وارد شده شامل “09” نبود، یک پیام خطا به کاربر نمایش داده میشود.
🔸متد sendCodeTMP
متد sendCodeTMP مطابق تصویر برای ارسال یک درخواست JSON به سرور برای شروع عملیات تأیید مبتنی بر پیامک برای یک شماره تلفن مشخص (شماره تلفنی که در ابتدای اجرا از کاربر درخواست میشود) استفاده میشود. این متد یک پارامتر ورودی یعنی شماره تلفنی است که باید تأیید شود را دریافت کرده و سپس یک رشته JSON میسازد که نشاندهنده payload درخواست ارسال به سرور است که شامل اطلاعات زیر است:
- method: عملیاتی را که باید انجام شود، در این مورد، ارسال کد (sendCode) را مشخص میکند.
- Input: شامل شماره تلفن را که کد به آن ارسال خواهد شد و نوع متد ارسال است که روی “SMS” تنظیم شده است.
- client: اطلاعاتی در مورد برنامه، از جمله نام برنامه، نسخه، پلتفرم، نام بسته و کد زبان مربوط به API که بدفزار در حال ارتباط با آن است را ارائه میدهد. رشته JSON با استفاده از متد post_TmpSession ارسال میشود. این متد درخواست JSON را با استفاده از یک شی Encryption رمزگذاری میکند و آن را به عنوان یک درخواست HTTP POST به سرور در URL تعریف شده در متغیر urlX (در کلاس Rubika) یعنی آدرس “https://messengerg2c88.iranlms.ir” ارسال میکند.
در ادامه بدافزار چندین عمل مرتبط با برنامه روبیکا را انجام میدهد و با متدهای مختلفی از کلاس Rubika برای مدیریت احراز هویت، پیوستن به گروه، ارسال پیام و غیره تعامل دارد. بدافزار سعی میکند با استفاده از متد signInTMP وارد نسخه وب برنامه روبیکا شود که یک متد ورود موقت با پارامترهایی مانند هش کد تلفن و کد تأیید است. پاسخ سرور در یک آرایه بنام arr_s تجزیه میشود که جهت احراز هویت و تنظیم بیشتر استفاده میشود.
با استفاده از متد registerDevic دستگاه را ثبت میکند و نتیجه در متغیر PA ذخیره میشود. سپس از متد joinGroup برای پیوستن به یک گروه خاص استفاده میکند و نتیجه را در متغیر join ذخیره میسازد و در ادامه مقدار authentication token در متغیر AuthAcunt ذخیره میشود.
همچنین از متد sendMessage برای ارسال مقدار malekam (این متغیر حاوی توکن احراز هویت کاربر بعلاوه کلید خصوصی نشست کاربر) به گروه یا کانالی که توسط Guid شناسایی شده است، استفاده میکند. سپس بلافاصله سعی میکند گروه را با فراخوانی متد leaveGroup ترک کند و با متد joinChannel جهت پیوستن به کانالی جدید فراخوانی میکند و سپس متد malek درخواستی را برای بازیابی اطلاعات مربوط به یک چت یا گروه در برنامه میسازد و ارسال میکند. سپس یک پاسخ از متد malek را بازیابی میکند (داخل متغیر s)، که حاوی اطلاعاتی در مورد وضعیت گروه یا کانال فعلی است و آن را به متغیر leave اختصاص میدهد .
سپس جزئیات مربوط به یک چت و آخرین پیام را استخراج و آن را در متغیر input ذخیره میکند. متغیر mmm حاوی یک درخواست حذف (mmmm) برای یک پیام چت خاص می باشد. سپس مقدار 659456667999560 با message_id واقعی آخرین پیام ورودی جایگزین میکند و متد Maleki را برای ارسال درخواست حذف برای پیام مشخص شده فراخوانی میکند. متد _ get در حال آماده سازی و ارسال یک درخواست POST به “https://rubino7.iranlms.ir” با پارامترهایی برای بازیابی لیست پروفایل است.
🔸 متد signInTMP
بدافزار یک شماره تلفن را به عنوان ورودی میگیرد و متد signInTMP را با یک phone_code_hash و کد تأیید ارائه شده توسط کاربر فراخوانی میکند. بدافزار در این متد در تلاش برای دور زدن جریانهای احراز هویت استاندارد با فراخوانی مستقیم متدهایی است که یک ورود معتبر را شبیهسازی میکنند. در این متد بدافزار از یک شی Encryption برای ایجاد یک نشست استفاده میکند و یک جفت کلید عمومی-خصوصی (keyGenerate) تولید میکند.
کلید خصوصی به صورت محلی ذخیره میشود، در حالی که کلید عمومی در درخواست ورود به سرور گنجانده شده است. این احتمالاً برای تأیید اعتبار نشست است. در ادامه JSON (s3) درخواست ورود به سیستم شامل: شماره تلفن، هش کد تلفن، کد تأیید و کلید عمومی و فراداده های مشتری، مانند نام برنامه، نسخه، پلتفرم و کد زبان است.
متد post_TmpSession این درخواست را به یک سرور مشخص (تنظیم شده در متغییر urlX یعنی آدرس “https://messengerg2c88.iranlms.ir” ارسال میکند. دادهها قبل از ارسال رمزگذاری میشوند و پاسخ پس از دریافت رمزگشایی میشود. بعد هنگامی که پاسخ سرور (s4) دریافت شد، این متد سعی میکند آن را تجزیه کند تا بررسی کند که آیا وضعیت ورود به سیستم “OK” است یا خیر و در صورت موفقیتآمیز بودن، یک کلید احرار هویت (auth key) را از دادههای پاسخ بازیابی میکند.
این توکن با استفاده از کلید خصوصی تولید شده رمزگشایی شده و در کنار پاسخ سرور برگردانده میشود. به طور کلی متد signInTMP میتواند برای تصاحب حساب کاربری روبیکا استفاده شده و اجازه دسترسی غیر مجاز و دستکاری نشستهای کاربر را میدهد.
🔸 متد joinGroup
متد joinGroup برای ارسال درخواست برای پیوستن به یک گروه در برنامه پیامرسان روبیکا با استفاده از یک درخواست رمزگذاری شده طراحی شده است. متد joinGroup یک پارامتر واحد، s را میگیرد که بیانگر یک پیوند هش به گروهی است که کاربر میخواهد به آن ملحق شود و سپس یک رشته JSON که نشاندهنده پیلود درخواست است ایجاد میکند، این رشته شامل method (“joinGroup” عملی را که باید انجام شود)، input (حاوی یک شی فرعی با “hash_link” است که s پیوند هش گروهی است که باید ملحق شود)، client (فراداده مشتری، از جمله نام برنامه، نسخه، پلتفرم، نام بسته و کد زبان را مشخص میکند) است و بارگذاری به صورت پویا با ترکیب مقادیر از نمونه فعلی مانند this.app_versipn برای نسخه برنامه ایجاد و سپس متد post فراخوانی میشود و رشته JSON ساخته شده را به عنوان آرگومان ارسال میکند.
🔸 متد sendMessage
متد sendMessage برای ارسال پیام به یک گیرنده یا گروه مشخص در برنامه پیامرسانی روبیکا طراحی شده است. یک پیلود JSON حاوی جزئیات پیام میسازد، دادهها را رمزگذاری و سپس با استفاده از درخواست POST به سرور ارسال میکند. این متد حاوی دو پارامتر هست، متغیر s متن پیامی که باید ارسال شود و متغیر s1 که گیرنده یا گروهی را که پیام به آن ارسال خواهد شد، مشخص میکند.
به طور کلی این متد یک پیلود JSON برای نمایش درخواست ارسال پیام میسازد و پیام را با استفاده از درخواست POST به یک گیرنده یا گروه مشخص ارسال میکند و پس از ارسال پیام با استفاده از متد joinChannel و یک لینک هش شده به یک کانال بپیوندد و در نهایت پاسخ سرور را برمیگرداند که نتیجه عملیات ارسال را نشان میدهد.
🔸 متد _get
متد _get یک درخواست HTTP POST با پارامترهای “api_version” (نسخه API را مشخص میکند)، “auth” ()، “client” (شامل جزئیات مربوط به مشتری است، مانند نام برنامه، نسخه برنامه، کد زبان، نام بسته، و پلتفرم)، “data” (جزئیات درخواستی خاص مانند برابری، تعداد پروفایلها ارسالی و نحوه مرتبسازی را مشخص میکند) و “method” (” متد API در حال فراخوانی (“getProfileList“) را مشخص میکند که لیستی از پروفایلها موجود از سرور درخواست میکند ) را به یک URL داده شده (https://rubino7.iranlms.ir) میسازد و ارسال میکند.
به طور خلاصه، این متد یک پیلود JSON میسازد و به صورت پویا یک authorization token را وارد میکند و سپس آن را به عنوان یک درخواست POST به URL مشخص شده ارسال میکند.
.
در ادامه دنبالهای از اقدامات مثل ارسال کد SMS به شماره تلفن ارائه شده توسط کاربر و به روز رسانی رابط کاربری بر اساس پاسخ سرور انجام میدهد. و متد sendCodePasswordTMP یک درخواست کد مبتنی بر پیامک را برای تأیید شماره تلفن با استفاده از یک کلید امنیتی ارائه شده آغاز میکند.
این درخواست را با اعتبار نشست موقت برای مدیریت ایمن در سمت سرور ارسال میکند و این مرحله بخشی از فرآیند احراز هویت یا بازیابی حساب در برنامه روبیکا است.
متد _folo برای ارسال یک درخواست “فالو” به سرور از طریق یک درخواست شبکهای POST طراحی شده است. این متد با استفاده از پارامترهای ورودی و مقادیر تنظیمشده، دادههای JSON را آماده کرده و درخواست دنبال کردن را برای پروفایلی خاص ارسال میکند.
ابتدا یک ساختار JSON برای ارسال درخواست دنبال کردن ساخته میشود و این JSON شامل اطلاعات عمومی درخواست مانند نسخه برنامه و نوع درخواست (Follow) میباشد و برای ارسال درخواست به سرور روبیکا آماده شده است.
پس از تنظیم ساختار اولیه JSON مقادیر بصورت داینامیک جایگزین میشوند بدین صورت که “Az” با مقدار AuthAcunt جایگزین میشود که نشاندهندهی توکن احراز هویت کاربر است و مقدار”635ff1379dc6d67fad3ae150” با مقدار متغیرs جایگزین میشود که profile_id پروفایلی است که باید فالو شود. مقدار “60aea5b63b775004b3e70883” با مقدار متغیر s1 جایگزین میشود که followee_id کاربری است که درخواست دنبال کردن را انجام میدهد.
پس از انجام جایگزینیها، JSON نهایی به یک HashMap تبدیل میشود، سپس درخواست فالو با استفاده از MALEK_OK که یک شیء RequestNetwork است، به آدرس “https://rubino29.iranlms.ir” ارسال میشود. MALEK_OK_request_listener به عنوان listener پاسخ درخواست شبکه عمل میکند و وضعیت درخواست را مدیریت میکند.
🔸متد initializeLogic
در این متد بدافزار یک (GET) request به آدرس“https[:]//tackserver-code.ir/json/\u0644\u06CC\u0646\u06A9 \u06AF\u0627\u0631\u062F .json” ارسال می نماید و با استفاده از شنونده vahid_request_listener پاسخ JSON دریافتی را کنترل می نماید. بدافزار از این پاسخ JSON برای بهروزرسانی متغیرهای داخلی (link، Link، id_fa) استفاده میکند و رفتار برنامه را به صورت پویا تغییر میدهد.
سپس متد vpn را فراخوانی می کند تا تشخیص دهد آیا VPN فعال است یا خیر و اگر VPN شناسایی شد، یک پیام “VPN را خاموش کنید!” نمایش داده می شود (بدافزار برای جلوگیری از مانیتور عملیات شبکه خود توسط ابزارهای مانیتورینگ و شناسایی عملکرد خود آن را بررسی می نماید) و بدافزار اکتیویتی خود را با استفاده از متد finishAffinity می بندد.
🔴 اکتیویتی com.malek.ir.GhoflActivity
🔸متد initialize
بدافزار در این متد چندین عنصر کاربری (UI elements) و همچنین یک درخواست شبکه برای انتقال شارژ راهاندازی میشود. متد onResponse یک متد callback است که زمانی فعال میشود که درخواست شبکه پاسخی موفقیتآمیز دریافت کند. این متد سه پارامتر شامل s (یک رشته)، s1 (پاسخ JSON به عنوان یک رشته) و hashMap0 (یک HashMap) را دریافت میکند. از کتابخانه Gson برای تجزیه s1 (پاسخ JSON) به HashMap استفاده میکند.
دادههای تجزیه شده در hashMap1 ذخیره میشوند. سپس این HashMap برای استفاده بیشتر در اکتیویتی به متغیر vahid12 اختصاص داده میشود. این متد یک کد USSDبا فرمت “numbersharj*1#10142” ساخته که در آن number و sharj مقادیری هستند که از vahid12 HashMap استخراج میشوند و احتمالاً نشاندهنده شماره تلفن مقصد و مقدار انتقالی شارژ هستند.
کد نهایی USSD در متغیر vahid ذخیره میشود. Uri.encode(“#”) برای اطمینان از کدگذاری صحیح کاراکتر # استفاده میشود، زیرا در قالببندی USSD لازم است. سپس این متد یک intent (intent) برای شروع تماس تلفنی با استفاده از کد USSD ایجاد شده تنظیم میکند. intent.setAction(“android.intent.action.CALL”) اکشن intent را برای برقراری تماس تنظیم میکند.
intent.setData(Uri.parse(“tel:” + GhoflActivity.this.vahid)) داده را روی tel و سپس کد USSD تنظیم میکند و یک درخواست “phone call” ایجاد میکند. در نهایت، متد startActivity فراخوانی میشود که شمارهگیر تلفن را راهاندازی میکند تا کد USSD تولید شده را شمارهگیری کند.
تکنیکهای بدافزار
بدافزار در متد “ˈ” بارگذاری فایل dex را بر اساس Android SDK مدیریت و ClassLoader را تنظیم میکند تا فایلهای dex را به صورت پویا بارگیری کند. سپس مواردی چون وجود چارچوب xposed، بررسی روت بودن و تشخیص امولاتور و وجود vpn را بر روی گوشی کاربر شناسایی کرده و در صورت وجود از برنامه خارج میشود.
روش مقابله و پاکسازی سیستم
- برای ایجاد اطمینان از عدم آلودگی دستگاه، آنتی ویروس پادویش را نصب و فایل پایگاه داده آن را به روز نگهدارید و اسکن آنتی ویروس را انجام دهید.
- برای غیرفعالسازی نشستهای ناشناس در روبیکا، میتوانید با شمارهگیری #999* روی خطی که اکانت روبیکا روی آن ثبت شده است و انتخاب گزینه ۲ از منوی نمایش داده شده و سپس انتخاب گزینه ۱ برای غیرفعالسازی نشستهای غیرمجاز اقدام نمایید.
- فعالسازی احراز هویت دو مرحلهای (2FA) و قفل صفحه نمایش میتواند بهطور چشمگیری امنیت حساب کاربری شما در برنامه روبیکا را ارتقا دهد و از دسترسی افراد ناشناس به اکانت شما جلوگیری کند.
روش های پیشگیری از آلوده شدن گوشی:
- از دانلود و نصب برنامه از منابع و مارکتهای موبایلی نامعتبر خودداری کنید.
- هنگام نصب برنامههای موبایلی، به مجوزهای درخواستی توجه فرمایید.
- از فایلها و اطلاعات مهم موجود در گوشی خود، به طور مستمر پشتیبانگیری کنید.
- از نسخههای غیر رسمی برنامهها استفاده نکنید.