HackTheBox Mobile Challenges (قسمت اول. Don't Overreact)

چالش Don't Overreact یک چالش دسته موبایل از HackTheBox است که به اهمیت تجزیه و تحلیل استاتیک اپلیکیشن ها اشاره می کند. اگر آسیب‌پذیری موجود در این چالش را با OWASP Mobile Top 10 مقایسه کنیم، در دسته Insecure Data Storage قرار می‌گیرد.


روش های زیادی برای انجام دادن این چالش وجود دارد که در ادامه، یکی از این روش ها را بررسی خواهیم کرد.

قدم اول:

در قدم اول، پس از دانلود فایل ها از HackTheBox فایل زیپ را extract می کنیم و می بینیم که این چالش تنها یک فایل apk دارد:

قدم دوم:

مهم ترین بخش عملیات Static Analysis اپلیکیشن ها، انجام عملیات مهندسی معکوس است. مهندسی معکوس به ما اجازه می دهد تا به Source Code های اپلیکیشن دست پیدا کنیم و به درک مناسبی از فرآیند برنامه برسیم. برای انجام مهندسی معکوس در اپلیکیشن های اندروید ابزار های زیادی موجود است که در اینجا از ابزار jadx-gui به دلیل سهولت کار با این ابزار استفاده می کنیم. با استفاده از open file فایل apk مورد نظر را انتخاب می کنیم:

اکنون به تجزیه و تحلیل کد های java می پردازیم:

در کد buildconfig چیزی که ما را به فلگ برساند وجود ندارد.

بیایید به کد MainActivity نگاهی بیندازیم:

این کد یک کلاس جاوا اندروید است که ReactActivity را که بخشی از چارچوب React Native است گسترش می دهد. React Native به توسعه دهندگان اجازه می دهد تا برنامه های تلفن همراه را با استفاده از جاوا اسکریپت و React بسازند، در حالی که بخش های اصلی برنامه به زبان جاوا (برای اندروید) یا Objective-C/Swift (برای iOS) نوشته شده است.

1- کد در پکیج com.wesomeproject قرار داده شده است. کلاس ReactActivity را از پکیج com.facebook.react وارد می کند. ReactActivity یک کلاس از پیش ساخته شده توسط چارچوب React Native است که به عنوان Base Activity برای برنامه React Native عمل می کند:

package com.awesomeproject;
import com.facebook.react.ReactActivity;

2- ین خط کلاس MainActivity را تعریف می کند که کلاس ReactActivity را گسترش می دهد. با گسترش ReactActivity، این کلاس عملکردی را به ارث می برد که آن را قادر می سازد یک برنامه React Native را اجرا کند:

public class MainActivity extends ReactActivity {

3- متدهای override شده:

@Override
protected String getMainComponentName() {
return &quotAwesomeProject&quot
}

این کد متد ()getMainComponentName را از کلاس ReactActivity لغو یا override می کند. هدف از این متد تعیین نام جزء اصلی برنامه React Native است. در این مورد، جزء اصلی "AwesomeProject" است.

مولفه Main component ریشه کل برنامه React Native است. این نقطه شروعی است که کد جاوا اسکریپت در آن اجرا می شود و معمولا نمای سطح بالای برنامه یا صفحه نمایش را نشان می دهد.

با برگرداندن «AwesomeProject»، این کلاس MainActivity نشان می‌دهد که مؤلفه اصلی این برنامه در فایل جاوا اسکریپت با همین نام، یعنی AwesomeProject.js تعریف شده است.

به طور خلاصه، این کد یک کلاس جاوا اندروید است که به عنوان entry point برای یک برنامه React Native به نام "AwesomeProject" عمل می کند. جزء اصلی برنامه در فایل جاوا اسکریپت با نام "AwesomeProject.js" تعریف شده است.

اکنون بیایید نگاهی به کد MainApplication بیندازیم:

این کد تعریف کلاس MainApplication در پروژه جاوا اندروید برای یک برنامه React Native است. بیایید گام به گام کد را مرور کنیم:

1- این کد در پکیج com.wesomeproject قرار می گیرد و شامل دستورات import کتابخانه های ضروری برای کلاس های مختلف اندروید و React Native است:

package com.awesomeproject;
import android.app.Application;
import android.content.Context;
import com.facebook.react.PackageList;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.soloader.SoLoader;
import java.util.List;

2- این خط، کلاس MainApplication را تعریف می کند که کلاس Android Application را گسترش می دهد و رابط ReactApplication را پیاده سازی می کند. با پیاده سازی رابط ReactApplication، این کلاس نشان می دهد که به عنوان کلاس برنامه اصلی برای برنامه React Native عمل می کند:

public class MainApplication extends Application implements ReactApplication {

3- این بلوک کد نمونه ای از ReactNativeHost را ایجاد می کند که کلاسی است که توسط React Native برای کنترل مقدار دهی اولیه و پیکربندی React Native Runtime ارائه می شود. این پل ارتباطی بین کد اصلی اندروید و کد جاوا اسکریپت در برنامه React Native است:

private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
// ...
};

در اینجا 3 متد override می شود:

getJSMainModuleName():

این متد، نام فایل اصلی جاوا اسکریپت را در پروژه React Native مشخص می کند. در این مورد، "index" است، به این معنی که نام entry point اصلی index.js است.

protected String getJSMainModuleName() {
return &quotindex&quot
}

getUseDeveloperSupport():

این متد نشان می دهد که آیا developer mode برای برنامه React Native فعال شود یا خیر. مقدار false را برمی‌گرداند، بنابراین developer support (مانند گزینه های debugging) غیرفعال است.

public boolean getUseDeveloperSupport() {
return false;
}

getPackages():

این متد لیست پکیج های React Native را که باید در برنامه load شوند، بازیابی می کند. کلاس PackageList برای به دست آوردن این بسته ها استفاده می شود و آنها را بر اساس پیکربندی که در فایل android/app/build.gradle موجود است را fetch می کند.

protected List<ReactPackage> getPackages() {
return new PackageList(this).getPackages();
}

4- کد زیر یک متد خالی است و در برنامه هیچ استفاده ای از آن نشده:

private static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
// Empty method body
}

5- این دو متد متدهای مربوطه تعریف شده در کلاس های ReactApplication و Application را override می کنند:

@Override
public ReactNativeHost getReactNativeHost() {
return this.mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
SoLoader.init((Context) this, false);
initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
}

getReactNativeHost():

این متد نمونه ReactNativeHost را که قبلا ایجاد شده بود برمی گرداند. این به سایر اجزای برنامه اجازه می دهد تا به نمونه ReactNativeHost دسترسی داشته باشند.

onCreate():

این متد بخشی از lifecycle برنامه اندروید است و به طور خودکار هنگام شروع برنامه فراخوانی می شود. در این روش SoLoader مقداردهی اولیه می شود که یک بارگذار کتابخانه بومی است که توسط React Native استفاده می شود. این مسئول بارگیری کتابخانه های بومی مورد نیاز در React Native runtime است. علاوه بر این، متد ()initializeFlipper (که همانطور که قبلاً ذکر شد در این مورد خالی است) فراخوانی می شود، اگرچه هیچ تأثیر عملکردی در کد ارائه شده ندارد.

به طور خلاصه، این کد کلاس MainApplication را برای یک برنامه اندروید React Native تعریف می کند. ReactNativeHost را راه‌اندازی می‌کند، پیکربندی‌های لازم را فراهم می‌کند و SoLoader را برای React Native runtime مقداردهی اولیه می‌کند. کلاس MainApplication به عنوان entry point اصلی برای بخش React Native از برنامه عمل می کند و امکان ادغام یکپارچه React Native با کد اصلی اندروید را فراهم می کند.

اما نکته ای که در همان ابتدای تحلیل کد MainActivity می توانست ما را به flag نزدیک کند این است برنامه های React Native در اندروید از کد های JavaScript پیروی می کنند و در نتیجه متوجه می شویم که کد های اصلی اپلیکیشن، کد های جاوا نیستند?

در واقع کد های JavaScript اصلی در Bundle و در زیر مجموعه Resources/assets که در فایل index.android.bundle ذخیره شده اند قرار دارد.

با بررسی این فایل می بینیم که این کد یک API را call می کند که احتمال می دهیم این ما را به flag برساند:


با decode کردن این کد base 64 به نتیجه جالبی می رسیم:

این هم از فلگ ?

منتظر نظرات و انتقادات شما هستم

در قسمت های بعدی، به بررسی سایر چالش های موبایل در HackTheBox خواهیم پرداخت ??