Android root detection bypass by reverse engineering APK
In this article, we will look at various techniques being used by the developers and ways to bypass these root detection techniques for android applications. Nowadays many applications such as financial, banking, payment wallet applications do not work on the rooted device. Pentesting requires root permission to install various tools to compromise the security of the application and it is very painful job for any pen tester if app does not work on the rooted device that restricts the tester from performing various test cases.
What should you learn next?
We would be focusing on the conventional root detection techniques and bypassing those by reverse engineering (Decompiling) APK file and building the new version of modified APK file with root detection evasion, signing techniques for tampered APK and running the APK on a rooted device.
In this exercise we would be using hybrid approach, we need various tools at different stages for bypassing the root detection logic are as follows:
- Android Studio (Android Virtual Device)
- Dex2Jar
- JDGui
- Apktool
- Notepad++
- Sign.jar
We will be using Android Studio for android virtual device (Emulator), Emulator can be used to install and run apps and test on virtual android device with customized configuration; Android phones, Android tablets, Android Wear, and Android TV devices etc. You can get the latest version of the Android studio from here
Once android studio setup is done, go ahead and create a virtual device with the help of Android Virtual Device (AVD) Manager. Keep the configurations as per your requirements to run APK. As you may aware that AVDs created with the android studio always has root access enabled, apps with root detection logic will not work on these virtual devices.
I have created one AVD as illustrated in below screenshot
After you created the virtual device, it can be started from the AVD manager or you can start with command line, no need to go to AVD manager every time. To run the virtual device, open command prompt with the path where SDK was installed and hit the following command illustrated in below screenshot
Emulator.exe -avd <avd_name>
As you can see our virtual device (Android Emulator) has started successfully.
Further, we would be using android application which is having root detection functionality enabled, its SAMPLE android application developed for the lab analysis, that does not run on the rooted device. Pen testers can use the APK for which they want to bypass the root detection and follow the steps in this article. Once we get the APK file we can install that file in to the emulator by just drag and drop to emulator screen or using adb command as illustrated in the below screenshot
Adb install <apk_file>
sample.apk file is successfully installed on the emulator illustrated above, we will quickly go to the android emulator and check installed application
We can see the app with name Demo installed on the virtual device, we will hit the app and see if it is working.
Oops!! Application is throwing error illustrated in above screenshot, from the error we can understand that application has Root Detection Logic implemented. At runtime application is verifying root access and stop running if the device is rooted.
Understanding root detection logic
To run this application on the rooted device, first we must understand the Root Detection Logic from the application source code. Once we get better idea about the logic been implemented by the developer for the root access detection, then we can use one of the root detection bypass techniques listed below
- We can simply decompile the APK file and remove the root detection code snippet and build a new APK file
- We can bypass the root detection logic with adb shell of the device and hide/replace the root files and directories in the device
- With the help of apps and frameworks such as Xposed, RootCloak, etc. we will have to disallow apps to read the root detection from your rooted device
In this article we will focus on the first approach, the second and third approaches are sometimes tricky.
So, to begin with, we first need to understand the techniques that developer has implemented to check root access on the device. The most common and well-known techniques being used for root detection in the applications are as follows
- Installed Packages: Check for the any of the below-installed packages on the mobile device at runtime
- supersu.apk
- Busybox
- Root Cloak
- Xpose framework
- Cydia
- Substrate
- Installed Files: Check for the installed files and directories on the device and its permissions
- Superuser
- Supersu
- /su
- /system/app/Superuser.apk
- /system/bin
- /system/bin/su
- /system/sd/xbin
- /system/xbin/su
- /system/xbin
- /data/local
- /data/local/bin
- /data/local/xbin
- /sbin
- /system/bin/failsafe
- /vendor/bin
Now, we will reverse engineer the application by decompiling the APK file to verify which techniques application is utilizing for root access detection. Here, we will use the dex2jar tool to decompile the APK file and get the java code.
Dex2jar tool is used to work with Android ". dex" and Java ".class" files, which convert." dex" files to ".class" files (zipped as jar). You can get the dex2jar converter from here
Decompile the sample.apk file as illustrated in the below screenshot
Dex2jar.bat <apk_file_path>
We got the decompiled version of the APK file, i.e., sample_dex2jar.jar file. We will now use JD-GUI tool to read the jar file and understand the root detection logic used in the application.
JD-GUI is a standalone graphical utility that displays Java source codes of ".class" files. You can browse the reconstructed source code with the JD-GUI for instant access to methods and fields. You can get the JD-GUI from here. Using JD-GUI, it is effortless to browse through the java code and search for the strings which we are looking for.
As illustrated in the following screenshot, open the jar file that we have just extracted from the APK file.
We can see the class files and java code inside the jar file; it can also be seen that this is the obfuscated APK file. Read more about Bytecode obfuscation here.
Further, using JD-GUI we are going to search the package names and files such as /system/su/bin, superuser.apk etc. that we discussed in the techniques sections.
As illustrated in the above screenshot we can see that JD-GUI search has identified two classes ah.class and m.class having string "/system." We will go through both the classes and look at Java code.
Yupp!! As we can see application root detection logic is implemented with these two classes ah.class and m.class, where application at runtime verifying if any root access files and packages are present on the device such as Superuser.apk and su binaries. If application found any of these files on the device, it will stop running and will go into hang state.
Root detection logic bypass
Moving forward, to bypass the root detection logic, we need to follow below steps
- Decompile the APK
- Remove the root detection logic
- Recompile the APK
- Sign APK
Here, we will be using Apktool to decompile the APK, Apktool is a used for reverse engineering 3rd party, closed, binary Android apps. It can decode resources to nearly original form and rebuild them after making some modifications; it makes possible to debug smali code step by step. Read more about Apktool here.
We will decompile the sample.apk file using Apktool that baksmali the classes.dex file, command illustrated in the below snapshot.
Apktool.bat d <apk_file>
Switch d signifies decompile.
Apktool has converted Dalvik Executable (dex) into smali code illustrated up above. Earlier we have identified two class files which has the root detection logic, we will quickly go to the smali folder and open those files (m.smali and ah.smali) with Notepad++ utility (more about Notepad++). Illustration below
In smali files we can see the file and package names which application is checking to verify the root access, we do not necessarily have to learn the smali programming or code here. What we need to do is just replace the strings with file/package names that are checking for root access, we have highlighted the same in above screenshots.
We will be replacing these files/package names with any random strings and will save the changes, as illustrated in the below snapshots.
Here we Go!! Now we just need to recompile the APK from the smali code that we had customized with Apktool with below command, illustrated in the following snapshot
Apktool.bat b <app dir_path>
Switch b signifies build apk.
This will convert the smali files back to classes.dex and build the APK file, which will be stored in the same directory under /dist folder. Illustrated below
Once APK is built, we need to sign that APK with public key since Android requires that all APKs be digitally signed with a certificate before they can be installed. We would be using sign.jar file to sign our new APK build.
This sign.jar will automatically sign an APK with the Android test certificate. The public and private keys are embedded within the jar. You can get this jar file from GitHub.
Sign the APK with command, illustrated in the following snapshot, and we will get the signed Apk file in the same directory under /dist folder.
Java -jar sign.jar <apk_file>
We are all set now, we are going to uninstall the old APK and install this new signed APK build into the android AVD/Emulator to check if we can run the application on the rooted device and ascertain that we have successfully bypassed root access detection. Illustration below
After installing the application into the emulator/AVD hit the application and try to open it
BANG!! As we can see that application is running properly on rooted device (Emulator/AVD), earlier application was verifying the root access on the device and stop running. From this exercise we learnt that it is possible to bypass the root detection logic from the APK if the techniques used by the developers are not implemented properly. That's it for this article.
Conclusion
There are many ways to detect root access on Android devices, but blacklisting packages and binaries is the simplest and most effective way to detect root. Majority developers usually do root detection with the help of these techniques which checks for the superuser.apk file, check for frameworks and su binary commands. There are ways to implement complex techniques but bypassing these verifications is not that difficult. It is always recommended to do not just depend on root detection techniques but secure the mobile application from all aspect of the information security.
FREE role-guided training plans