Frida on non-rooted Android devices
Frida is a dynamic instrumentation toolkit for developers, reverse-engineers, and security researchers.
Frida allows:
- Injection of your own scripts into black box processes.
- Hook any function.
- Spy on crypto APIs or trace private application code.
- Disable SSL Pinning and root checkers.
Frida is one of the best tools to use during an application penetration testing.
Why install Frida in a non-rooted Android device?
The most frequent installation of Frida is described here and consists in running a Frida server in the rooted device as a process:
$ adb root # might be required
$ adb push frida-server /data/local/tmp/
$ adb shell "chmod 755 /data/local/tmp/frida-server"
$ adb shell "/data/local/tmp/frida-server &"
Then a conection with the Frida client is done and the instrumentation begins.
frida-ps -U
PID NAME
1590 com.facebook.katana
13194 com.facebook.katana:providers
12326 com.facebook.orca
13282 com.twitter.android
The injection is done with ptrace
by attaching or spawning a process and then injecting the agent. Once the agent is injected, it communicates with its server through a pipe. ptrace
can’t be used as a normal user. To address this constraint, Frida provides another mode of operation called embedded. In this mode the user is responsible to inject the frida-gadget
library.
Moreover, there are some situations that is not possible to have a rooted phone but still you need to use Frida.
I suggest two methods to inject the Frida Gadget:
- Using LIEF to inject Frida Gadget in the libraries of the APK
- Using Objection and modifying the Dalvik bytecode
Using LIEF to inject Frida Gadget in the libraries of the APK
Executable formats include libraries that are linked with executable. In the loading phase of the executable, the loader iterates over these libraries and map them in the memory space of the process. Once mapped it calls its constructor. The idea is to add frida-agent.so
as a dependency of native libraries embedded in the APK.
Based of the awesome job of Romain Thomas @rh0main, I have written a small script to automate the ELF gadget injection with LIEF. It can be downloaded here:
The script does the following:
- 1 Unzips the APK passed as input.
- 2 Asks for the architecture of the Android device. There are two options: The architecture is known, then the gadget is injected only for that architecture. The architecture is unknow, then the gadget is injected in all architectures.
- 3 Asks for the library to be injected, then downloads the last gadget from Frida repository and injects it.
- 4 Removes the old signature.
- 5 Generates the APK with the name
my_app.apk
Requirements
Python 3.6
pip install https://github.com/lief-project/packages/raw/lief-master-latest/pylief-0.9.0.dev.zip
pip install xtract
Usage
python frida_lief_injection.py
[+] Enter the path of your APK: original.apk
[+] Unzip the original.apk in /tmp/tmpknzr8dx4_lief_frida
[+] Select the architecture of your system:
If you don't know run: adb shell getprop ro.product.cpu.abi
1) armeabi
2) arm64-v8a
3) x86
4) armeabi-v7a
5) x86_64
6) I don't know. Inject frida-gadget for all architectures (slower)
> 4
[+] In with library do you want to inject?:
1) libshinobicharts-android.so
2) libmodpng.so
3) libpl_droidsonroids_gif.so
4) libmodft2.so
5) libjniPdfium.so
6) libmodpdfium.so
[+] Enter the number of the desired library:
> 1
[+] Downloading and extracting frida gadget for: armeabi-v7a
[+] Injecting libgdgt.so into armeabi-v7a/libshinobicharts-android.so
[*] Removing old signature
[+] APK Building...
[+] SUCCESS!! Your new apk is : my_app.apk. Now you should sign it.
Signing the APK
Generation of the keystore:
keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000
Signing:
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.keystore my_app.apk alias_name
Frida Injection
The first error is because Frida needs to be executed when the app is opened and the library loaded. If we inject in a library that is used under some circumstances, those circumstances must be followed to activate the Frida gadget.
If the APK is decompiled or the temporary directory that the script generates is analyzed, the ELF injection could be observer with readelf
:
root@kali:/tmp/tmp9fqng8xe_lief_frida/lib/armeabi-v7a# ls
libgdgt.so libtmessages.30.so
root@kali:/tmp/tmp9fqng8xe_lief_frida/lib/armeabi-v7a# readelf -d libtmessages.30.so | grep NEEDED
0x00000001 (NEEDED) Shared library: [libgdgt.so]
0x00000001 (NEEDED) Shared library: [libjnigraphics.so]
0x00000001 (NEEDED) Shared library: [liblog.so]
0x00000001 (NEEDED) Shared library: [libz.so]
0x00000001 (NEEDED) Shared library: [libEGL.so]
0x00000001 (NEEDED) Shared library: [libGLESv2.so]
0x00000001 (NEEDED) Shared library: [libandroid.so]
0x00000001 (NEEDED) Shared library: [libOpenSLES.so]
0x00000001 (NEEDED) Shared library: [libdl.so]
0x00000001 (NEEDED) Shared library: [libstdc++.so]
0x00000001 (NEEDED) Shared library: [libm.so]
0x00000001 (NEEDED) Shared library: [libc.so]
root@kali:/tmp/tmp9fqng8xe_lief_frida/lib/armeabi-v7a#
Reading depedencies of libtmessages.30.so
, libgdgt.so
is the first loaded and corresponds to the Frida Gadget.
Using Objection and modifying the Dalvik bytecode
Objection is a runtime mobile exploration toolkit, powered by Frida. It was built with the aim of helping assess mobile applications and their security posture without the need for a jailbroken or rooted mobile device.
Objection includes a module called patchapk
that does the following:
- 1 Detects the architecure of the Android device using
ADB
. - 2 Unzips the APK passed as input.
- 3 Check if the App has android.permission.INTERNET, if not it rewrites
AndroidManifest.xml
. - 4 Get the first activity launched from the
AndroidManifest.xml
. - 5 Injects the frida gadget in the constructor.
const-string v0, "frida-gadget" invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
- 6 Copies Frida gadget to libs path.
- 7 Rebuild the APK and signs it.
After the new APK is installed, the Frida gadget is injected and Objection can start the instrumentation:
Considerations:
-
Some applications performs integrity checks and these methods will not work.
-
Both methods need
android.permission.INTERNET
inAndroidManifest.xml
. If this is not in the manifest, add it and rebuild the APK. -
For method 1. Using LIEF to inject Frida Gadget in the libraries of the APK, the App must use at least one library.