First off, before we get into the technical details of Android Static Analysis and attacking applications, a few housekeeping bits must be understood. This blog is aimed at technical individuals that already understand at a basic level Android development and architecture, aiming to give Security Testers and application developers an insight into the ways an attacker may interrogate code to achieve some form of compromise.
“Compromise” for Android applications is a generic term, colloquially used to describe the achievement of an end goal set by an attacker. This could be anything from compromising user accounts, exploiting a company’s perimeter network or in this case, simply bypassing a client-side control to access some application functionality. In this blog, we will aim to provide an understanding of how android static analysis can aid a security tester when interrogating a Mobile Application.
So, what is Android Static Analysis? Static analysis is a term used to describe the process of decompiling and reverse engineering an application (whether this is Android, iOS, Windows, OS X and so on). It refers to the way in which the decompiled files will be interrogated in a static manner with the aim to gather information to aid further testing. The target of this process can widely vary.
The information that may be targeted as part of this process could include some of the following:
In this blog, we will interrogate the ‘KGB messenger’ CTF which can be found here: (‘https://github.com/tlamb96/kgb_messenger’) in an attempt to bypass its launch controls.
The following tools will be used if you would like to follow along:
First things first, there is no threat landscape without an application. So let’s get this installed. Download the APK file from the linked GIT repository, ensure your device is started and run:
(Command)“` adb install [apkname].apk “`
Now we have this installed, let’s boot the application and see the trouble we are faced with. As you can see (Figure 1) we are greeted with a message preventing us from opening the application fully.
Now we can see the problem, let’s dive into the application source itself to identify how we may be able to bypass this. Open the APK file in JadXGui and browse to the AndroidManifest.xml file. Here we can see the following extract (Figure 2).
We can see as the intent filter states ‘android.intent.action.MAIN’ which means that ‘com.tlamb96.kgbmessenger.MainActivity’ is the entry point of the application. This means we should interrogate MainActivity to understand how the application determines whether or not we are using a russian device.
When we open the MainActivity class, we are greeted with a readable code and several Methods. In this instance we are interested in the onCreate() Method. The reason for this is that when any activity is called, the onCreate method is used to create the activity. This means that the result we are seeing above (Figure 1) is likely as a result of the onCreate method.
Please note there is lots more code in this activity, it is always recommended to research this in full.
However, for the purposes of keeping this blog concise, we will concentrate on the following extract:
String property = System.getProperty(“user.home”);
String str = System.getenv(“USER”);
if (property == null || property.isEmpty() || !property.equals(“Russia”)) {
a(“Integrity Error”, “This app can only run on Russian devices.”);
} else if (str == null || str.isEmpty() || !str.equals(getResources().getString(R.string.User))) {
a(“Integrity Error”, “Must be on the user whitelist.”);
} else {
a.a(this);
startActivity(new Intent(this, LoginActivity.class));
}
From the above we can see some interesting information:
There are a couple of ways we could bypass this, however, only one of which is actually usable in this scenario.
Please note, this section will assume you understand how Android applications are developed and understand what smali code is. There are many articles online surrounding this topic that will explain this in greater detail than is possible here.
Begin by decompiling the application with APKTool:
(Command)“` apktool d kgbmessenger.apk -o patchedkgb “`
This will create a folder that will include the decompiled application where we are able to edit the smali code to remove the integrity message. Open the decompiled app in a text editor of your choice. I typically use something such as Visual Studio Code.
Navigate to the smali code of the MainActivity Class (Smali > com > tlamb96 > kgbmessenger > MainActivity.smali). In this file there are two things that need to be removed, even with no experience with Smali, it is fairly readable for someone who is able to read Java code (or code in general).
Find the method called onCreate(), this should be down on line 94. Both IF statements which undertake checks to ensure that the device is both Russian and the user is on the list need to be removed. At this point I would recommend spending some time familiarising yourself with smali code and how to read it at a high level.
To bypass the checks remove lines 115 through to 175, then change line 186 to return-void (as :goto_0 no longer exists).
This would result in an onCreate function which looks something similar to the following:
.method protected onCreate(Landroid/os/Bundle;)V
.locals 3
invoke-super {p0, p1}, Landroid/support/v7/app/c;->onCreate(Landroid/os/Bundle;)V
const v0, 0x7f09001c
invoke-virtual {p0, v0}, Lcom/tlamb96/kgbmessenger/MainActivity;->setContentView(I)V
const-string v0, “user.home”
invoke-static {v0}, Ljava/lang/System;->getProperty(Ljava/lang/String;)Ljava/lang/String;
move-result-object v0
const-string v1, “USER”
invoke-static {v1}, Ljava/lang/System;->getenv(Ljava/lang/String;)Ljava/lang/String;
move-result-object v1
return-void
.end method
After this we need to then recompile and resign the application, then install the patched APK back to the test device. Please note, when reinstalling the application, delete the version of the application originally installed on the device.
First of all start by generating the key which will be used to sign the application:
(Command)“`keytool -genkey -alias patchkgb -keystore patchingkeys -keyalg RSA -keysize 2048 -validity 10000“`
Then rebuild the application (Please note, the patched apk will be located under /dist of the decompiled app folder):
(Command)“`apktool b patchedkgb“`
Then resign the application, as Android devices always need to be signed to run on devices:
(Command)“`jarsigner -sigalg SHA1withRSA -digestalg SHA1 -keystore patchingkeys.keystore -storepass ‘<password>’ <path-to>/patchedkgb.apk patchkgb“`
After this, ensure that the application is installed again:
(Command)“`adb install patchedkgb.apk“`
Then ta’da, we can now see the login page without needing to prove we have a russian device or prove we are on the list.
It may not be entirely clear what we have just exploited here if you are not sure about the working of Android applications, however, the edits we have made to the application have allowed us to abuse client-side controls to access further functionality. Essentially deleting the previously identified checks and removing these when reinstalling the patched application.
In this case, the functionality may not be considered particularly sensitive, however, in the real world, this may be used to bypass other types of restrictions. For example:
Although the example explored here is fairly trivial, it helps to provide a good idea about what is required when considering client-side controls and how they can be bypassed. In a real-world engagement it is much more likely that other difficulties would be encountered, however, this helps to raise awareness for weaknesses in client-side controls and hopefully helps to prompt developers to make smart decisions when considering access requirements whilst planning application architecture.
References and further reading: