Bug Bounty & Android Applications

2 months ago I started my final year internship at ITsec, a company that does a wide variety of security assessments. The assignment for my internship is to develop an Android application for internal use. When I look for bugs my main focus is on web application targets and never really looked at Android applications. During my research about Android security I already learned a lot about testing Android applications and through a series of posts I want to share what I’ve learned so far.

When we take a look at one of the many public Bug Bounty programs provided by HackerOne and Bugcrowd, we can see that quite a lot of programs have included their Android or iOS application in scope.

Google Play Security

There are many ways to test these Android applications, which are .apk files. In the first part of this series I’ll talk about expanding the scope and finding new endpoints by using .apk files.

Setting up the environment

Let’s get started! We are going to need an environment in which we can test. I’m using Fedora 27 as OS because I noticed quite a speed increase and less compatibility issues compared to Windows. I’m still saving up for my MacBook Pro, so I can’t share anything on my experience with OS X yet.

First thing to setup is Android Studio, the official IDE for Android.

Android Studio provides the fastest tools for building apps on every type of Android device.

World-class code editing, debugging, performance tooling, a flexible build system, and an instant build/deploy system all allow you to focus on building unique and high quality apps.

I won’t be going through every step of the setup but if you have any problems with setting up the IDE feel free to contact me.

Android Studio also provides us with a virtual machine. This makes it possible to test .apk files on a virtual Android device. Now you don’t have to purchase an actual Android phone and it’s easier to revert your testing device. There are a couple of pros and cons between an emulator and physical device, but for the coming posts I will be using the emulator.

Here’s a small bash script to start your emulator without starting up Android Studio:


# android.sh
#!/bin/bash

cd ~/Android/Sdk/tools && ./emulator -avd x1m-demo-avd1 -no-snapshot-load

This script does require the initial setup of the emulator, you can do this in Android Studio -> AVD Manager.

Desktop

A Java Development Kit (JDK) is also required, you can verify that JDK is installed by running java -version in your terminal. If you don’t have this you should be able to install this pretty easy.

For Fedora users this line will install Java on your system:


sudo dnf install java-1.8.0-openjdk-devel

For the tools you are also going to need Java 7 or high (JRE 1.7). If I’m correct, all Linux distribution have this by default.

This is all we need for the environment. Let’s move on to the next part:

Tools of the trade

Testing Android apps is different from testing web apps. It requires skills in reverse engineering, Java, API’s and more. This can be quite intimidating if you don’t have a lot of experience in these fields. I faced the same steep learning curve, so perseverance is really important here. Read guides, README’s and try to develop your own mobile application. In the first part of this post I want to take a look at decompiling an .apk file and looking at some “easy” findings to help with the reconnaisance phase of bug hunting.

Tools

We’re going to need a decompiler. Decompilers try to convert an .apk file to it’s original source code. After decompiling we can check the output to look for hidden strings like API keys or even credentials to some webservice.

  • jadx: A Dex to Java decompiler. This is my favorite decompiler for now, it is easy to use and has 2 options: Command line and GUI to produce source code from Android Dex files and .apk files. Android programs are compiled into .dex (Dalvik Executable) files, which are in turn zipped into a single .apk file on the device. .dex files can be created by automatically translating compiled applications written in the Java programming language. For more information about Dex files I would refer to the official documentation: https://source.android.com/devices/tech/dalvik/dex-format

Jadx

  • Apktool: A tool 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 also makes working with an app easier because of the project like file structure and automation of some repetitive tasks like building apk, etc.

Apktool

Both the decompilers work fine, my personal preference goes out to jadx and I’ll be using it throughout this post.

  • APK Downloader (Ruby): I’m currently developing a quick tool to grab APK’s from the Google Play Store, but for now I’m using mirrors to download them. You could use these mirrors to download Android .apk files: APKPure or APKMirror.

Time for some action

Let’s decompile an .apk file!

Imgur

Imgur seems to have a mobile application: Imgur: Memes, GIFs and More and it’s in scope for their bug bounty program.

After downloading the .apk file we can decompile it:


./jadx -d ~/bugbounty/Imgur/ ~/bugbounty/Imgur/imgur_mobile_v4.0.1.6893.apk 

I did not put any flags in but you can do this if you like. Sometimes the code is heavily obfuscated and Jadx can try to build a more human readable source code if you provide it with some options. --help is also available to check out what options are available.

If we navigate to the directory we provided to Jadx we can see that the .apk file has changed in to source code.

We can see 2 directories: Resources and Sources.

  • Resources contains all the static files, like strings and .xml files like AndroidManifest.xml

  • Sources contains all of the code that has been developed and also includes all third-party code that is needed to run the Android application.

Resources

Let’s go through some of the static files first to keep it simple. A good starting point can be the AndroidManifest.xml file. This file has an important role in every Android application. In this file the developer determines the permissions that the application will require, actions that the app can perform and general other activities.

The AndroidManifest.xml is located in /resources/AndroidManifest.xml

AndroidManifest.xml

AndroidManifest.xml Checklist

  • Debug mode: This is a mistake that is overlooked by many developers, simply by forgetting to set android:debuggable="true" to android:debuggable="false"

This tag should be set to false before releasing your app:


  <application>
  android:debuggable="false"
  </application>

An application should NEVER be in debug mode when launched to production. I will elaborate this in a future post of this series.

  • Backups allowed: This setting should be set to false if your application handles and stores sensitive data such as passwords and credit card details

  <application>
  android:allowBackup="false"
  </application>

  • External Storage: Applications that have the permission to copy data to external storage (SD-card) should be reviewed to ensure that no sensitive information is stored.

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

  • Permissions: There are four values that can be used with the android:protectionLevel attribute:

    • normal
    • dangerous
    • signature
    • signatureOrSystem

<permission>
android:protectionLevel="signature"
</permission>

  • Intents: Intents can be used for a variety of functions: It can be used to launch an activity and send it to any broadcast receiver components. It also allows to communicate with a background service.

 <intent-filter>
 <action android:name="sting" />
 <category android:name="string" />
 </intent-filter>

Always go through the above settings when testing an Android application! Good recon starts at the beginning and the AndroidManifest.xml is an excellent starting point!

Digging a little deeper

To round up the first part of this post I want to take a look at the hardcoded strings in an Android application. Almost all of the text you see in an Android app is stored in the /values/strings.xml file. And the best part: it’s not encoded and just placed hardcoded :)

Normally you would think that developers don’t hardcode sensitive data in their applications.. Maybe Android developers are a different breed, because I’ve found some very juicy data inside the strings.xml file!

It could contain API keys, credentials and much more. A good example to show this is the first flag of the H1-202 CTF: It was hardcoded in the strings.xml file:


 <string name ="first_flag">flag{easier_th4n_voting_4_pr3z}</string>

You can find these interesting strings quite fast: You can open the /res/values/strings.xml file in your favorite code editor and ctrl + f to search for juicy lines. Another option is to grep for some interesting strings:


grep -Hrn 'juicystring' ~/bugbounty/Imgur/resources/res/values

That is it for the first part of this series! I hope you enjoyed reading it and maybe even learned something, that would be cool :)

In the next part I will talk more about reverse engineering, finding external links and tools, so stay tuned!