Seperti yang sudah ada dideskripsi challenge nya, untuk menyelesaikan challenge ini kita perlu untuk membuat malicious/exploit aplikasi sendiri yang dimana nanti akan diinstall di Virtual Android Device dari TCP1P.
Sebelum kita membuat malicious code atau exploitnya, penting bagi kita untuk memahami aplikasi internals ini secara mendalam. Langkah pertama yang krusial adalah menganalisis aplikasi tersebut dengan menggunakan tools decompiler. Decompiler ini memungkinkan kita untuk membuka aplikasi “challenge” menjadi source code yang dapat kita baca dan pahami. Saya pribadi menggunakan tools decompiler dari jadx untuk melakukan ini.
Cara menggunakan jadx:
Buka exe dari jadx yang sudah didownload, dan akan menampilkan seperti gambar berikut ini.
Kita klik tombol Open file dan kemudian cari .apk challenge yang sudah didownload oleh teman teman.
Setelah itu jadx akan menalisis nya dan mendecompile apk tersebut agar dapat kita baca, beriku ini hasil decompile dari jadx.
Cari nama package dari aplikasi challenge terlebih dahulu, untuk mengetahui nama package dari aplikasi ini adalah dengan melihat code dari file AndroidManifest.xml terlebih dahulu, yang didapatkan dari isi dari Resources -> AndroidManifest.xml.
Buka file AndroidManifest.xml nya dan cari kata MainActivity, karena biasanya developer android menggunakan MainActivity sebagai class utama dari aplikasi mereka.
Dalam contoh kasus ini nama package dari aplikasi ini adalah com.kuro.internals.
Setelah mendapatkan nama package dari aplikasi nya, kita bisa melihat source code dari aplikasinya lewat jadx yang ada pada Source code -> [nama package dari aplikasi] contohnya Source Code -> com.kuro.internals.
Diberikan challenge dengan nama Internals dengan deskripsi sebagai berikut:
Deskripsi Challenge
Let’s see how well your knowledge about android internals. Using any type of external library will deduct your points by half.
Hint :
You do know android is open source right? Then it’s time to read the source code! Especially on getPackageName.
Do some OSINT on the author’s repositories, maybe you’ll find an interesting project.
Dari deskripsi yang diberikan terlihat kita dichallenge oleh pembuat soal terkait knowledge kita tentang andoir internals, dan pembuat soal juga melarang kita untuk menggunakan library external untuk melakukan exploit nya, kalaupun kita menggunakan library external kita akan mendapatkan pengurangan point.
Sekarang coba kita install dan buka terlebih dahulu aplikasi challenge ini dan melihat bagaimana tampilan nya.
Terlihat aplikasi ini meminta url yang akan mendownload payload.dex dan akan meload dex nya.
Static analys
Oke setelah membaca deskripsi dan isi aplikasi dari soal kita perlu untuk melihat terlebih dahulu source code dari aplikasi internals ini, dan didpatkan satu activity yaitu MainActivity saja: Dengan isi dari activitynya sebagai berikut:
Bisa dilihat bahwa aplikasi menggunakan layout activity_main yang bisa didapatkan di jadx didalam folder Resources/res/layout/activity_main.xml, aplikasi ini juga mempunyai 1 button dan 1 EditText. Jadi simplenya ketika user sudah memasukan url kedalam box dan menekan button nya maka aplikasi akan mengambil url tersebut dan melemparkannya ke fungsi downloadDex, jika user tidak memasukan url kedalam box maka akan memunculkan popup URL cannot be empty!.
downloadDex
Pada fungsi downloadDex bisa dilihat bahwa aplikasi akan memunculkan dialog Downloading... dan akan melemparkannya ke fungsi AnonymousClass2.
Setelah membaca source code dari fungsi AnonymousClass2 bisa dilihat bahwa dia mencoba untuk mendownload file dex dari url yang kita berikan dan menyimpannya dengan nama file payload.dex yang kemudian akan dialihkan ke fungsi loadDex().
Create a malicious app
Dan disinilah bagian menariknya muncul dan bagaimana kita akan membuat malicious dex nya. Yang dimana dalam fungsi ini dia mengecheck terlebih dahulu apakah ada file payload.dex didalam folder files aplikasi kita, perlu dinote setiap file yang diload oleh android studio itu ada pada folder /data/data/[nama package apk]/files, jadi dalam kode ini aplikasi challenge akan mengecheck terlebih dahulu apakah file payload.dex itu ada atau tidak didalam folder files kita.
Selanjutnya ketika file payload.dex itu ada didalam folder files, payload.dex akan diload dengan DexClassLoader yang nantinya akan dicheck dengan menggunakan Reflection untuk meload class didalam file dex nya, yang dimana dikode ini aplikasi challenge berusaha untuk meload class dari package com.kuro.payload dengan nama class Main dan juga dia mengambil method dari execute untuk dijalankan diaplikasi challenge, setelah berhasil loadClass dari payload.dex dia akan mengecheck nama package dari aplikasi challenge yang dimana saat ini masihlah com.kuro.internals sudah berubah ke nama package baru atau tidak yaitu l33t_h4x0r, ketika kondisi ini terpenuhi aplikasi akan menampilkan flag nya.
Setelah berhasil memahami bagaimana alur dari aplikasi ini berjalan, penulis sudah mempunya gambaran tentang bagaimana membuat malicious dex nya agar ketika dex yang penulis buat nanti bisa merubah packageName dari aplikasi challenge dari com.kuro.internals ke l33t_h4x0r.
Dari hint yang diberikan oleh pembuat soal, pembuat soal meminta kita untuk melakukan osint digithub akunnya dia.
Akhirnya penulis menemukan akun githubnya dan menemukan repository yang menarik didalamnya yaitu APKKiller , didalam repository ini pembuat soal memberitahukan bahwa dengan menggunakan Reflection kita bisa membaca dan memodifikasi internal classes dan fields nya.
Setelah membaca dan melakukan trial and error tentang Reflection penulis menemukan cara bahwa kita bisa menggunakan class dari ActivityThread untuk mengubah packageName ke packageName yang kita mau.
Cobalah untuk membuat projek baru di Android Studio dengan setup sebagai berikut:
Pilih Empty Views Activity lalu Next.
Buatlah nama terserah kalian, asalkan nama package nya itu com.kuro.payload karena pada aplikasi challenge package ini yang akan di load, lalu pilihlah Java sebagai bahasa pemrogramannya, karena Reflection bisa kita pakai di java.
Setelah itu klik Finish dan tunggu sampai android studio menyiapkan setupnya.
Setelah semuanya sudah selesai, kita buat class baru dengan nama Main karena aplikasi challenge akan meload class dari package kita dengan nama Main dengan klik kanan pada package com.kuro.payload lalu klik New -> Java Class.
Masukan nama Main dan enter.
Kita akan memakai activity MainActivity terlebih dahulu untuk debugging.
Jadi step pertama adalah cari terlebih dahulu field dari packageName dan kemudian baru kita set ke value yang baru
Coba gunakan kodingan diatas dan jalankan, lalu coba untuk melihat logcat nya karena saya memasukan Log.e disitu untuk debugging dan melihat isi field dari ActivityThread.
Dan didapatlah isi field dari class ActivityThread.
Seperti yang diberikan hint oleh pembuat soal bahwa getPackageName itu terdapat pada mPackageInfo.
Setelah menghabiskan banyak waktu disini, akhirnya saya menemukan bahwa didalam fields mBoundApplication terdapat field info
@Override protectedvoidonCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); try { // Get the current ActivityThread instance Class<?> activityThreadClass = Class.forName("android.app.ActivityThread"); MethodcurrentActivityThread= activityThreadClass.getDeclaredMethod("currentActivityThread"); currentActivityThread.setAccessible(true); ObjectactivityThread= currentActivityThread.invoke(null);
// Get the loaded package info FieldmBoundApplicationField= activityThreadClass.getDeclaredField("mBoundApplication"); mBoundApplicationField.setAccessible(true); ObjectmBoundApplication= mBoundApplicationField.get(activityThread);
// Set the new package name FieldpackageNameField= loadedApkInfo.getClass().getDeclaredField("mPackageName"); packageNameField.setAccessible(true); packageNameField.set(loadedApkInfo, "l33t_h4x0r");
try { // Get the current ActivityThread instance Class<?> activityThreadClass = Class.forName("android.app.ActivityThread"); MethodcurrentActivityThread= activityThreadClass.getDeclaredMethod("currentActivityThread"); currentActivityThread.setAccessible(true); ObjectactivityThread= currentActivityThread.invoke(null);
// Get the loaded package info FieldmBoundApplicationField= activityThreadClass.getDeclaredField("mBoundApplication"); mBoundApplicationField.setAccessible(true); ObjectmBoundApplication= mBoundApplicationField.get(activityThread);
// Set the new package name FieldpackageNameField= loadedApkInfo.getClass().getDeclaredField("mPackageName"); packageNameField.setAccessible(true); packageNameField.set(loadedApkInfo, "l33t_h4x0r"); } catch (Exception e) { e.printStackTrace(); }
} }
Setelah itu set gradle nya agar ketika dibuild classes.dex nya itu hanya satu dan tidak multiple dengan menambahkan config sebagai berikut:
Setelah itu kita build projek ini.
Akan muncul popup di pojok kanan bawah seperti berikut ini.
Klik locate dan akan diarahkan ke folder apk yang sudah dibuild:
Masuk kedalam folder debug.
Dan app-debug.apk ini adalah hasil compile kita tadi, setelahnya kita buka apk ini di jadx untuk kita ambil classes.dex nya dan kita pakai di aplikasi challenge.
folder apk hasil compile ada di <Nama Folder Projek>\app\build\outputs\apk\debug.
Setelah dibuka dengan jadx, kita save all hasil decompile ini dan masukan kedalam sebuah folder, saya sendiri memasukannya ke folder kelasss.
Setelah itu kita copy classes.dex nya yang terdapat di folder kelasss/resources/classes.dex ke folder yang lain untuk bisa kita transfer ke aplikasi challenge.
Saya memasukannya di folder internals saja dan saya rubah namanya ke payload.dex dan menjalankan http.server dan ngrok, setelah itu tinggal masukan url nya ke box dan exploit kita berhasil untuk mendapatkan flagnya.
Tinggal dijalankan di Virtual Android Device dan didapatkan flagnya: