How to install Frida into an Android application
On a recent job I was testing a rather interesting piece of technology that had several server side checks but they wanted to add some additional security on the client side. Great!! One of these additional checks was to see if Frida was running on the device, this was proving a difficult nut to crack so I tried an alternate method.
What if I insert the Frida gadget into the application? This has been done before, so I am not re-writing or doing anything particularly new, but it was new to me so was an awesome new method to add to my tool belt.
How do we do this?
So, the first step is to look at the Android application and see if any Shared Objects (*.so) are in the /lib folder. To do this we simply grab the Android package (*.apk) and use your favourite unzipping tool and check the folder.
If there is an *.so file we can continue, if not, don’t fret we have an alternate plan 😊
For the next step grab the latest version of the Frida-Gadget from https://github.com/frida/frida/releases this will be structured like frida-gadget-<Frida_version>-android-<processor_version>.so.xz. To get the processor version you can run the following Android Debug Bridge (adb) command:
- adb shell getprop ro.product.cpu.abi
We have everything we need at this point, so we can work on injecting into the apk. First decompile the application using apktool:
- apktool d <app name>.apk
Then insert the library and modify the *.so file, this can be done with the following python script:
import lief libnative = lief.parse("<app name>/lib/<processor_version>/<shared object filename>.so") libnative.add_library("<Frida gadget name>.so") libnative.write("<app name>/lib/<processor_version>/<shared object filename>.so")
Modify the above script with your parameters then run it. To check if the injection was successful, we can run “readelf”:
readelf -d “<app name>/lib/<processor_version>/<shared object filename>.so”
The images below show before running the python script and after:
Next, we need to repackage, sign, and install the application, I will detail these steps after we go through the alternative method, if your application does not have a *.so file present. As before we disassemble the apk using apktool, download the Frida gadget and copy to the /lib location:
- apktool d <app name>.apk
- wget https://github.com/frida/frida/releases/download/<frida_version>/frida-gadget-/<frida_version>-android-<processor_version>.so.xz
- cp frida-gadget-<frida_version>-android-<processor_version>.so target/lib/<processor_version>/libfrida-gadget.so
The next stage is to discover what activity is called first by the apk, this is generally going to be the MainActivity but the class name could change from each apk. To check this open the AndroidManifest.xml and find the first activity, an example is shown below:
Alternatively, you could do a recursive grep within the decompiled application folder:
Then repeat the grep command with the correct name, we are looking for a method constructor calling the MainActivity, once located we can add a “loadlibrary” call into the smali, this will look something like this, the added command has been highlighted:
Finally, the injections are done *phew* next we need to rebuild the apk, sign, and install, the steps to this are as follows:
- apktool b <app_name>
- java -jar uber-apk-signer-1.1.0.jar -a ./<app name>/dist/<app name>.apk
- adb install -r ./<app name>/dist/<signed app name>.apk
*-r may or may not be required. This option allows the installation of untrusted applications via adb.
We can then check if Frida is running by using:
- frida-ps -U
If we get a response it worked 😊
You can find everything you need to automate this here: https://github.com/pentestpartners/Inject-Frida-into-APK
Some issues are known and should be checked, for example if the application does not have the internet permission then this will need to be added to the AndroidPermission.xml:
- Decompile the application with apktool
- Grep INTERNET <app name>/AndroidManifest.xml
- Add this line to the Android manifest: <uses-permission android:name=”android.permission.INTERNET” />
- Recompile the application