به نام خدا
با سلام خدمت دوستان. خداروشکر فرصتی دیگه پیدا شد که مرحله سوم مسابقه رو در خدمتتون باشم.
همونطور که توی پست اول گفتم این چالش مرحله به مرحله جلوتر میره و هر مرحله نسبت به قبل سختتر میشه. ما تا الان توی دوتا مرحله قبلی، تونستیم نحوه ریورس کردن فایلهای .Net و Native رو توضیح بدیم. توی این مرحله ما مهندسی معکوس فایهای apk اندرویدی رو یاد میگیریم. همچنین میفهمیم که چجور با استفاده از ابزار Frida در اپهای اندرویدی حین اجرا کد تزریق کنیم. قطعا این تجربه جالبی خواهد بود، چون با نحوه آنالیز فایلهای اندرویدی آشنا میشیم و میتونیم بدافزارها و برنامه های اندرویدی رو هم بررسی کنیم. خب بریم سراغ مرحله سوم.
چالش شماره 3 : Flarebear
فایلهای مربوط به این چالش رو میتونید از اینجا دانلود کنید.
پیش نیازها:
- ویندوز 7 یا بالاتر
- ابزار jadx
- آشنایی با زبان جاوا یا اندروید
- یک گوشی اندروید 5 به بالا یا استفاده از شبیه ساز اندروید که من اینجا شبیه ساز NOX رو پیشنهاد میکنم.
- یه ذره ریاضی هم نیاز داریم در حد ریاضی دبیرستان 😀
خب شما یک فایل زیپ دارید که داخلش دوتا فایل هست یه فایل apk که هدف اصلی سوال هست و یک فایل Message که اطلاعاتی در مورد چالش به ما میده. در ابتدا وقتی فایل Message رو باز میکنیم به ما گفته شده که «ما توی Flare یه حیوان خانگی داریم که اسمش هست flarebear . اونو زنده و خوشحال نگه دارید و اون پرچم مرحله بعد رو به شما نشون میده».
خب ما بعد از اینکه این متن رو میخونیم میفهمیم که با یه بازی مواجه هستیم که یه خرسی رو باید زنده و خوشحال نگه داریم تا رمز ورود به مرحله بعد رو به ما نشون بده.
خب چون ما برا کار با گوشی های اندرویدی نیاز داریم یه سری ابزارها و پروتکل ها رو بلد باشیم، من اینجا مرحله به مرحله توضیحات مورد نیاز رو براتون میگم.
اولا که ما باید این فایل apk رو روی گوشیمون یا شبیه ساز اندروید نصب کنیم. من اینجا پیش فرض رو بر این میزارم که شما روی شبیه ساز نصب میکنید. پس هرجا که از کلمه شبیه ساز استفاده کردم، شما خودتون متوجه بشید که منظورم هم گوشی هست هم شبیه ساز.
خب اول بگیم شبیه ساز یا simulator android چی هست:
همونطور که میدونید سیستم عامل اندروید یک سیستم عامل متن باز یا همون open source هست که توسط شرکت گوگل توسعه داده میشه و هسته این سیستم عامل، همون هسته لینوکس هست. این سیستم عامل مختص گوشی و تبلت ها ساخته میشه. نوع پردازنده های گوشی ها و تبلت ها، با پردازنده های کامپیوتر و لپ تاپ فرق میکنه. به عنوان مثال اکثر گوشی ها از پردازنده های ARM استفاده میکنند ولی کامپیوتر ها از پردازنده های AMD یا Intel استفاده میکنند. به همین دلیل گوگل سیستم عامل اندرویدش رو بر پایه پردازنده های ARM تولید میکنه. ولی شما میتونید کد سیستم عامل اندروید رو بردارید و برای پردازنده های Intel کامپایل کنید و روی سیستمتون در کنار ویندوزتون سیستم عامل اندروید هم داشته باشید.
حالا یه سری شرکت ها از جمله خود گوگل اومدن برا اینکه ما بتونیم از سیستم عامل اندروید بدون نیاز به سخت افزار خاصی استفاده کنیم، یه شبیه ساز ساختن که سیستم عامل اندروید رو به صورت مجازی برای ما اجرا میکنه. مثل اینکه دقیقا شما با virtualBox یا VMware یه ماشین مجازی میسازید.
چونکه شبیه ساز گوگل حجم بالایی داره و اینکه مارو هم تحریم کرده، من پیشنهاد یه شبیه ساز بهتر رو دارم به نام NOX که اندروید 5.1. رو شبیه سازی کرده و خیلی راحت با چندتا کلیک ساده نصب میشه و اجرا میشه و دسترسی و کار کردن باهاش هم خیلی راحته.
بازم اینجا تاکیید میکنم که برای این مرحله، ما نیاز به شبیه ساز نداریم چونکه این فایلی که میخوایم آنالیز کنیم هیچ خطری نداره و شما میتونید روی گوشیتون هم اجراش کنید. ولی در نظر داشته باشید که برای تحلیل فایلهای بدافزار اندرویدی شما حتما نیاز دارید که یه شبیه ساز اندروید داشته باشد که با خیال راحت برنامه روش اجرا کنید.
قدم اول: نصب فایل apk
خب مرحله اول نصب فایل Apk بر روی شبیه ساز هست. خوشبختانه خود NOX برامون قابلیت نصب فایل بدون نیاز به کار خاصی رو داره. البته اگه از شبیه ساز گوگل استفاده میکنید باید با استفاده از پروتکل ADB ، فایل رو روی شبیه ساز نصب کنید.
خب NOX رو نصب کنید، که البته با چندتا کلیک ساده نصب میشه. فقط حواستون باشه که قابلیت Virtualization CPU رو از داخل تنظیمات بایوس فعال کنید که CPU سیستمتون بتونه پردازش شبیه ساز رو به خوببی انجام بده. بعد وقتی اجراش کردید دقیقا یه محیط اندروید رو خواهید دید. یه نوار ابزار سمت چپ وجود داره که یه دکمه داره با زدن اون میتونید آدرس فایل APK رو بهش بدید و خودش براتون نصب میکنه.
خب وقتی نصب بشه آیکن یه خرس میاد روی صفحه. خب ما وقتی بازی رو اجرا کنیم اولش میگه یه خرس برا خودت بساز یه اسم هم براش انتخاب کنید و بازی شروع میشه. اگه دوستان مخصوصا خانم ها یادشون باشه چندسال پیش یه بازی اندرویدی خیلی مد شده بود خیلی هم باحال بود به نام Poo که شما باید یه موجودی رو بزرگ میکردید و بهش آب و غذا میدادید و از این حرفا. این بازی هم تقریبا مثه اونه.
خب یه سری دکمه هست توی بازی که باید اینارو ببینیم هر کدوم برا چی هست:
یه دکمه قاشق چنگال هست که وقتی روش بزنی مثلا به این خرس غذا میدید
یه دکمه توپ هست که مثلا این خرس باهاش بازی کنه و یه دکمه جارو هست که وقتی این خرس خرابکاری میکنه، شما باید با جارو تمیز کنی.
خب حالا برگردیم به هدف این مرحله. به ما گفته شده که این خرس رو زنده و خوشحال نگه دارید تا رمز عبور رو به شما نشون بده. حالا ما باید ببینیم که این خرس چه جور زنده و خوشحال میشه. قطعا با بازی کردن و غذا خوردن این خرس خوشحال میشه ولی ما نمیدونیم چقدر باید بهش غذا بدیم و تا کی باید کثافت کاریشو جمع کنیم تا خوشحال بشه.
پس راه حل چیه؟ راه حل اینه که ما بیایم و این برنامه رو Reverse کنیم، کدش رو بخونیم و بفهمیم که این خرس چه زمانی خوشحال میشه.
خب پس الان یه دید خوبی از کاری که قراره بکنیم داریم. حالا بریم سراغ مهندسی معکوس فایلهای اندرویدی.
خب فایلهای اندروید در حقیقت چیزی نیستند جز یه سری کلاس که به زبان جاوا نوشته شدند و بعدش zip میشن و پسوندشون رو عوض میکنن و میگن بهشون APK. شما میتونید یه فایل Apk رو به راحتی با winrar باز کنید و اون کلاس های جاوا رو توش ببینید.
خب پس ما فهمیدیم که ماهیت فایلهای اندرویدی، جاوا هستن و جاوا هم یه زبان مفسری هست شبیه به .net که خب reverse کردنش راحت تر از زبانهای native هست. حالا بریم سراغ اینکه چجور کد برنامه رو به دست بیاریم.
خب ابزار jadx برا این ساخته شده که برامون این کار رو انجام بده. وقتی دانلوش کردید توی فولدرش، یه فایل bat هست که نوشته jadxgui ، اونو باز کنید تا نرم افزار jadx به صورت گرافیکی براتون باز بشه. بعدش فایل Apk رو توش darg کنید و بعدش میبینید که در کنار سمت چپ صفحه، براتون لیست کلاس ها و توابع رو میاره. دقیقا عین ابزار dnspy که برای چالش ۱ براتون گفتم. خب توی عکس میبینید اینارو.
خب همونطور که میبینید، تمام پکیج های برنامه رو برامون اورده، ما با پکیج اصلی برنامه کار داریم که اینجا پکیج اصلی به اسم com.fireeye.flarebear وجود داره. پکیج اصلی همون پکیج هست که توابع و کدهای برنامه داخلشه. خب بریم ببینیم داخل این پکیج چه توابعی هست. من یه نکته بگم اینجا شاید براتون سوال باشه که من از کجا فهمیدم که کلاس اصلی برنامه com.fireeye.flarebear هست؟ باید بگم که اینا تجربی هست. مثلا من چندین بار با فایلهای apk اندرویدی کار کردم و فهمیدم که اسم پکیج ها توی اندروید با این فرمت ساخته میشه:
Com.packagename
از اینجا من میفهمم که این اسم پکیج ما هست که پکیج اصلی برنامه هست. مثلا ببینید اون kotlin و android و اینا همگی کتابخونه هایی هستند که توی ساخت نرم افزارهای اندرویدی ازشون استفاده میشه.
خب همونطور که توی عکس میبینید وقتی این پکیج رو باز میکنیم به یه سری کلاس ها برخورد میکنیم، ولی یه کدومش هست که توابعش از همه بیشتره که اسمش هست FlareBearActivity و اسم توابع به ما میگه که این کلاس همون کلاس اصلی برنامه هست. مثلا توابعی مثل feed به معنی غذادادن، dance و … که مشخص میکنه توابع اصلی برنامه مثل غذادادن و رقصیدن و تمیز کردن و اینا توی این قسمت تعریف شدن.
خب یه تابعی اینجا به چشم ما میخوره که کنارش خط کشیدم، و اونم تابع dancewithflag هست. که از معنیش مشخصه که خرس زمانی که خوشحال باشه برامون میرقصه و پرچم یا همون فلگ رو بهمون نشون میده. خب این تابع برامون مهمه بریم داخلش ببینیم چه خبره.
خب وقتی روی تابع dancewithflag کلیک کنیم کدش رو داخل کلاس FlareBearActivity برامون نمایش میده توی پنجره سمت راست.
خب همونطور که توی عکس پایین میبینید، توی کد این تابع اومده و اولش رفته و از قسمت Resource های برنامه و یه چیزی به نام ecstatic رو باز کرده و بعدش تو خط بعدی اومده و یه رشته به نام EcstaticeEnc رو خونده و اونو توی یه آرایه ذخیره کرده و در ادامه کار همینطور که به کد نگاه کنیم میتونیم بفهمیم که با این رشته ها یه سری کارا کرده و بعد در انتها اومده و تابع dance رو اجرا کرده. خب نکته الان همینجاست. پس هر خبری هست توی resource های برنامه باید بریم دنبالش.
معرفی و شناخت Resources در فایلهای اجرایی
من یه توضیحی در مورد resource بدم. توی فایلهای اجرایی، یه قسمتی هست به نام resources که اینجا یه سری از اطلاعاتی که برنامه برای اجرا شدن نیاز داره رو ذخیره میکنه. مثلا آیکن برنامه ها توی ویندوز توی قسمت Resource هاش ذخیره میشه و مثلا اگه عکسی، و مدیا خاصی برنامه نیاز داشته باشه اصولا برنامه نویس اینارو توی قسمت resource ها قرار میده. این Resource ها دقیقا جزیی از فایل اجرایی هست و خیال نکنید که مثلا از یه جای عجیب غریب ویندوز مییره و آیکن هاشو میاره. تمام آیکن ها و … توی همین resources هست.
برای درک بهتر این قضیه میخوام خدمتتون resource های برنامه ماشین حساب ویندوز رو مثال بزنم. ببینید برای اینکه ببینید توی Resource های یه برنامه چیا هست، شما نیاز دارید که از ابزار ResourceHacker استفاده کنید. من الان این ابزارو دارم و براتون ماشین حساب ویندوز رو توش باز میکنم و تو عکس زیر میبینید که آیکن ها و یه سری string های ماشین حساب رو ذخیره کرده.
خب ببینید ابنجا مثلا الان من میتونم توی این قسمت resource ها رو دستکاری کنم. و مثلا آیکن ماشین حساب ویندوز رو عوض کنم. یا مثلا متن پیغام error که ماشین حساب میده رو من عوض کنم. خب ببینید مثلا این آیکنی که اینجا انتخاب کردیم رو من با یه آیکن دیگه میتونم عوض کنم.
روی همون عدد یا index مربوط به آیکن که اینجا 12:1033 هست کلیک راست میکنیم و گزینه replace icon رو میزنیم و یه آیکن همینجوری انتخاب میکنیم و بعدش هم save میکنیم.
خب همونطور که میبینید من آیکن ماشین حساب رو عوض کردم و به جاش آیکن notepad رو گذاشتم.
خب هدف از این چیزایی که گفتم این بود که کلا بفهمید Resource چی هست. حالا اینا که من گفتم به چه دردی میخوره؟؟ یکی از مکان هایی که بدافزارها خیلی ازش استفاده میکنن همین قسمت resource هست. مثلا یه بدافزار میاد و کد مخرب رو توی این قسمت میزاره به صورت رمز شده. با این کار آنتی ویروس میاد و وقتی اون بدافزار رو آنالیز میکنه چیز خاصی نمیبینه و اینو به عنوان یه فایل سالم میشناسه. بعد بدافزار میاد و این کدی که توی این قسمت resource خودش ذخیره کرده رو استخراج میکنه و رمزگشایی میکنه و اونو اجرا میکنه و به این صورت بدافزار خیلی شیک اجرا میشه بدون اینکه آنتی ویروس بشناسه. البته جدیدا آنتی ویروس ها دیگه این قسمت resource های یه فایل رو هم اسکن میکنن ولی این قسمت resource همچنان یه مکان خوبی برای مخفی کاری هست.
خب اینارو گفتم حالا بریم سراغ ادامه کار. حالا ما فهمیدیم که این تابع dancewithflag میاد و یه رشته ای رو توی resource ها میخونه. و بعد از این رشته استفاده میکنه و در نهایت این خرس شروع میکنه به رقصیدن.
حالا ما چه جوری میتونیم ببینیم داخل این قسمت resource های این apk چیا هست؟؟ ابزار jadx خودش برامون Resource ها رو هم میاره. همونطور که در عکس میبینید دقیقا توی Resource ها همون رشته ecstatic موجوده ولی وقتی بازش میکنیم با یه مشت داده چرت و پرت مواجه میشیم. که خب معلومه که رمزنگاری شده. پس عملا نمیتونیم چیزی ازشون پیدا کنیم که بفهمیم رمز عبور چی هست.
شناسایی و بررسی تابع هدف
خب حالا چیکار کنیم؟ راهی که به ذهن من رسید برا حل این چالش این بود که بیام و تابع dancewithflag رو کاری کنم که اجرا بشه با تغییر ایجاد کردن توی کد و بعد دوباره کامپایل کردن اون. ولی یه کم که رفتم جلو فهمیدم کلا این کار سخت ترین راه با احتمال بالا نشدنی ترین راه هست. چونکه شما باید تمام این کدهایی که توی این jadx میبینید رو بردارید ببرید توی یه محیطی مثل android studio تغییرات رو توش اعمال کنید و بعد کامپایلش کنید که آیا بشه یا نشه.
بعد یه کم که فکر کردم گفتم بذار ببینم این تابع Dancewithflag کی و کجا اجرا میشه؟؟ بلاخره یه زمانی این خرسه به خوشحالی میرسه و بعدش این تابع فراخوانی میشه. برم ببینم در چه صورتی این تابع فراخوانی میشه.
خب اومدم و این کارو کردم:
شما برا اینکه بفهمید این تابع dancewithflag کجا فراخوانی میشه فقط کافیه که اسمش رو توی کد جست و جو کنید. توی عکس میبینید که من اسمشو سرچ کردم و فقط و فقط یه جا این تابع فراخوانی میشه. اونم جایی نیست جز تابع setMood که اومده یه سری شرط ها رو چک کرده و در صورتی که این شرطها درست بودن در نهایت میره و تابع dancewithflag رو صدا میزنه. خب حالا بیاین بریم و ببینیم این شرطها چی هستند هر کدوم.
( اگه تصویر واضح نیست روی عکس راست کلیک کنید و گزینه open in new tab رو بزنید)
خب اولین شرطی که چک میشه، مقدار خروجی تابع isHappy هست. همونطور که از اسمش مشخصه، اسن تابع بررسی میکنه که ایا خرس خوشحاله یا نه. در صورتی که این تابع مقدار true برگردونه، میاد و یه شرط دیگه رو چک میکنه و اونم تابع isEcsatic هست که مشخص میکنه آیا خرس هیجان زده شده یا نه. فک کنم خرسه خیلی که خوشحال بشه دیگه از خود بیخود میشه. این تابع اگه مقدار true برگردونه یعنی دیگه خرس به اوج درجه شادی رسیده و رمز رو به شما نشون میده و تابع dancewithflag رو اجرا میکنه.
خب حالا بریم ببینیم تابع isHappy چه زمانی مقدار true رو برمیگردونه:
همونطور که توی عکس میبینید، این تابع میاد و یه بار تابع getstat رو با پارامتر f و یه بار با پارامتر p فراخوانی میکنه، و بعد اینا رو به هم تقسیم میکنه و اگه جواب تقسیم بین 2 تا 2.5 بود، مقدار صحیح برمیگردونه. در این صورت خرس خوشحاله. حالا دوتا سوال پیش میاد: یکی اینکه این تابع getstat چیه و یکی هم، این f ,p چی هستن؟؟
خب اول بریم ببینیم این تابع getstat چیه. توی تصویر مشخصه دقیقا زیر تابع isHappy واقع شده. این تابع میاد و از تابع getDefaultSharedPrefrences استفاده میکنه و رشته ای با نام activity رو پیدا میکنه. یه کم گیج کننده شد. اصن اینا جی هستند. حقیقتا منم خودم اینارو نمیدونستم ولی خب شما زمانی که دارید reverse میکنید به کلی مشکل و تابع میخورید که باید اینارو سرچ کنید تا بفهمید کارشون چی هست.
هر برنامه اندرویدی، یه فایل تنظیمات داره که با فرمت xml ذخیره میشه توی محلی که توی گوشی نصب شده. اسم اون فایل تنظیمات،Default Shared preferences هست. حالا این تابع میاد و مقدار متغیر Activity رو توی این فایل پیدا میکنه و میاد تعداد اون کارکتری که به تابع پاس داده شده رو توش شمارش میکنه. قبول دارم که یه کم درک این قسمت سخت شده ولی من برا اینکه راحت بتونید بفهمید چی شده این فایل رو براتون باز کردم توی عکس زیر و مشخص کردم اون قسمت رو. مثلا الان توی تابع isHappy اومده تابع getstat رو با مقدار f فراخوانی کرده. خب اینجا تابع getstat میاد و حرف f روی توی رشته Activity توی اون فایل preferences میشماره و تعدادش رو به ما برمیگردونه. عکسو ببینید تا بهتر متوجه بشید. این فایل رو شما میتونید از طریق دستورات adb باز کنید.( Adb یک پروتکل ارتباطی هست برای ارتباط با گوشی های اندوریدی از طریق کامپیوتر)
خب ببینید من این فایلو توی سیستم خودم باز کردم. این فایل توی سیستم من نیست. این فایل توی گوشی یا همون شبیه ساز هست که من از طریق پروتکل adb به شبیه ساز وصل شدم و رفتم داخل فولدری که بازی نصب شده و این فایلو از اونجا باز کردم. در مورد ADB آخر این پست توضیح دادم. ولی اگه خواستید این فایلو ببینید، میتونید با دانلود کردن Adb و اجرای دستوراتی که از اول توی عکس مشخصه، به این فایل برسید. دوستانی که لینوکس بلدن میدونن که این دستورات همه لینوکسیه.
خب ببینید توی این فایل یه جاهایی رو با فلش قرمز مشخص کردم که جالبه. مثلا اسم خرس من Alee هست که میبینید توس خط اول ذخیره شده با مقدار name و یا مثلا متغیر هایی مثل clean,happy,poo که یه عدد هست که مشخص کرده وضعیت خرس من الان چیه مثلا 226 تا خوشحاله. حالا در ادامه متغیر activity رو میبینیم که با رنگ آبی مشخص کردم که مقدارش یه رشته طولانی هست که از f ,p,c تشکیل شده.
این همون رشته Activity هست که تابع getstat میگیره و به دنبال تعداد f توش میگرده.
حالا این رشته به این طویلی از کجا اومده؟؟ چون من یه کم بازی کردم و این رشته تولید شما. شما اگه این فایل رو قبل از اجرای بازی باز کنید میبینید که فایل تمام مقادیرش خالیه.
خب حالا ببینیم این f,p,c هر کدوم نشونه چی هست. البته قطعا تا الان متوجه شدید که مثلا f حرف اول food هست و p برای poo و c حرف اول clean ولی فرض کنیم اینارو نمیدونیم. از کجا بفهمیم که این تابع isHappy چرا اومده و تابع getstat را با مقدار f و p صدا زده؟
میایم و یه کم کد رو میچرخیم و دنبال جایی میگردیم که این f و یا p رو استفاده کرده باشن. وقتی کد رو دیدیم بر میخوریم به چندتا تابع که توی عکس مشخصه و از حروف f و c و p داخلشون استفاده شده.
خب ببینید من این سه تابع رو عکسشون رو کنار هم گذاشتم تا بهتر متوجه بشید وگرنه اینا توی کد کنار هم نیستن. خب همونطور که میبنید مثلا تابع play وقتی فراخوانی میشه، تابع saveactivity با مقدار p صدا زده میشه. از اینجا میشه فهمید وقتی خرس بازی میکنه، یه دونه p به انتهای اون رشته ای که توی عکس قبلی دیدیم اضافه میشه یا مثلا اگه خرس رو تمیز کنیم تابع clean صدا زده میشه و بعدش تابع saveactivity با مقدار c صدا زده میشه و خب یه دونه کارکتر c به انتهای اون رشته Activity اضافه میشه و خب تابع feed هم برا زمانی هست که شما به خرس غذا میدید و اون تابع saveactivity با مقدار f صدا زده میشه که خب مسلما یه دونه f به ته اون رشته اضافه میشه. برا اثبات حرفم میام و من یک بار به خرس غذا میدم و یک بار هم باهاش بازی میکنم ما انتظار داریم که به انتهای رشته Activity اول یه دونه f برا غذا دادن اضافه بشه، بعد هم یه دونه p برای بازی کردن.
خب ببینید توی عکس اون رشته ای که اول من ازش عکس گرفته بودم و تو عکس قبلی بود رو با 1 مشخص کردم بعدش اومدم یه بار روی قاشق کلیک کردم و بعدش هم روی توپ و بعدش دوباره اون فایل رو باز کردم که همونجور که میبینید، یه fp به انتهاش اضافه شده. پس شما هرکاری با این خرس بکنید توی این رشته Activity به این صورت ذخیره میشه. امیدوارم که فهمیده باشید. تمام تلاشم رو کردم با عکس و اینا توضیح بدم.
خب یه بار برگردیم به عقب ببینیم چیا الان دستگیرمون شده. ما فهمیدیم که زمانی رمز مرحله بعد به ما نشون داده میشه که خرس خوشحال باشه و بعدشم هیجان زده بشه. یعنی تابع isHappy و تابع isEcstatic مقدار true برگردونن. خب ما اومدیم فهمیدیم که تابع isHappy میاد و تعداد f ها رو میشماره یعنی تعداد دفعاتی که بهش غذا دادیم و تعداد p ها که میشه تعداد دفعاتی که باهاش بازی کردیم و اولیو تقسیم میکنه به دومی و اگه حاصل این تقسیم بین 2 و 2.5 بود یعنی خوشحاله. خب پس ما اگه میخوایم که خرسمون خوشحال بشه یا همون تابع isHappy مقدار true برگردونه باید مثلا 5 بار بهش غذا بدیم و 2 بار باهاش بازی کنیم که تقسیم 5 بر 2 میشه 2.5 پس خرسمون خوشحال میشه. البته من کمترین تعداد رو گفتم شما ممکنه هر عدد دیگه ای که تقسیمشون به هم میشه بین 2 تا 2.5 رو بتونید مثال بزنید ولی اون موقع باید هی کلیک کنید روی اون دکمه های چنگال و توپ تا خرس خوشحال بشه.
خب حالا خرس رو خوشحال کردیم ولی هنوز یه مرحله دیگه هست تا اینکه رمز عبور رو نشون بده به ما اونم اینه که تابع isEcstatic مقدار true برگردونه که خب یعنی خرس هیجان زده شده.
خب بریم سراغ غول مرحله آخر. ببینیم چه زمانی خرس هیجان زده میشه.
خب ما میریم و تابع isEcstatic رو توی کد پیدا میکنیم و میبینیم که توش همچین کدی زده شده. خب توی عکس ببینید:
خب همونطور که میبینید این تابع اول میاد و تابع getState رو با مقادیر mass و happy و clean فراخوانی میکنه و مقادیر بازگشتی رو میریزه توی سه تا متغیر state1,stat2,state3 بعد میاد بررسی میکنه میگه اگه اولی 72 بود، دومی 30 و سومی 0 بود مقدار true رو برگردون. خب این mass و happy و clean آشنا نیست براتون؟؟ توی عکسای قبلی که فایل preferences رو باز کردم اینا هم بود حالا دوباره هم عکسشو میزارم که متوجه بشید اینا چی بودن.
همونطور که دوباره میبینید، اون فلش قرمزا مقادیر اینارو مشخص کرده. خب الان میفهمیم که این تابع getState میاد و این مقادیر رو از توی فایل میخونه و مقدارش رو توی اون متغیرهای state1-3 ذخیره میکنه. خب پس ما فهمیدیم که اینا باید مقادیرشون 72 و 30 و 0 باشه تا خرس هیجان زده بشه. حالا چجور مقادیر اینا رو بفهمیم که از کجا تعیین میشه؟؟ خب mass یعنی اینکه خرسمون چقدر حجیم تر شده. Happy هم یعنی چقدر خوشحاله و Clean هم یعنی چقدر تمیزه.
حالا بیایم یه دور کد رو بچرخیم ببینیم این کلمات کجا استفاده شده.
خب من سه تا تابع پیدا کردم که این کلمات توش وجود داشت که عکسشونو کنار هم گذاشتم.
غذا دادن: 10 واحد به mass اضافه میشه، 2 واحد به happy اضافه میشه، 1 واحد از تمیزیش کم میشه.
بازی کردن: 2 تا واحد از mass کم میشه البته طبیعی هم هست چون وقتی بازی میکنه وزنش کم میشه- 4 واحد به happy اضافه میشه- 1 واحد هم از تمیزیش کم میشه
نظافت کردن: تغییری توی mass نمیکنه،1 واحد از خوشحالیش(happy) کم میشه، 6 واحد به تمیزیش(clean) اضافه میشه
خب ببینید: توی تابع feed که غذا به خرس میدیم وقتی که میاد و یه f به ته اون رشته اضافه میکنه ، بعدش میاد و از سه تا تابع استفاده میکنه که یکیش changeMass ، changeHappy و changeClean هست رو با مقادیر 10، 2 ، 0 فراخوانی میکنه. این یعنی چی؟؟ اینجا یعنی اینکه وقتی شما به خرس غذا میدید، 10 واحد به حجمش اضافه میشه(mass)، 2 واحد به خوشحالیش اضافه میشه(happy) و 1 واحد از تمیزیش کم میشه(clean) و همین روال برای اون دوتا تابع بازی و نظافت هم هست. خب پس اینجا میفهمیم که بار هر بار بازی کردن و غذا دادن و تمیز کردن این سه تا مقدار چه جوری تغییر میکنن.
خب حالا باید ما بفهمیم که چند بار باید به خرس غذا بدیم و بازی کنیم باهاش و تمیزش کنیم تا این مقادیر بشه اون عددهای 72 و 30 و 0 که توی تابع هیجان یا همون isEcstatic بود. چه جوری بفهمیم؟؟ خیلی ساده باید یه معادله طرح کنیم 3 معادله 3 مجهول. اینجاس که شما میفهمید ریاضی دبیرستان چقدر میتونه تو زندگی بهتون کمک کنه 😀
خب بیایم مساله خردش کنیم. من توی این جدول مقادیر چیزهایی که میدونیم رو مرتب نوشتم و اون اخرین سطر هم مشخص کردم که هدفمون چیه
خب الان معادله اینجوری میشه:
10f-2p+0c=72 2f+4p-1c=30 -1f-1p+6c=0
خب الان سه تا معادله داریم با سه تا مجهول که باید حلش کنیم. اینجا دیگه حوصله ندارم توضیح بدم چه جوری حلش کنید. چون خودمم یادم رفته بود رفتم خوندم در موردش فهمیدم. و درنهایت داریم f=8 , p=4, c=2
خب این یعنی اینکه اگه ما 8 بار به خرس غذا بدیم، 4 بار باهاش بازی کنیم و 2 بار تمیزش کنیم خرس خوشحال و هیجان زده میشه و پرچم رو به ما نشون میده. چرا خوشحال میشه؟؟ چون تابع ishappy میومد f رو تقسیم به p میکرد و مقدارش اگه بین 2 تا 2.5 بود میگفت خوشحاله که خب اینجا 8 تقسیم بر 4 میشه 2 پس خرس خوشحال میشه و از اون طرف هم مقادیر mass و happy و clean هم به ترتیب 72 و 30 و 0 میشن.
خب برا اثبات حرفمون یه دونه خرس جدید باید بسازیم چونکه اطلاعات خرس قبلیم ذخیره شده و باید از اول یکی بسازیم. ما یه دونه جدید میسازیم 8 بار روی دکمه چنگال قاشق میزنیم، 4 بار روی دکمه توپ و 2 بار هم روی دکمه جارو و خرس رمز رو به ما نشون میده.
خب همونطور که میبینید رمز رو نشون داد و برامون رقصید.
رمز:th4t_was_be4rly_a_chall3nge@flare-on.com
Hook کردن توابع با استفاده از Frida
الان دیگه کارمون تموم شده ولی من میخوام یه راه دیگه هم بگم و البته یه تکنیک بهتون یاد بدم برا تزریق کد توی برنامه های اندرویدی. این قسمت دیگه خوندنش دلبخواهیه هرکی علاقه داره بخونه وگرنه سوال حل شد و تمام.
خب حالا ما تمام این کارا رو کردیم و به نتیجه رسیدیم. توی قسمت آخر، ما مجبور شدیم که خودمون بیایم و روی اون دکمه های بازی کلیک کنیم تا بتونیم خرس رو هیجان زده کنیم. حالا خب اینجا کار سختی نکردیم و فقط کلیلک کردن روی چندتا دکمه بود. ولی شما فرض کنید دارید یه بدافزار اندرویدی رو آنالیز میکنید که اصلا چیزی به عنوان UI نداره و هیچ محیطی نداره موقع اجرا که شما بتونید روی چیزی کلیک کنید و میخواین که رفتار اون برنامه رو بفهمید زمانی که مثلا یه تابع خاص اجرا میشه.
فرض کنید من یه بدافزار اندرویدی دارم که یه تابعی با نام X داخلش وجود داره. این تابع تحت یه شرایط خاصی اتفاق میافته مثلا توی یه روز و تاریخ خاص و ساعت خاص اون تابع اجرا میشه. خب فرض کنید ما میخوایم اون تابع را اجرا کنیم ببینیم که چه خروجیای به ما میده. خب نمیتونیم منتظر بشینیم که تاریخ و ساعت بشه اون روزی که مد نظر بدافزار هست. فرض کنید که بدافزار میاد و تاریخ و ساعت رو از اینترنت میگیره و چک میکنه اگه که اون تاریخ مثلا توی سال 2020 بود و ساعت 12 شب بود، اونموقع اون تابع X رو اجرا کن. خب اینجوری ما نمیتونیم حتی با عوض کردن تاریخ و ساعت گوشی و شبیه ساز، این تابع رو مجبور به اجرا کنیم چونکه داره زمان رو از اینترنت میگیره. خب حالا چیکار باید بکنیم و چه جوری مجبور کنیم تابع اجرا بشه؟؟
خب یه کار جالبی اومدن انجام دادن و یه ابزاری نوشتن به نام Frida که این میاد و کد مورد نظر شما رو توی برنامه مورد هدف تزریق میکنه در حین اجرا. خیلی کارش قشنگه.
من خودم راه کار اولی که خدمتتون توضیح دادم رو رفتم ولی یه جایی خوندم یه نفر اومده بود این مرحله رو با Frida حل کرده بود. گفته بود یه مدته دلم برا Frida تنگ شده میخوام با Frida حلش کنم. من حقیقتا لذت بردم وقتی راهشو خوندم و دلم نیومد براتون نذارم.
خب قبلش چندتا چیز باید بهتون یاد بدم که بتونید با گوشی اندرویدی و یا شبیه ساز اندرویدی از طریق کامپیوتر ارتباط برقرار کنید.
خب اول میخوام در مورد پروتکل ADB براتون بگم:
خب ADB مخفف Android Debug Bridge هست. یعنی یه پل ارتباطی بین گوشی و کامپیوتر، برای برنامه نویسای اندروید. یعنی چی؟ یعنی اینکه فرض کنید یه برنامه نویس اندروید میاد و میخواد مثلا یه بازی برای اندروید بسازه. میاد و کد میزنه توی ویندوز و حالا میخواد کدش رو توی اندروید تست کنه. اگه این برنامه نویس بخواد هر بار فایل بازیش رو هی بفرسته رو گوشی تست کنه و بعد بیاد دوباره تغییر بده و دوباره بفرسته روی گوشی خب خیلی سخت میشه براش. به همین خاطر برا راحتی کار برنامه نویس، گوگل اومده و یه پروتکل ساخته به نام ADB برای ارتباط بین کامپیوتر و گوشی که برنامه نویس بتونه راحت با گوشی ارتباط بگیره و برنامشو تست کنه. البته هدف از این پروتکل فقط برای برنامه نویس نیست. کلا شما میتونید کنترل گوشیتون رو توسط این پروتکل به دست بگیرید، فایل بریزید، فایل بردارید، نصب کنید، گوشی رو فلش کنید و ….
این ADB صرفا به شما یه شل لینوکسی میده که میتونید از طریق دستورات لینوکس با گوشی کار کنید.
خب حالا شما میتونید adb رو از اینترنت از سایت خود اندروید، دانلود کنید ولی اگه NOX رو نصب کرده باشید توی محلی که NOX نصب شده، adb هم موجوده. خب مثلا من میرم داخل دایرکتوری که NOX رو نصب کردم و از اونجا یه cmd باز میکنم و بهتون میگم که چه جوری به گوشیتون یا شبیه ساز وصل بشید.
اولین کاری که باید بکنید اینه که توی شبیه ساز یا گوشیتون وارد تنظیمات بشید و DeveloperOption رو فعال کنید. برا این کار من توی تنظیمات شبیه ساز و توی قسمت About Phone گزینه Buildnumber رو روش 5 بار یا 7 بار پشت سر هم کلیک میکنم و بعد یه پیغام میده که now you are a developerخب حالا برگردید توی تنظیمات و میبینید که یه گزینه اضافه شده به نام Developer Options. روی این کلیک میکنید و توی این قسمت گزینه USB debugging رو فعال میکنید.
خب حالا میتونید از سیستم به شبیه ساز وصل بشید.
خب من یه نکته بگم: شما وقتی میخواین روی گوشی خودتون این پروتکل رو اجرا کنید گوشیتون باید از طریق کابل وصل باشه. ولی وقتی ما الان از شبیه ساز استفاده میکنیم کابلی در کار نیست و باید از طریق شبکه به شبیه ساز وصل بشیم. نکته مهم اینه که پروتکل ADB روی شبیه ساز NOX روی پورت 62001 کار میکنه.
خب حالا توی عکس میبینید که به ترتیب من چه دستوراتی رو زدم. شما هم همین دستورات رو بزنید.
خب حالا ما وصل شدیم به شبیه ساز. ابتدا با دستور adb connect و سپس دستور adb devices رو که زدیم لیست گوشی هایی که به سیستم وصل هست رو به ما نشون داده که اینجا به ما ادرس آی پی خودمون رو به عنوان یه دستگاه شناسایی کرده چون شبیه ساز استفاده میکنیم ولی اگه گوشی خودتون باشه اینجا مدل گوشیتون رو میزنه.
خب حالا توی اخرین خط میبینید که با دستور adb shell تونستیم یه شل لینوکسی روی شبیه ساز با دسترسی روت داشته باشیم. شبیه ساز به صورت پیش فرض روت هست ولی شما توی گوشیتون لازم نیاز نیست روت باشید چون گوشی ها به خاطر مسایل امنیتی، دسترسی روت رو غیر فعال کردن.
خب دوستانی که لینوکس بلدن دیگه میتونن اینجا با زدن دستورات شل، از گوشی اطلاعات بگیرن و اینا که البته این قسمت کار توی مبحث ما جایی نداره.
خب برگردیم سراغ Frida برای نصب Frida شما باید python 2.7 رو روی سیستمتون نصب داشته باشید. چونکه Frida یک پیکیج پایتونی هست.
خب حالا ما پایتون رو داریم و میخوایم که Frida رو روی سیستممون نصب کنیم. میریم توی مسیری که پایتون نصب شده، توی دایرکتوری scripts و از اونجا با دستور pip که مدیریت پکیج ها رو توی پایتون انجام میده، Frida رو دانلود میکنیم و نصب میکنیم. البته همه این کارا کلا چهارتا کلمه بیشتر نیست:
اگر احیانا pip رو ندارید توی python از لینک میتونید نحوه نصبش رو یاد بگیرید.
خب خیلی راحت همنطور که میبینید ما Frida رو نصب کردیم. حالا من یه کم در مورد نحوه کار Frida براتون بگم و بعد بریم سراغ اینکه چجوری کد تزریق کنیم توی بازی.
ببینید شما برا اینکه بتونید با Frida کار کنید اول باید یه سرور مربوط به Frida رو روی گوشی یا شبیه ساز اجرا کنید. وقتی این سرور رو اجرا کردید، این سرور منتظر میمونه تا بهش دستور بدن. خب طبیعیه که ما از روی ویندوز نمیتونیم کد تزریق کنیم به صورت مستقیم روی گوشی اندروید، پس نیازه که اینجا یه واسط وجود داشته باشه. خب بعد اینکه این سرور اجرا شد روی گوشی و منتظر دستور شد، ما باید یه اسکریپت پایتون رو اجرا کنیم از روی سیستممون و این اسکریپت میاد و با سروری که روی شبیه ساز اجرا شده، ارتباط برقرار میکنه و توابعی که ما میخوایم کد داخلشون تزریق کنیم رو از یه فایل JavaScript میخونه و میفرسته برای سرور.
خب پس کلا ما باید اول فایل سرور مربوط به شبیه ساز رو روی گوشی بریزیم، بعد اجراش کنیم.
توی مرحله بعدی باید اسکریپت پایتونی که قراره با سرور ارتباط برقرار کنه رو اجرا کنیم که این اسکریپت توسط سایت خود Frida آماده هست و شما فقط باید دانلودش کنید و اجراش کنید. حالا شما باید توی یه فایل JavaScript، مشخص کنید که کدوم قسمت از برنامه و چه توابعی رو میخواین تغییر بدید. پس نیاز داریم تا یه ذره هم جاوا اسکریپت کد بزنیم. یه کم گیج کننده شد ولی برای اطلاعات بیشتر میتونید این لینک که برای خود Frida هست رو مطالعه کنید تا کاملتر متوجه بشید.
خب مرحله به مرحله میریم جلو تا کامل مشخص بشه چه خبره:
اولین مرحله دانلود فایل سرور مربوط به گوشی یا شبیه ساز:
برا این کار وارد گیت هاب Frida میشیم و از اونجا فایل مربوط به شبیه سازخودمون رو بسته به نوع پردازنده و معماری اون دانلود میکنیم. الان چه جوری بفهمیم مدل و معماری cpu گوشی یا شبیه ساز چیه ؟
با دستور زیر توی adb میتونید بفهمید:
خب همونطور که میبینید معماری شبیه ساز ما x86 هست که خب از لیست فایلهای توی گیت هاب اینو دانلود میکنیم. ممکنه برا گوشی ها فرق داشته باشه که شما باید با توجه به گوشی خودتون دانلودش کنید.
خب وقتی دانلودش کردیم، از زیپ خارجش میکنیم و حالا باید فایل رو بفرستیم توی گوشی. برا راحتی کار فایل رو من کپی میکنم کنار فایل adb توی همون جایی که NOX نصب شده بود که راحت بشه آدرسشو داد. حالا توی عکس زیر من از دستور push استفاده کردم برای ارسال فایل داخل گوشی.
توی عکس اگه دقت کنید، من adb push رو زدم بعدش اسم فایل سرور رو دادم که توی همون دایرکتوری هست و بعدش یه آدرس /data/local/tmp که این آدرس، آدرس یه دایرکتوری توی گوشی هست که شما میتونید داخلش فایل بریزید. اینجا تنها جاییه که میتونید توش فایل بریزید توی گوشی های اندروید. شما دسترسی به بقیه دایرکتوری ها رو ندارید توی گوشی چون روت نیستید. روال کپی و اجرا فایل سرور توی عکس مشخصه که البته همش دستورات لینوکسه.
خب اول فایل رو push کردیم داخل گوشی، بعد شل گرفتیم به شبیه ساز، رفتیم داخل اون دایرکتوری tmp و بعد مجوز اجرا دادیم به فایل، و بعد هم اجراش کردیم. به ترتیب شماره های داخل عکس، دستورات رو بزنید.
خب حالا سرور اجرا شده روی گوشی و منتظره که ما از سیستم بهش دستور بدیم.
مرحله دوم این بود که ما بیایم و اسکریپت پایتونی که قراره بیاد و کدهای مارو بفرسته سمت سرور برای تزریق رو آماده کنیم. خب این اسکریپت همونطور که گفتم قایل دانلود از اینجا هست که یه آموزش خوبی نوشته برا نحوه استفاده از Frida توی اندروید. من کدش رو اینجا اوردم و یه کوچولو تغییرش دادم، توضیح میدم براتون.
خب ببینید اینجا توی خط اول و دوم که اومدیم کتابخونه Frida و time رو اضافه کردیم. توی خط چهارم اومدیم تابع Frida.get_usb_devices رو اجرا کردیم، که این تابع لیست گوشی های متصل به سیستم رو برمیگردونه. بعد توی خط 6 هم اومدیم گفتیم که ما اسم برنامه ای که قراره توش کد تزریق کنیم com.fireeye.flarebear هست و بعدش هم Frida میاد وصل میشه به اون برنامه و اون اسکریپتی که اسمش رو توی خط 11 ام اوردیم که اسمش رو من گذاشتم hook.js که یه فایل جاوا اسکریپت هست، رو باز میکنه و از اونجا میفهمه که چه کدهایی باید تزریق کنه.
خب این فایل رو من با اسم fr.py توی پوشه ای که پایتون نصب شده ذخیره کردم. و این فایل چیزیه که ما باید اجراش کنیم.
حالا بیام بهتون در مورد قسمت اصلی کار یعنی، کد جاوا اسکریپتی که باید بنویسیم توضیح بدم و اینکه بگم چیکار باید بکنیم.
ما فهمیدیم که اگه تابع، isHappy مقدار true برگردونه و بعدش هم تابع isEcstatic مقدار true برگردونه، خرس شروع میکنه به رقصیدن و رمز عبور رو نشون میده به ما.
بعد اومدیم گفتیم برا اینکه این دوتا تابع true بشن، اون معادله رو طرح کردیم و حل کردیم و عددهای میزان بازی و غذا خوردن و نظافت رو پیدا کردیم.
خب حالا فرض کنید که این دوتا تابع رو یه جوری دستکاری کنیم که بدون چک کردن مقادیر f,p,c ، بیان و همیشه true برگردونن. یعنی اصلا این دوتا تابع بدون هیچ کاری فقط یه دستور return true رو داشته باشن. خب این اتفاق وقتی بیافته دیگه نیاز نیست که شما روی دکمه های چنگال و اینا کلیک کنید، چون عملا اینا دیگه توی این دوتا تابع اصلا حساب نمیشن و این دوتا تابع تحت هر شرایطی، true برمیگردونن.
امیدوارم متوجه شده باشین چی گفتم ولی اگه سوالی براتون پیش اومده حتما بپرسید من پاسخ میدم.
خب حالا توی اون کد جاوا اسکریپت، باید بیایم به Frida بگیم که ما دوتا تابع داریم به اسم های isHappy و isEcstatic که میخوایم تو برامون، اینارو تغییر بدی جوری که همیشه true برگردونن.
خب نحوه نوشتن دستوراتش توی کد اینجوریه که خب اگه داکیومنت خود Frida رو بخونید متوجه میشید.
خب ببینید خط به خط میخوام توضیح بدم که این اسکریپت چیه دقیقا. ببینید اولش که ما اومدیم و یه تابع ساختیم اسمش رو هم گذاشتیم function که خب اینو توی خود سایت Frida به این صورت نوشتن. بعد توی خط 5 ام که با فلش مشخصه اومدم اسم کلاس مربوط به کد بازی رو گذاشتم. اگه یادتون نمیاد اینو از کجا اوردم، برید و اول پست رو دوباره بخونید که توضیح دادم توی jadx این کلاس، کلاس اصلی برنامه خرس هست. و اینجا به Frida میگیم که ما میخوایم داخل این کلاس کد تزریق کنیم. بعد اومدیم توی خط 7 دقیقا عین اسم تابع isEcstatic رو اوردیم، که Frida بفهمه کدوم تابع از اون کلاس رو باید تغییر بده. حواستون باشه عین اسم رو باید بنویسید. و در ادامه گفتیم این تابع فقط یه کار میکنه اونم return true هست. اون خطوطی که میبینید نوشته console.log ، اینا چیز خاصی نیس اینا فقط برا اینه که بتونه توی کنسول برامون لاگ بندازه. بعد اومدیم توی خط 13 ام دوباره گفتیم که ما یه تابعی هم داریم به اسم isHappy که اونم فقط میخوایم یه کار کنه اونم return true هست. خب همه چی واضحه. بعد هم در اخر اومدیم تابع getStat که خودش میومد حساب میکرد برامون مقادیر f,p,c رو، کدش رو تغییر دادیم و گفتیم هر وقت این اجرا شد، اگه ورودیش f بود، عدد 8 ، اگه p بود 4 و اگه c بود 2 رو برگردون. که خب این عددهارو از معادله به دست اوردیم. خب اسن کد رو هم به اسم hook.js کنار همون اسکریپت پایتون قرار میدیم.
حالا اماده ایم تا استارت Frida رو بزنیم. همه چی امادست. سرور که روی شبیه ساز همچنان منتظره، و فایل ها هم اماده شدن و فقط ما باید فایل اسکریپت پایتون رو اجرا کنیم.
خب همونطور که میبینید، فایل fr.py و hook.js رو گذاشتم توی دایرکتوری پایتون.
خب حالا میریم و بازی رو اجرا میکنیم. الان دیگه نیاز نیس مثه راه حل قبلی خرس جدید بسازیم، چونکه دیگه تابع getStat ما نمیره و اون رشته Activity رو بخونه. به خاطر اینکه الان کد جدید توی این تابع تزریق کردیم که همیشه عدد 8 و 4 و 2 برگردونه.
یادتون باشه قبل از اجرای اسکریپت حتما باید بازی رو اجرا کنید. چون Frida نمیتونه خودش حدس بزنه که بازی اجرا هست یا نیست.
خب همونجور که تو عکس میبینید ما بازی رو اجرا کردیم و بعدش هم اسکریپت رو اجرا کردیم. فقط یادتون باشه برا اینکه توابع به اصلاح trick بشن توی Frida شما باید یه دکمه همینجوری بزنید. مثلا روی توپ یه کلیک کنید.
خب امیدوارم با تمام تلاشی که کردم برا توضیح این مرحله و آموزش Frida تونسته باشم حق مطلبو ادا کنم. واقعا تلاشم این بود که با تکنیک های مختلف reverse فایلهای اندرویدی آشنا بشید و امیدوارم این کار رو تونسته باشم به خوبی انجام بدم.
منتظر چالش بعدی باشید.