Today I solved FridaLab, a playground Android application for playing with Frida and testing your skills.
The app is made of various challenges, with increasing difficulty, that will guide you through Frida’s potential.
This is a writeup with solutions to the challenges in FridaLab. We suggest the reader to take a look at it and try to solve it by itself before reading further.
In this writeup we will assume that the reader has a working environment with frida-server already installed on the Android device and frida-tools installed on the PC as well, since we will not cover those topics.
First of all, install and decompile the APK file and open the Frida API documentation.
The first challenge is:
Change class challenge_01’s variable ‘chall01’ to 1
From the decompiled code we can se that the challenge_01 class has a variable chall01 declared as int.
|
|
With Frida we can get a wrapper for a Java class and change its static variables like this:
|
|
All the Frida code we will list below needs to be placed inside a Java.perform in order to run, like the code above.
Run chall02()
chall02 is an instance method of the MainActivity class (it’s not declared as static), so if we try to run it with the above approach Frida will fail telling us:
“Error: chall02: cannot call instance method without an instance”.
We need to get a running instance (or making a new one) to call that method.
The following code will do it through the Java.choose Frida API.
|
|
Note that we are declaring a main variable so we can use that instance for the following challenges.
Make chall03() return true
We need to overload MainActivity.chall03() with an implementation that always returns true.
With Frida we can overload it like this:
|
|
Send “frida” to chall04()
Can be solved just by calling the function with “frida” as argument:
|
|
Always send “frida” to chall05()
We can solve this challenge by overloading the function and inside the implementation call the original one with “frida” as argument.
This translate to the following code:
|
|
Run chall06() after 10 seconds with correct value
In the challenge_06 class there are 3 static methods: startTime, addChall06 and confirmChall06.
The startTime method simply stores the time when the application started in the variable timeStart.
The addChall06 is called every 1 second inside a TimerTask (see MainActivity code) with a random value that is summed to the variable chall06.
The confirmChall06 checks if 10 seconds are elapsed since the application’s start and if the argument value match the variable chall06.
Here we can follow 2 approach:
The following code will wait 10 seconds and perform the submission:
|
|
Bruteforce check07Pin() then confirm with chall07()
This is pretty interesting since we can completely bypass the bruteforce check by watching the value of the variable chall07.
Anyway, we know that the pin is 4 digits long so we can cycle through all the possible values from 9999 to 0000.
We defined a pad function in JavaScript that convert the pin from integer to string and adds 0es to the left, if necessary.
The Frida code that performs the bruteforce is the following:
|
|
Change ‘check’ button’s text value to ‘Confirm’
This challenge consists of UI manipolation.
On Android, UI functions must run on the Main UI thread, in Frida we can use the Java.scheduleOnMainThread API.
It’s just a matter of calling the Android Activity.findViewById method, casting to the correct class and replacing it’s text with Button.setText.
** Code below:
**
|
|
The complete solver script is available at: @TheZ3ro/fridalab-solver
Thanks to Ross Marks for making FridaLab.
I really enjoyed breaking it and I hope they will made a version 2 (with some JNI code maybe) or an iOS version.