Frida is a dynamic instrumentation toolkit for developers,
reverse-engineers, and security researchers.
Required tools to follow along:
- Java decompiler (JD-GUI)
- Android emulator (Genymotion)
- Dynamic instrumentation toolkit (Frida)
You’ll need to download 3 files from here: https://github.com/frida/frida/releases
Depending on your distribution, you can easily install the first two and their dependencies. As for the frida-server-android, I’m going to walk you through the installation and emulator setup.
I created an Android application just for demonstration and testing purposes. I’m going to use it during the examples, you can download it from Github: https://github.com/t0thkr1s/frida-demo/releases
I added a new Genymotion virtual device with Android version 5.0 (API 21).
The setup is pretty straightforward just the usual next, next and finish. It’s time to download the Frida Server for the Android client. Don’t forget to check the correct architecture! Next, we need to upload the server to the emulator. I installed Genymotion in the /opt directory
t0thkr1s@btksoftware:/opt/genymobile/genymotion/tools$ ls aapt adb glewinfo lib64
Uploading the file:
./adb push ~/Downloads/frida_server /data/local/tmp/
Changing file permissions:
./adb shell "chmod 755 /data/local/tmp/frida_server"
Running the server in detached mode:
./adb shell "/data/local/tmp/frida_server &"
Now, the emulator is ready and the server is running!
In order to understand the inner workings of an application, we need to reverse engineer it. Fortunately, we can restore the java source files easily.
I’m not going to write about reverse engineering Android apps here, because I already did it in my previous post. Check it out!
I have to admit that the reverse engineering of the demo application reveals all the secrets hidden in it. So, in order to make it more realistic let’s suppose the encryption key is generated from the user-provided PIN code which is used to encrypt private data in the app.
In this case, brute-forcing the PIN code might be a good solution for compromising the security of the whole app. That’s why you need to choose long and strong PINs.
Okay, you looked through the reversed source code and you found a method, which checks if the provided PIN is correct or not.
Spoiler: The PIN is in the strings.xml file.
Most of the time, it’s not that easy… Let’s suppose, we don’t know the PIN. You found the PinUtil class and the boolean *checkPin(String pin) *method. This checks the pin and returns true if the pin is correct, otherwise, it returns false.
import frida, sys
Previously, I mentioned that knowing the PIN could be really beneficial. In this example, I going to show you how to brute-force with Frida.
First, let’s suppose that the PinUtil’s checkPin(String pin) method is not static. By using Java.choose, *we can search the memory for a *PinUtil instance and the onMatch is called when the instance is found. Then, we can use that instance’s method* *in a loop to test all numbers with a length of 4. This is actually not a time-consuming process. You can even try brute-forcing numbers with a length of 5 and finish in a day depending on the number.
The PinUtil’s class checkPin(String pin) function is static. This means that we don’t need to search for the PinUtil object in the memory just call the method using the class name. However, I implemented both (static and non-static solution) in the script below. I hope it’s not confusing. The jscode variable will be overridden by the second assignment and that will be used.
import frida, sys
I included this example because it’s quite common in banking and other applications to restrict rooted device access. It’s a simple check and very, very similar to the PIN bypass example.
I encourage you to write the script yourself and check back, when you finished!
Now, everything in this script should also be familiar to you. You can log a method’s incoming parameters and return normally. This way, we have the ability to log the encryption key used and also the plain text. Again, the key is hardcoded in the code, but you won’t always be this lucky in real life. Here is how I implemented this:
import frida, sys
Modify these script and experiment with them.
It’s the best way to learn new things!
If you found this article helpful, please share to help others with similar interest find it! + Feedback and donations are always welcome!