📜 ⬆️ ⬇️

Disabling runtime status checks in an Android application



In the last article I reviewed the OWASP Mobile TOP 10 and then I didn’t have a good case to demonstrate the need to protect the source code. An interesting case for the demonstration appeared only recently, and who are interested in looking at our experience in circumventing environmental checks, let's take a cat.

When evaluating the work of one of the projects, our team immediately realized that the case would not be easy. The developers approached well the issue of information protection in the program and implemented checks of the state of the execution environment. The application did not start under any of the following conditions:


The developers did not obfustirovat the source code and was not embedded test for modification of the code, which allowed me to analyze the ways in which the checks were performed and perform the necessary manipulations with them.
')
So, let's begin. According to the OWASP Mobile TOP 10, which we use as a basic testing methodology at Hacken, source code analysis (Reverse Engineering) - this vulnerability includes the analysis of binary files for determining source code, libraries, algorithms, etc. Software such as IDA Pro, Hopper, otool and other reverse engineering tools can provide insight into the internal workings of an application. This can be used to search for application vulnerabilities, extract critical information such as backend server, encryption keys or intellectual property.

For basic static analysis, I used an interesting tool such as MobSF, which performed decompilation and basic static analysis. After decompiling, I was interested in java- and smali-codes of the program. Java code is needed for analysis, and we will make changes to the smali code. In more detail, how smali and java correspond can be read here .

After reviewing the list of classes, I found a file that is responsible for checking the phone’s rudeness (see Fig. 1) - rootingcheck / RootBeerNative.java.


Fig. 1. List of application classes

After analyzing the class, it became clear that we need to further look for calls to the checkForRoot () and setLogDebugMessage () functions (see. Fig. 2).


Fig. 2. The source code of the classroom check for rutting

Using the grep command, we get the following results, which show us which files have a call to the checkForRoot () and setLogDebugMessage () methods.

Search results:
root @ kali: ~ / Desktop # grep -nr 'RootBeerNative' ******** _ v_0.9.2 /

********_v_0.9.2/smali/rootingcheck/RootBeerNative.smali:1:.class public Lrootingcheck/RootBeerNative; ********_v_0.9.2/smali/rootingcheck/RootBeerNative.smali:17: sput-boolean v0, Lrootingcheck/RootBeerNative;->?:Z ********_v_0.9.2/smali/rootingcheck/RootBeerNative.smali:28: sput-boolean v0, Lrootingcheck/RootBeerNative;->?:Z ********_v_0.9.2/smali/rootingcheck/RootBeerNative.smali:57: sget-boolean v0, Lrootingcheck/RootBeerNative;->?:Z ********_v_0.9.2/smali/o/CM.smali:591: new-instance v1, Lrootingcheck/RootBeerNative; ********_v_0.9.2/smali/o/CM.smali:593: invoke-direct {v1}, Lrootingcheck/RootBeerNative;-><init>()V ********_v_0.9.2/smali/o/CM.smali:685: new-instance v0, Lrootingcheck/RootBeerNative; ********_v_0.9.2/smali/o/CM.smali:687: invoke-direct {v0}, Lrootingcheck/RootBeerNative;-><init>()V ********_v_0.9.2/smali/o/CM.smali:689: invoke-static {}, Lrootingcheck/RootBeerNative;->?()Z ********_v_0.9.2/smali/o/CM.smali:753: new-instance v4, Lrootingcheck/RootBeerNative; ********_v_0.9.2/smali/o/CM.smali:755: invoke-direct {v4}, Lrootingcheck/RootBeerNative;-><init>()V ********_v_0.9.2/smali/o/CM.smali:764: invoke-virtual {v4, v3}, Lrootingcheck/RootBeerNative;->checkForRoot([Ljava/lang/Object;)I ********_v_0.9.2/smali/o/xZ$5.smali:257: new-instance v1, Lrootingcheck/RootBeerNative; ********_v_0.9.2/smali/o/xZ$5.smali:259: invoke-direct {v1}, Lrootingcheck/RootBeerNative;-><init>()V ********_v_0.9.2/smali/o/xZ$5.smali:261: invoke-static {}, Lrootingcheck/RootBeerNative;->?()Z 

root @ kali: ~ / Desktop # grep -nr 'setLogDebugMessages' ******** _ v_0.9.2 /
 ********_v_0.9.2/smali/o/CM.smali:599: invoke-virtual {v1, v0}, Lrootingcheck/RootBeerNative;->setLogDebugMessages(Z)I ********_v_0.9.2/smali/o/CM.smali:761: invoke-virtual {v4, v0}, Lrootingcheck/RootBeerNative;->setLogDebugMessages(Z)I 

But these were not all checks. After analyzing the class MainActivity.java, function calls were found, where the “su”, “test-keys” and “which” strings are passed, with which the test is performed (see. Fig. 3).


Fig.3. Check for rutting

And again, using the grep command, we search for somo-files for rutting checks:

Search results:
root @ kali: ~ / Desktop # grep -nr 'su' ******** _ v_0.9.2 /

 ********_v_0.9.2/smali/o/CM.smali:443: const-string v2, "su" ********_v_0.9.2/smali/o/CM.smali:706: const-string v2, "su" ********_v_0.9.2/smali/o/xZ$5.smali:172: const-string v1, "su" ********_v_0.9.2/smali/o/xZ$5.smali:347: const-string v0, "su" 

root @ kali: ~ / Desktop # grep -nr 'test-keys' ******** _ v_0.9.2 /

 ********_v_0.9.2/smali/o/xZ$5.smali:141: const-string v1, "test-keys" ********_v_0.9.2/smali/o/xZ$5.smali:374: const-string v0, "test-keys" 


root @ kali: ~ / Desktop # grep -nr 'which' ******** _ v_0.9.2 /

 ********_v_0.9.2/smali/o/CM.smali:437: const-string v2, "which" 

In the article I will show only one of the found modifications of checks for rutting. After a small manipulation, namely, a shift of 1 to 0 - checks for rutovnost removed.


Fig. 4. The variable value is one if the phone is rooted


Fig. 5. Now the value of the variable is zero if the phone is rooted

After that - the program can be assembled, signed with its release key and launched on a mobile phone. But if not two BUT! Namely:

  1. check USB connection;
  2. Developer mode enable check - USB connection and enabled Developer mode enable dynamic analysis.

Developer mode check is turned off in the same way as rutting check - changing the unit to zero in the checks

In the MainActivity.java class, we find the line that is responsible for checking the Developer mode (see Figure 6). After this grep, we look for files in which the line “development_settings_enabled” is present and modify the check - change 1 to 0 (see Fig. 7 and 8).


Fig. 6. Check whether Developer mode is enabled on the phone

Search results:
grep -nr "development_settings_enabled" ******** _ v_0.9.2 \

 Binary file ********_v_0.9.2\/build/apk/classes.dex matches ********_v_0.9.2\/smali/o/xZ$1.smali:49: const-string v1, "development_settings_enabled" 


Fig. 7. The place where you need to modify


Fig. 8. Modification

After all the manipulations, you can run the program in Developer mode.

Next, disable the USB connection check. This check is in the class MainActivity.java (see Figure 9). Without the use of grep, we find a line in MainActivity.smali, we find a line that contains a string with a USB check — android.hardware.usb.action.USB_STATE. After that, in the smali-code, we modify the string to any other permissions, which returns “false” (see Fig. 10).


Fig. 9. Check for USB connection in the MainActivity.java code


Fig. 10. Line code to be deleted in MainActivity.smali

It now remains to generate your release key and sign the application with it. This is done as follows:

  1. You need to install two applications: Keytool and Jarsinger.
  2. Run the application assembly command:
  3. apktool b C: \ Users \ User \ Desktop \ ********
  4. Next: cd ******** \ dist \
  5. Next: Keytool.exe -genkey -alias key.keystore -keyalg RSA -validity 20000 -keystore key.keystore
  6. Next: Jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore key.keystore ********. Apk key.keystore
  7. Next: jarsigner -verify -verbose -certs ********. Apk

That's basically all the manipulations and finished. Now install the application on your phone using adb install or from the smartphone directory and you can conduct dynamic testing for vulnerabilities.

After installing the application, launch it (see Fig. 11 and Fig. 12).

Fig. 11. Turn on Developer mode and connect USBFig. 12. Running the application

findings

On a practical example, I showed how you can turn off some checks on the state of the execution environment. Further, with the help of other tools, we analyzed the vulnerability, but this is another story ...

What may cause neglect to protect the code:


How can I defend myself? At Hacken, we decided not to reinvent the wheel and offered the client to obfuscate the source code and use functions that verify the modification of the source code.

PS

You can use a more advanced analysis method — this is smali debugging. You can read more about this in the manual .

For reference, I have formulated a list of strings that is used to check for rutting:

Source: https://habr.com/ru/post/419171/


All Articles