Post

[FridaLab] All Challenges Walktrough

Setelah sebelumnya kita mempelajari Frida menggunakan aplikasi Frida-Labs karya DERE-ad2001, pada kesempatan ini kita akan mengasah kemampuan Frida lebih lanjut dengan menyelesaikan soal CTF dari aplikasi FridaLab karya Ross Marks.

Sebelum melihat walkthrough ini, saya sangat menyarankan kamu untuk mencoba menyelesaikan soal tersebut terlebih dahulu menggunakan keterampilan yang telah kita pelajari sebelumnya.

0x1 - Prerequisites

  • Dasar reverse engineering menggunakan JADX.
  • Kemampuan untuk memahami kode Java.
  • Kemampuan untuk menulis kode Javascript.
  • Familiar dengan ADB.
  • Perangkat Android yang sudah di-root.
  • Familiar dengan Frida.

0x2 - FridaLab App

Mari kita unduh aplikasinya di sini, lalu instal dan jalankan.

Aplikasi FridaLab Aplikasi FridaLab

Pada aplikasi ini terdapat 8 tantangan yang harus kita selesaikan dan terdapat tombol CHECK. Jika kita klik tombol tersebut, maka semua soal tantangan akan menjadi berwarna merah.

Soal Tantangan Menjadi Warna Merah Soal Tantangan Menjadi Warna Merah

Jika kita analisis menggunakan JADX, ketika mengklik tombol CHECK, fungsi changeColors() dipanggil.

Fungsi Tombol CHECK Fungsi Tombol CHECK

Fungsi ini akan mengubah warna soal menjadi hijau jika nilai dari setiap indeks array completeArr bernilai 1, yang menandakan bahwa tantangan berhasil diselesaikan.

Urutan indeks array ini mencerminkan jawaban dari setiap tantangan. Indeks 0 untuk tantangan 1, indeks 1 untuk tantangan 2, dan seterusnya.

Fungsi changeColors() Fungsi changeColors()

Untuk menyelesaikan tantangan-tantangan ini, kita bisa mengubah nilai array completeArr menjadi 1 untuk setiap indeksnya. Mari kita coba.

Pertama kita cari tahu dulu identifier dari aplikasi ini. Diketahui identifier-nya adalah uk.rossmarks.fridalab.

Cek Identifier Aplikasi Cek Identifier Aplikasi

Jalankan aplikasinya menggunakan Frida.

1
➜ frida -U -f uk.rossmarks.fridalab

Gunakan script berikut untuk mengubah nilai array completeArr menjadi 1 disetiap indeksnya.

1
2
3
4
5
6
7
8
Java.performNow(function(){
    Java.choose('uk.rossmarks.fridalab.MainActivity', {
      onMatch: function(instance) {
        instance.completeArr.value = [1, 1, 1, 1, 1, 1, 1, 1];
      },
      onComplete: function() {}
    });
});

Berhasil Menyelesaikan Tantangan Aplikasi Berhasil Menyelesaikan Tantangan Aplikasi

Hasilnya, semua tantangan berubah menjadi hijau kecuali tantangan nomor 5. Hal ini disebabkan karena fungsi chall05() yang dipanggil ketika tombol CHECK ditekan menggunakan argumen yang membuat nilai array menjadi 0.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public void onClick(View view) {
    ...
	MainActivity.this.chall05("notfrida!");
	...
}

...
...

public void chall05(String str) {
	if (str.equals("frida")) {
		this.completeArr[4] = 1;
	} else {
		this.completeArr[4] = 0;
	}
}

Hahaha.. Meskipun kita berhasil menyelesaikan banyak tantangan dengan “curang”, kita akan mencoba menyelesaikan setiap tantangan sesuai keinginan Lab Maker.

0x3 - Change class challenge_01 variable ‘chall01’ to: 1

Dengan membaca soal dan menganalisis kode Java-nya, kita bisa mengetahui bahwa untuk menyelesaikan tantangan 1 ini, kita perlu mengubah nilai dari variabel statis chall1 pada class challenge_01 menjadi 1.

Kode Tantangan 1 Kode Tantangan 1

Class Challenge_01 Class Challenge_01

Untuk melakukan perubahan nilai pada variabel statis, kita bisa menggunakan konsep yang telah kita pelajari sebelumnya dalam seri Frida-Labs Challenge.

Berikut adalah template script yang akan kita gunakan:

1
2
3
4
5
6
Java.perform(function (){
 
    var <class_reference> = Java.use("<package_name>.<class>");
    <class_reference>.<variable>.value = <value>;

})

Lakukan penyesuaian dengan mengubah nilai variabel chall01 menjadi 1.

1
2
3
4
5
6
Java.perform(function (){
 
    var a = Java.use("uk.rossmarks.fridalab.challenge_01");
    a.chall01.value = 1;

})

Selanjutnya, jalankan script-nya dan tekan tombol CHECK. Terlihat bahwa kita berhasil menyelesaikan tantangan 1.

Berhasil Menyelesaikan Tantangan 1 Berhasil Menyelesaikan Tantangan 1

0x4 - Run chall02()

Untuk menyelesaikan tantangan 2, kita hanya perlu memanggil fungsi chall02().

Fungsi chall02() Fungsi chall02()

Untuk memanggil fungsi chall02() kita memerlukan akses ke class instance MainActivity.

Berikut adalah template script yang akan kita gunakan:

1
2
3
4
5
6
7
8
Java.performNow(function(){
    Java.choose('<Package>.<class_Name>', {
      onMatch: function(instance) {
        // TO DO//
      },
      onComplete: function() {}
    });
});

Mari kita sesuaikan dengan memanggil fungsi chall02().

1
2
3
4
5
6
7
8
Java.performNow(function(){
    Java.choose('uk.rossmarks.fridalab.MainActivity', {
      onMatch: function(instance) { //"instance" is the instance for the MainActivity
        instance.chall02(); //Calling the function
      },
      onComplete: function() {}
    });
});

Jalankan script tersebut dan kita akan berhasil menyelesaikan tantangan 2.

Berhasil Menyelesaikan Tantangan 2 Berhasil Menyelesaikan Tantangan 2

0x5 - Make chall03() return true

Untuk menyelesaikan tantangan 3, kita perlu mengubah nilai pengembalian dari fungsi chall03() menjadi true.

Fungsi chall03() Fungsi chall03()

Berikut adalah script yang akan kita gunakan:

1
2
3
4
5
6
7
8
Java.perform(function (){
 
  var a = Java.use("uk.rossmarks.fridalab.MainActivity");
  a.chall03.implementation = function() {
    return true;
  }

})

Kita tidak perlu mengaitkan ke class instance MainActivity terlebih dahulu, karena fungsi chall03() akan dipanggil ketika kita menekan tombol CHECK dan kita hanya perlu meng-hook dan mengubah nilai pengembaliannya saja.

Berhasil Menyelesaikan Tantangan 3 Berhasil Menyelesaikan Tantangan 3

0x6 - Send “frida” to chall04()

Untuk menyelesaikan tantangan 4, kita perlu memanggil fungsi chall04() dengan argumen string “frida”.

Fungsi chall04() Fungsi chall04()

Karena kita akan memanggil sebuah fungsi yang bukan statis, maka kita membutuhkan akses class instance MainActivity.

Berikut adalah script yang akan kita gunakan:

1
2
3
4
5
6
7
8
Java.performNow(function(){
    Java.choose('uk.rossmarks.fridalab.MainActivity', {
      onMatch: function(instance) { //"instance" is the instance for the MainActivity
        instance.chall04('frida'); //Calling the function with argument
      },
      onComplete: function() {}
    });
});

Jalankan script tersebut dan kita akan berhasil menyelesaikan tantangan 4.

Berhasil Menyelesaikan Tantangan 4 Berhasil Menyelesaikan Tantangan 4

0x7 - Always send “frida” to chall05()

Setiap kali kita menekan tombol CHECK, fungsi chall05() dengan argumen string “notfrida!” akan dipanggil.

Pemanggilan Funsi chall05() Pemanggilan Funsi chall05()

Untuk menyelesaikan tantangan ini, kita harus meng-hook fungsi chall05() dan mengubah nilai argumennya menjadi “frida”.

Fungsi chall05() Fungsi chall05()

Berikut adalah script yang akan kita gunakan:

1
2
3
4
5
6
7
8
Java.perform(function (){
 
  var a = Java.use("uk.rossmarks.fridalab.MainActivity");
  a.chall05.overload('java.lang.String').implementation = function(a){ //Calling the function with argument
    this.chall05('frida');
  }

})

Jalankan script tersebut dan kita akan berhasil menyelesaikan tantangan 5.

Berhasil Menyelesaikan Tantangan 5 Berhasil Menyelesaikan Tantangan 5

0x8 - Run chall06() after 10 seconds with correct value

Saat aplikasi berjalan, beberapa tindakan dilakukan, di antaranya:

  • Fungsi startTime() dari kelas challenge_06 dipanggil untuk menyimpan waktu saat ini dalam format epoch time ke dalam variabel timeStart.
  • Dijadwalkan sebuah TimerTask untuk menjalankan kode yang secara teratur menghasilkan nilai acak dan menambahkannya ke variabel chall06 setiap detiknya melalui fungsi addChall06().
  • Dalam fungsi addChall06(), jika nilai variabel chall06 melebihi 9000, maka nilainya akan direset kembali.

Pemanggilan Fungsi Ketika Aplikasi Berjalan Pemanggilan Fungsi Ketika Aplikasi Berjalan

Class challenge_06 Class challenge_06

Fungsi chall06() Fungsi chall06()

Untuk menyelesaikan tantangan ini, kita perlu memanggil chall06() dengan menyertakan nilai argumen dari variabel chall06 setidaknya setelah 10 detik aplikasi berjalan. Validasi ini diimplementasikan dalam fungsi confirmChall06().

Setelah memahami kondisinya, jalankan aplikasi dan tunggu selama 10 detik. Setelah itu, jalankan script berikut:

1
2
3
4
5
6
7
8
9
Java.performNow(function(){
    Java.choose('uk.rossmarks.fridalab.MainActivity', {
      onMatch: function(instance) { //"instance" is the instance for the MainActivity
        var a = Java.use("uk.rossmarks.fridalab.challenge_06");
        instance.chall06(a.chall06.value); //Calling the function
      },
      onComplete: function() {}
    });
});

Berhasil Menyelesaikan Tantangan 6 Berhasil Menyelesaikan Tantangan 6

Yey.. Kita berhasil menyelesaikan tantangan 6.

Selain menunggu selama 10 detik sebelum menjalankan script, kita juga bisa menambahkan delay sebelum suatu kode dieksekusi. Dengan demikian kita bisa menyelesaikan tantangan ini dengan menjalankan script di awal pada saat aplikasi mulai berjalan.

Berikut adalah script yang akan kita gunakan, dengan penundaan (delay) selama 15 detik sebelum script dijalankan.

1
2
3
4
5
6
7
8
9
10
11
12
setTimeout(function() {
    Java.performNow(function(){
        Java.choose('uk.rossmarks.fridalab.MainActivity', {
          onMatch: function(instance) { //"instance" is the instance for the MainActivity
            var a = Java.use("uk.rossmarks.fridalab.challenge_06");
            instance.chall06(a.chall06.value); //Calling the function
            console.log("Check now!")
          },
          onComplete: function() {}
        });
    });
}, 15000); //execute after 15 seconds

Simpan script tersebut dalam sebuah file, lalu jalankan aplikasi dan script menggunakan Frida.

1
➜ frida -U -f uk.rossmarks.fridalab -l script.js

Berhasil Menyelesaikan Tantangan 6 Menggunakan Delay Berhasil Menyelesaikan Tantangan 6 Menggunakan Delay

Tantangan 6 berhasil diselesaikan dengan menyisipkan kode delay.

0x9 - Bruteforce check07Pin() then confirm with chall07()

Ketika aplikasi pertama kali berjalan, fungsi setChall07() dari class challenge_07 akan dipanggil.

Pemanggilan Fungsi Ketika Aplikasi Berjalan Pemanggilan Fungsi Ketika Aplikasi Berjalan

Fungsi setChall07() akan menyimpan nomor acak dengan rentang 1000 hingga 9000 pada variabel statis chall07.

Class challenge_07 Class challenge_07

Untuk menyelesaikan tantangan ini, kita perlu memanggil fungsi chall07() pada class MainActivity dengan argumen yang nilainya sama dengan nomor acak yang telah tersimpan.

Fungsi chall07() Fungsi chall07()

Ada beberapa cara untuk menyelesaikan tantangan ini. Salah satunya adalah dengan menggunakan pendekatan seperti pada tantangan 6 yang langsung mengakses variabel statis sebagai nilai argumen dalam pemanggilan fungsi chall07(). Berikut contoh script-nya:

1
2
3
4
5
6
7
8
9
10
Java.performNow(function(){
    Java.choose('uk.rossmarks.fridalab.MainActivity', {
      onMatch: function(instance) { //"instance" is the instance for the MainActivity
        var a = Java.use("uk.rossmarks.fridalab.challenge_07");
        console.log("chall07: " + a.chall07.value);
        instance.chall07(a.chall07.value); //Calling the function
      },
      onComplete: function() {}
    });
});

Berhasil Menyelesaikan Tantangan 7 Berhasil Menyelesaikan Tantangan 7

Dari gambar di atas, terlihat bahwa tantangan 7 berhasil diselesaikan.

Selain itu, kita juga dapat menggunakan metode bruteforce sebagaimana yang disiratkan dalam judul tantangan. Pada pendekatan ini, kita mencoba PIN dari 1000 hingga 9000. Berikut contoh script-nya:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Java.performNow(function(){
    Java.choose('uk.rossmarks.fridalab.MainActivity', {
      onMatch: function(instance) { //"instance" is the instance for the MainActivity
        var a = Java.use("uk.rossmarks.fridalab.challenge_07");

        // brute force
        for (i=1000; i<=9000; i++) {
            if (a.check07Pin(i.toString())) {
                console.log("Pin: " + a.chall07.value);
                instance.chall07(a.chall07.value);
            }
        }

      },
      onComplete: function() {}
    });
});

Berhasil Menyelesaikan Tantangan 7 Dengan Cara Bruteforce PIN Berhasil Menyelesaikan Tantangan 7 Dengan Cara Bruteforce PIN

Dengan pendekatan bruteforce PIN, tantangan 7 berhasil diselesaikan.

0xA - Change ‘check’ button’s text value to ‘Confirm’

Setiap tombol CHECK ditekan, fungsi chall08() akan dipanggil dan mengembalikan nilai true atau false.

Pemanggilan Fungsi Ketika Aplikasi Berjalan Pemanggilan Fungsi Ketika Aplikasi Berjalan

Untuk menyelesaikan tantangan ini, nilai pengembalian dari fungsi chall08 harus menjadi true. Fungsi ini akan mengembalikan nilai true jika teks tombol diubah dari CHECK menjadi Confirm.

Fungsi chall08() Fungsi chall08()

Kita bisa menggunakan Frida untuk mengubah nilai pengembalian seperti pada tantangan 3. Berikut contoh script-nya:

1
2
3
4
5
6
7
8
9
10
11
Java.perform(function (){
 
    var a = Java.use("uk.rossmarks.fridalab.MainActivity");
    a.chall08.implementation = function(){

		console.log("This method is hooked");
		return true // set return "true"
        
    }

})

Berhasil Menyelesaikan Tantangan 8 Berhasil Menyelesaikan Tantangan 8

Dari gambar di atas, terlihat bahwa tantangan 8 berhasil diselesaikan.

Selain itu, kita juga bisa menggunakan cara mengubah teks tombol CHECK menjadi Confirm sesuai dengan yang disiratkan dalam judul tantangan.

Untuk mengubah tombol CHECK, kita perlu menggunakan fungsi findViewById yang ada di class instance MainActivity. findViewById() berfungsi untuk mencari dan mengambil referensi ke view (komponen UI) di layout XML.

Mari kita siapkan template script untuk mengakses class instance MainActivity.

1
2
3
4
5
6
7
8
Java.performNow(function(){
    Java.choose('uk.rossmarks.fridalab.MainActivity', {
      onMatch: function(instance) { //"instance" is the instance for the MainActivity
        // TO DO
      },
      onComplete: function() {}
    });
});

Selanjutnya, kita siapkan objek button untuk berinteraksi dengan class android.widget.Button.

1
2
3
4
5
6
7
8
Java.performNow(function(){
    Java.choose('uk.rossmarks.fridalab.MainActivity', {
      onMatch: function(instance) {
        var button = Java.use('android.widget.Button'); //set up a button object to interact with Java's android.widget.Button class.
      },
      onComplete: function() {}
    });
});

R adalah class pada Android yang memiliki ID dari semua komponen UI. Komponen yang digunakan pada tombol CHECK adalah R.id.check. Jika kita mengklik dua kali pada kode tersebut, kita akan melihat bahwa komponen ini memiliki ID 0x7f07002f.

Nilai R.id.check Nilai R.id.check

Setelah mengetahui ID dari komponen yang akan diubah. kita melakukan casting untuk memastikan bahwa objek checkid adalah instance dari class android.widget.Button.

1
2
3
4
5
6
7
8
9
10
Java.performNow(function(){
    Java.choose('uk.rossmarks.fridalab.MainActivity', {
      onMatch: function(instance) {
        var button = Java.use('android.widget.Button');
        var checkid = instance.findViewById(0x7f07002f); //find a view with ID 0x7f07002f (the Button that we want to modify).
        var check = Java.cast(checkid, button); //ensure that the view found is Button by casting to the android.widget.Button class.
      },
      onComplete: function() {}
    });
});

Selanjutnya, kita siapkan objek string untuk menangani string dalam Java dan memanggil method setText pada tombol untuk mengubah teks tombol menjadi “Confirm”.

1
2
3
4
5
6
7
8
9
10
11
12
Java.performNow(function(){
    Java.choose('uk.rossmarks.fridalab.MainActivity', {
      onMatch: function(instance) {
        var button = Java.use('android.widget.Button');
        var checkid = instance.findViewById(0x7f07002f);
        var check = Java.cast(checkid, button);
        var string = Java.use('java.lang.String'); //set up a string object to handle strings in Java.
        check.setText(string.$new("Confirm")); //calls the setText method on the Button to change the Button text to "Confirm"
      },
      onComplete: function() {}
    });
});

Berikut adalah script lengkapnya:

1
2
3
4
5
6
7
8
9
10
11
12
Java.performNow(function(){
    Java.choose('uk.rossmarks.fridalab.MainActivity', {
      onMatch: function(instance) { //"instance" is the instance for the MainActivity
        var button = Java.use('android.widget.Button'); //set up a button object to interact with Java's android.widget.Button class.
        var checkid = instance.findViewById(0x7f07002f); //find a view with ID 0x7f07002f (the Button that we want to modify).
        var check = Java.cast(checkid, button); //ensure that the view found is Button by casting to the android.widget.Button class.
        var string = Java.use('java.lang.String'); //set up a string object to handle strings in Java.
        check.setText(string.$new("Confirm")); //calls the setText method on the Button to change the Button text to "Confirm"
      },
      onComplete: function() {}
    });
});

Berhasil Mengubah Teks Tombol Berhasil Mengubah Teks Tombol

Kita berhasil mengubah teks tombol dan menyelesaikan tantangannya.

This post is licensed under CC BY 4.0 by the author.