Android Applications Pentesting

If you want to know about my latest modifications/additions or you have any suggestion for HackTricks or PEASS, join the 💬 PEASS & HackTricks telegram group here, or follow me on Twitter 🐦@carlospolopm. If you want to share some tricks with the community you can also submit pull requests to that will be reflected in this book. Don't forget to give ⭐ on the github to motivate me to continue developing this book.

Android Application Fundamentals

This introduction is taken from

Fundamentals Review

  • Android applications are in the APK file format. APK is basically a ZIP file. (You can rename the file extension to .zip and use unzip to open and see its contents.)

  • APK Contents (Not exhaustive)

    • AndroidManifest.xml

    • resources.arsc/strings.xml

    • res/xml/files_paths.xml

    • META-INF/

      • Certificate lives here!

    • classes.dex

      • Dalvik bytecode for application in the DEX file format. This is the Java (or Kotlin) code that the application will run by default.

    • lib/

      • Native libraries for the application, by default, live here! Under the lib/ directory, there are the cpu-specific directories.

        • armeabi: compiled code for all ARM based processors only

        • armeabi-v7a: compiled code for all ARMv7 and above based processors only

        • x86: compiled code for X86

        • mips: compiled code for MIPS processors only

    • assets/

      • Any other files that may be needed by the app.

      • Additional native libraries or DEX files may be included here. This can happen especially when malware authors want to try and “hide” additional code, native or Dalvik, by not including it in the default locations.

    • res/

      • the directory containing resources not compiled into resources.arsc

    • classes.dex: The classes compiled in the dex file format understandable by the Dalvik virtual machine

    • resources.arsc: a file containing precompiled resources, such as binary XML for example.

Dalvik & Smali

Most Android applications are written in Java. Kotlin is also supported and interoperable with Java. For ease, for the rest of this workshop, when I refer to “Java”, you can assume that I mean “Java or Kotlin”. Instead of the Java code being run in Java Virtual Machine (JVM) like desktop applications, in Android, the Java is compiled to the Dalvik Executable (DEX) bytecode format. For earlier versions of Android, the bytecode was translated by the Dalvik virtual machine. For more recent versions of Android, the Android Runtime (ART) is used. If developers, write in Java and the code is compiled to DEX bytecode, to reverse engineer, we work the opposite direction. Flowchart of Developer's process. Java to DEX bytecode Flowchart of Reverse Engineer's process. DEX bytecode to SMALI to Decompiled Java

Smali is the human readable version of Dalvik bytecode. Technically, Smali and baksmali are the name of the tools (assembler and disassembler, respectively), but in Android, we often use the term “Smali” to refer to instructions. If you’ve done reverse engineering or computer architecture on compiled C/C++ code. SMALI is like the assembly language: between the higher level source code and the bytecode.

Application Entry Points

One of the most important points of reverse engineering is knowing where to begin your analysis and entry points for code execution is an important part of that.

Launcher Activity and other activities

An Android activity is one screen of the Android app's user interface. In that way an Android activity is very similar to windows in a desktop application. An Android app may contain one or more activities, meaning one or more screens.

The launcher activity is what most people think of as the entry point to an Android application. The launcher activity is the activity that is started when a user clicks on the icon for an application. You can determine the launcher activity by looking at the application’s manifest. The launcher activity will have the following MAIN and LAUNCHER intents listed.

Keep in mind that not every application will have a launcher activity, especially apps without a UI. Examples of applications without a UI (and thus a launcher activity) are pre-installed applications that perform services in the background, such as voicemail.

<activity android:name=".LauncherActivity">
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />

Activities can be exported allowing other processes on the device to launch the activity. By default, they aren't exported but you can export them setting:

<service android:name=".ExampleExportedService" android:exported="true"/>

An application can declare an URL schema inside and activity so every time the Android device try to access an address using that schema the applications activity will be called:

In this case the scheme in myapp://

If inside the intent-filteryou find something like this:

Then, it's expecting something like

If you find something like this:

It will mean that it's expecting a URL starting by example://gizmos In this case you could try to abuse the functionality creating a web with the following payloads. It will try to navigate to arbitrary pages and try to execute JS:

<a href="example://gizmos/">click here</a>
<a href="example://gizmos/javascript://%250dalert(1)">click here</a>

In order to find the code that will be executed in the App, go to the activity called by the deeplink and search the function onNewIntent.

Learn how to call deep links without using HTML pages below.

Content Provider

  • Content Provider component supplies data from one application to others on request.

  • You can store the data in the file system, an SQLite database, on the web, or any other persistent storage location your app can access.

  • Through the content provider, other apps can query or even modify the data (if the content provider allows it).

  • Content Provider is useful in cases when an app want to share data with another app.

  • It is much similar like databases and has four methods.

    • insert()

    • update()

    • delete()

    • query()


This is a type of Content Provider that will share files from a folder. You can declare a file provider like this:

<provider android:name="androidx.core.content.FileProvider"
android:grantUriPermissions="true" android:exported="false">
android:resource="@xml/filepaths" />

Note the android:exported attribute because if it's true external applications will be able to access the shared folders. Note that the configuration android:resource="@xml/filepaths" is indicating that the file res/xml/filepaths.xml contains the configuration of which folders this FileProvider is going to share. This is an example of how to indicate to share a folder in that file:

<files-path path="images/" name="myimages" />

Sharing something like path="." could be dangerous even if the provider isn't exported if there is other vulnerability in some part of the code that tried to access this provider. You could access an image inside that folder with content://com.example.myapp.fileprovider/myimages/default_image.jpgasd More information about FileProviders here.


Services run in the background without a UI. There is a myriad of ways that they can be started and thus are an entry point for applications. The default way that a service can be started as an entry point to an application is through Intents.

When the startService API is called to start a Service, the onStart method in the Service is executed.

For example, a service might play music in the background while the user is in a different application, or it might fetch data over the network without blocking user interaction with an activity.

A service can be exported which allows other processes on the device to start the service. By default services aren't exported but it can be configured in the Manifest:

<service android:name=".ExampleExportedService" android:exported="true"/>

Broadcast Receivers

Broadcasts can be thought of a messaging system and broadcast receivers are the listeners. If an application has registered a receiver for a specific broadcast, the code in that receiver is executed when the system sends the broadcast. There are 2 ways that an app can register a receiver: in the app’s Manifest or dynamically registered in the app’s code using the registerReceiver() API call.

In both cases, to register the receiver, the intent filters for the receiver are set. These intent filters are the broadcasts that should trigger the receiver.

When the specific broadcasts are sent that the receiver is registered for are sent, onReceive in the BroadcastReceiver class is executed.

An application may register a receiver for the low battery message for example, and change its behavior based on that information.

Application Subclass

Android applications can define a subclass of Application. Applications can, but do not have to define a custom subclass of Application. If an Android app defines a Application subclass, this class is instantiated prior to any other class in the application.

If the attachBaseContext method is defined in the Application subclass, it is called first, before the onCreate method.


Intent is basically a message that is passed between components (such as Activities, Services, Broadcast Receivers, and Content Providers). Intents can be directed to specific components or apps, or can be sent without a specific recipient. To be simple Intent can be used:

  • To start an Activity, typically opening a user interface for an app

  • As broadcasts to inform the system and apps of changes

  • To start, stop, and communicate with a background service

  • To access data via ContentProviders

  • As callbacks to handle events

Improper implementation could result in data leakage, restricted functions being called and program flow being manipulated. Learn more about intents reading here.

Intent Filter

An IntentFilters specifies the types of Intent that an activity, service, or Broadcast Receiver can respond to. An Intent Filter declares the capabilities of a component. It specifies what an activity or service can do and what types of broadcasts a Receiver can handle. It allows the corresponding component to receive Intents of the declared type. IntentFilters are typically defined via the AndroidManifest.xml file. For BroadcastReceiver it is also possible to define them in coding. An IntentFilters is defined by its category, action and data filters. It can also contain additional metadata.

If any of the component is public then it can be accessed from another application installed on the same device. In Android an activity/services/content provider/broadcast receiver is public when exported is set to true but a component is also public if the manifest specifies an Intent filter for it. However, developers can explicitly make components private (regardless of any intent filters) by setting the “exported” attribute to false for each component in the manifest file. Developers can also set the “permission” attribute to require a certain permission to access each component, thereby restricting access to the component.

Implicit Intents

Intents are programatically created using an Intent constructor:

Intent email = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));

The Action of the previously declared intent is ACTION_SEND and the Extra is a mailto Uri (the Extra if the extra information the intent is expecting).

This intent should be declared inside the manifest as in the following example:

<activity android:name="ShareActivity">
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />

An intent-filter needs to match the action, data and category to receive a message.

The "Intent resolution" process determine which app should receive each message. This process considers the priority attribute, which can be set in the intent-filter declaration, and the one with the higher priority will be selected. This priority can be set between -1000 and 1000 and applications can use the SYSTEM_HIGH_PRIORITY value. If a conflict arises, a "choser" Window appears so the user can decide.

Explicit Intents

An explicit intent specifies the class name it's targeting:

Intent downloadIntent = new (this, DownloadService.class):

In other applications in order to access to the previously declared intent you can use:

Intent intent = new Intent();
intent.setClassName("", "");

Other App components

Application Signing

  • Android requires that all apps be digitally signed with a certificate before they can be installed. Android uses this certificate to identify the author of an app.

  • To run application on the device ,it should be signed.When application is installed on to an device then package manager verifies that whether the application has been properly signed with the certificate in the apk file or not.

  • Application can be self signed or can be signed through CA.

  • Application signing ensures that one application can’t access any other application except through well-defined IPC and also that it is passed unmodified to the device.

Application Verification

  • Android 4.2 and later support application verification. Users can choose to enable “Verify Apps” and have applications evaluated by an application verifier prior to installation.

  • App verification can alert the user if they try to install an app that might be harmful; if an application is especially bad, it can block installation.

Android Sandbox

Once installed on a device, each Android app lives in its own security sandbox: – The Android operating system is a multi-user Linux system in which each app is a different user.

  • By default, the system assigns each app a unique Linux user ID (the ID is used only by the system and is unknown to the app). The system sets permissions for all the files in an app so that only the user ID assigned to that app can access them.

  • Each process has its own virtual machine (VM), so an app’s code runs in isolation from other apps.

  • By default, every app runs in its own Linux process. Android starts the process when any of the app’s components need to be executed, then shuts down the process when it’s no longer needed or when the system must recover memory for other apps.

Android Security Model

There are two layers:

  • The OS, which keeps installed applications isolated from one another.

  • The application itself, which allows developers to expose certain functionalities and configures application capabilities.

UID Separation

Each application is assigned a specific User ID. This is done during the installation of the app so the app can only interact with files owned by its User ID or shared files. Therefore, only the app itself, certain components of the OS and the root user can access the apps data.


The Android Application Sandbox allows to run each application as a separate process under a separate user ID. From Android 5.0(L) SELinux is enforced. Basically, SELinux denied all process interactions and then created policies to allow only the expected interactions between them.

Pre-Installed Applications

These apps are generally found in the /system/app directory and any of them are optimised. Theses applications are worth checking because some times they are running with too many permissions (as root).

  • The ones shipped with the AOSP (Android OpenSource Project) ROM

  • Added by the device manufacturer

  • Added by the cell phone provided (if purchased from them)


In order to obtain root access into a physical android device you generally need to exploit 1 or 2 vulnerabilities which use to be specific for the device and version. Once the exploit has worked, usually the Linux su binary is copied into a location specified in the user's PATH env variable like /system/xbin.

Once the su binary is configured, another Android app is used to interface with the su binary and process requests for root access like Superuser and SuperSU (available in Google Play store).

Note that the rooting process is very dangerous and can damage severely the device


It's possible to replace the OS installing a custom firmware. Doing this it's possible to extend the usefulness of an old device, bypass software restrictions or gain access to the latest Android code. OmniROM and LineageOS are two of the most popular firmwares to use.

Note that not always is necessary to root the device to install a custom firmware. Some manufacturers allow the unlocking of their bootloaders in a well-documented and safe manner.


Once a device is rooted, any app could request access as root. If a malicious application gets it, it can will have access to almost everything and it will be able to damage the phone.

ADB (Android Debug Bridge)

This is the main tool you need to connect to an android device (emulated or physical). It allows you to control your device over USB or Network from a computer, copy files back and forth, install and uninstall apps, run shell commands, perform backups, read logs and more.

Take a look to the following list of ADB Commands to learn how to use adb.


Sometimes it is interesting to modify the application code to access hidden information (maybe well obfuscated passwords or flags). Then, it could be interesting to decompile the apk, modify the code and recompile it. In this tutorial you can learn how to decompile and APK, modify Smali code and recompile the APK with the new functionality. This could be very useful as an alternative for several tests during the dynamic analysis that are going to presented. Then, keep always in mid this possibility.

Other interesting tricks

Static Analysis

First of all, for analysing an APK you should take a look to the to the Java code using a decompiler. Please, read here to find information about different available decompilers.

Looking for interesting Info

Just taking a look to the strings of the APK you can search for passwords, URLs (, api keys, encryption, bluetooth uuids, tokens and anything interesting... look even for code execution backdoors or authentication backdoors (hardcoded admin credentials to the app).


Pay special attention to firebase URLs and check if it is bad configured. More information about whats is FIrebase and how to exploit it here.

Basic understanding of the application - Manifest.xml, strings.xml

Using any of the decompilers mentioned here you will be able to read the Manifest.xml. You could also rename the apk file extension to .zip and unzip it. Reading the manifest you can find vulnerabilities:

  • First of all, check if the application is debuggeable. A production APK shouldn't be (or others will be able to connect to it). You can check if an application is debbugeable looking in the manifest for the attribute debuggable="true" inside the tag <application Example: <application theme="@2131296387" debuggable="true"

    • Learn here how to find debuggeable applications in a phone and exploit them

  • Backup: The android:allowBackup attribute defines whether application data can be backed up and restored by a user who has enabled usb debugging. If backup flag is set to true, it allows an attacker to take the backup of the application data via adb even if the device is not rooted. Therefore applications that handle and store sensitive information such as card details, passwords etc. should have this setting explicitly set to false because by default it is set to true to prevent such risks.

    • <application android:allowBackup="false"

  • NetworkSecurity: The application network security can be overwritten the defaults values with android:networkSecurityConfig="@xml/network_security_config". A file with that name may be put in res/xml. This file will configure important security settings like certificate pins or if it allows HTTP traffic. You can read here more information about all the things that can be configure, but check this example about how to configure HTTP traffic for some domains:

    • <domain-config cleartextTrafficPermitted="true"> <domain includeSubdomains="true"> </domain></domain-config>

  • Exported activities: Check for exported activities inside the manifest as this could be dangerous. Later in the dynamic analysis it will be explained how you can abuse this behaviour.

  • Content Providers: If a exported provider is being exposed, you could b able to access/modify interesting information. In dynamic analysis you will learn how to abuse them.

  • Exposed Services: Depending on what the service is doing internally vulnerabilities could be exploited. In dynamic analysis you will learn how to abuse them.

  • Broadcast Receivers: You will learn how you can possibly exploit them during the dynamic analysis.

  • URL scheme: Read the code of the activity managing the schema and look for vulnerabilities managing the input of the user. More info about what is an URL scheme here.

  • minSdkVersion, targetSDKVersion, maxSdkVersion: They indicate the versions of Android the app will run on. It's important to keep them in mind because from a security perspective, supporting old version will allow known vulnerable versions of android to run it.

Reading resources.arsc/strings.xml you can find some interesting info:

  • API Keys

  • Custom schemas

  • Other interesting info developers save in this file

Insecure data storage

Internal Storage

Files created on internal storage are accessible only by the app. This protection is implemented by Android and is sufficient for most applications. But developers often use MODE_WORLD_READBALE & MODE_WORLD_WRITABLE to give access to those files to a different application, but this doesn’t limit other apps(malicious) from accessing them. During the static analysis check for the use of those modes, during the dynamic analysis check the permissions of the files created (maybe some of them are worldwide readable/writable). More information about this vulnerability and how to fix it here.

External Storage

Files created on external storage, such as SD Cards, are globally readable and writable. Because external storage can be removed by the user and also modified by any application, you should not store sensitive information using external storage. As with data from any untrusted source, you should perform input validation when handling data from external storage. We strongly recommend that you not store executables or class files on external storage prior to dynamic loading. If your app does retrieve executable files from external storage, the files should be signed and cryptographically verified prior to dynamic loading. Info taken from here.

External storage can be accessed in /storage/emulated/0

Broken Cryptography

Poor Key Management Processes

Some developers save sensitive data in the local storage and encrypt it with a key hardcoded/predictable in the code. This shouldn't be done as some reversing could allow attackers to extract the confidential information.

Use of Insecure and/or Deprecated Algorithms

Developers shouldn't use deprecated algorithms to perform authorisation checks, store or send data. Some of these algorithms are: RC4, MD4, MD5, SHA1... If hashes are used to store passwords for example, hashes brute-force resistant should be used with salt.

Other checks

  • It's recommended to obfuscate the APK to difficult the reverse engineer labour to attackers.

  • If the app is sensitive (like bank apps), it should perform it's own checks to see if the mobile is rooted and act in consequence.

  • If the app is sensitive (like bank apps), it should check if an emulator is being used.

  • If the app is sensitive (like bank apps), it should check it's own integrity before executing it to check if it was modified.

React Native Application

Read the following page to learn how to easily access javascript code of React applications:

Other interesting functions

  • Code execution: Runtime.exec(), ProcessBuilder(), native code:system()

  • Send SMSs: sendTextMessage, sendMultipartTestMessage

  • Native functions declared as native: public native, System.loadLibrary, System.load

Dynamic Analysis

First of all, you need an environment where you can install the application and all the environment (Burp CA cert, Drozer and Frida mainly). Therefore, a rooted device (emulated or not) is extremely recommended.

Online Dynamic analysis

You can create a free account in: This platform allows you to upload and execute APKs, so it is useful to see how an apk is behaving.

You can even see the logs of your application in the web and connect through adb.

Thanks to the ADB connection you can use Drozer and Frida inside the emulators.

Local Dynamic Analysis

You can use some emulator like:

  • Android Studio (You can create x86 and arm devices, and according to this latest x86 versions support ARM libraries without needing an slow arm emulator).

    • If you want to try to install an image and then you want to delete it you can do that on Windows:C:\Users\<User>\AppData\Local\Android\sdk\system-images\ or Mac: /Users/myeongsic/Library/Android/sdk/system-image

    • This is the main emulator I recommend to use and you can learn to set it up in this page.

  • Genymotion (Free version: Personal Edition, you need to create an account.)

  • Nox (Free, but it doesn't support Frida or Drozer).

When creating a new emulator on any platform remember that the bigger the screen is, the slower the emulator will run. So select small screens if possible.

As most people will use Genymotion, note this trick. To install google services (like AppStore) you need to click on the red marked button of the following image:

Also, notice that in the configuration of the Android VM in Genymotion you can select Bridge Network mode (this will be useful if you will be connecting to the Android VM from a different VM with the tools).

Or you could use a physical device (you need to activate the debugging options and it will be cool if you can root it):

  1. Settings.

  2. (FromAndroid 8.0) Select System.

  3. Select About phone.

  4. Press Build number 7 times.

  5. Go back and you will find the Developer options.

Once you have installed the application, the first thing you should do is to try it and investigate what does it do, how does it work and get comfortable with it. I will suggest to perform this initial dynamic analysis using MobSF dynamic analysis + pidcat, so will will be able to learn how the application works while MobSF capture a lot of interesting data you can review later on.

Unintended Data Leakage


Often Developers leave debugging information publicly. So any application with READ_LOGS permission can access those logs and can gain sensitive information through that. While navigating through the application use pidcat(Recommended, it's easier to use and read) or adb logcat to read the created logs and look for sensitive information.

Copy/Paste Buffer Caching

Android provides clipboard-based framework to provide copy-paste function in android applications. But this creates serious issue when some other application can access the clipboard which contain some sensitive data. Copy/Paste function should be disabled for sensitive part of the application. For example, disable copying credit card details.

Crash Logs

If an application crashes during runtime and it saves logs somewhere then those logs can be of help to an attacker especially in cases when android application cannot be reverse engineered. Then, avoid creating logs when applications crashes and if logs are sent over the network then ensure that they are sent over an SSL channel. As pentester, try to take a look to these logs.

Analytics Data Sent To 3rd Parties

Most of the application uses other services in their application like Google Adsense but sometimes they leak some sensitive data or the data which is not required to sent to that service. This may happen because of the developer not implementing feature properly. You can look by intercepting the traffic of the application and see whether any sensitive data is sent to 3rd parties or not.

SQLite DBs

Most of the applications will use internal SQLite databases to save information. During the pentest take a look to the databases created, the names of tables and columns and all the data saved because you could find sensitive information (which would be a vulnerability). Databases should be located in /data/data/ like /data/data/com.mwr.example.sieve/databases

If the database is saving confidential information and is encrypted but you can find the password inside the application it's still a vulnerability.

Enumerate the tables using .tables and enumerate the columns of the tables doing .schema <table_name>

Drozer (Exploit Activities, Content Providers and Services)

Drozer allows you to assume the role of an Android app and interact with other apps. It can do anything that an installed application can do, such as make use of Android’s Inter-Process Communication (IPC) mechanism and interact with the underlying operating system. From Drozer Guide. Drozer is s useful tool to exploit exported activities, exported services and Content Providers as you will learn in the following sections.

Exploiting exported Activities - Authorisation bypass

Read this if you want to remind what is an Android Activity. When an Activity is exported you can invoke its screen from an external app. Therefore, if an activity with sensitive information is exported you could bypass the authentication mechanisms to access it. Learn how to exploit exported activities with Drozer.

You can also start an exported activity from adb:

  • PackageName is com.example.demo

  • Exported ActivityName is com.example.test.MainActivity

adb shell am start -n com.example.demo/com.example.test.MainActivity

NOTE: MobSF will detect as malicious the use of singleTask/singleInstance as android:launchMode in an activity, but due to this, apparently this is only dangerous on old versions (API versions < 21).

Exploiting Content Providers - Accessing and manipulating sensitive information

Read this if you want to remind what is a Content Provider. Content providers are basically used to share data. If an app has available content providers you may be able to extract sensitive data from them. It also interesting to test possible SQL injections and Path Traversals as they could be vulnerable. Learn how to exploit Content Providers with Drozer.

Exploiting Services

Read this if you want to remind what is a Service. As service is basically something that can receive data, process it and returns (or not) a response. Then, if an application is exporting some services you should check the code to understand what is it doing and test it dynamically for extracting confidential info, bypassing authentication measures... Learn how to exploit Services with Drozer.

Exploiting Broadcast Receivers

Read this if you want to remind what is a Broadcast Receiver. A broadcast receiver will be waiting for a type of message. Depending on ho the receiver handles the message it could be vulnerable. Learn how to exploit Broadcast Receivers with Drozer.

You can look for deep links manually, using tools like MobSF or scripts like this one. You can open a declared scheme using adb or a browser:

adb shell am start -a android.intent.action.VIEW -d "scheme://hostname/path?param=value" []

Note that you can omit the package name and the mobile will automatically call the app that should open that link.

<!-- Browser regular link -->
<a href="scheme://hostname/path?param=value">Click me</a>
<!-- fallback in your url you could try the intent url -->
<a href="intent://hostname#Intent;scheme=scheme;;;end">with alternative</a>

Code executed

In order to find the code that will be executed in the App, go to the activity called by the deeplink and search the function onNewIntent.

Sensitive info

Every time you find a deep link check that it's not receiving sensitive data (like passwords) via URL parameters, because any other application could impersonate the deep link and steal that data!

Parameters in path

You must check also if any deep link is using a parameter inside the path of the URL like:{username} , in that case you can force a path traversal accessing something like: example://app/users?username=../../unwanted-endpoint%3fparam=value . Note that if you find the correct endpoints inside the application you may be able to cause a Open Redirect (if part of the path is used as domain name), account takeover (if you can modify users details without CSRF token and the vuln endpoint used the correct method) and any other vuln. More info about this here.

More examples

An interesting bug bounty report about links (/.well-known/assetlinks.json).

Insufficient Transport Layer Protection

  • Lack of Certificate Inspection: Android Application fails to verify the identity of the certificate presented to it. Most of the application ignore the warnings and accept any self-signed certificate presented. Some Application instead pass the traffic through an HTTP connection.

  • Weak Handshake Negotiation: Application and server perform an SSL/TLS handshake but use an insecure cipher suite which is vulnerable to MITM attacks. So any attacker can easily decrypt that connection.

  • Privacy Information Leakage: Most of the times it happens that Applications do authentication through a secure channel but rest all connection through non-secure channel. That doesn’t add to security of application because rest sensitive data like session cookie or user data can be intercepted by an malicious user.

From the 3 scenarios presented we are going to discuss how to verify the identity of the certificate. The other 2 scenarios depends on the TLS configuration of the server and if the application sends unencrypted data. The pentester should check by it's own the TLS configuration of the server (here) and detect if any confidential information is sent by an unencrypted/vulnerable channel . More information about how to discover and fix these kind of vulnerabilities here.

SSL Pinning

By default, when making an SSL connection, the client(android app) checks that the server’s certificate has a verifiable chain of trust back to a trusted (root) certificate and matches the requested hostname. This lead to problem of Man in the Middle Attacks(MITM). In certificate Pinnning, an Android Application itself contains the certificate of server and only transmit data if the same certificate is presented. It's recommended to apply SSL Pinning for the sites where sensitive information is going to be sent.

Inspecting HTTP traffic

First of all, you should (must) install the certificate of the proxy tool that you are going to use, probably Burp. If you don't install the CA certificate of the proxy tool, you probably aren't going to see the encrypted traffic in the proxy. Please, read this guide to learn how to do install a custom CA certificate. If installing a custom CA certificate isn't enough to capture the requests of the application you will need to sligtly modify the application, read this page about how to make an APK accept custom certificates.

SSL Pinning

We have already discuss what is SSL Pinning just 2 paragraphs before. When it's implemented in an application you will need to bypass it to inspect the HTTPS traffic or you won't see it. Here I'm going to present a few options I've used to bypass this protection:

  • Automatically modify the apk to bypass SSLPinning with apk-mitm. The best pro of this option, is that you won't need root to bypass the SSL Pinning, but you will need to delete the application and reinstall the new one, and this won't always work.

  • You could use Frida (discussed below) to bypass this protection. Here you have a guide to use Burp+Frida+Genymotion:

  • You can also try to automatically bypass SSL Pinning using objection: objection --gadget explore --startup-command "android sslpinning disable"

  • You can also try to automatically bypass SSL Pinning using MobSF dynamic analysis (explained below)

Common Web vulnerabilities

Note that in this step you should look for common web vulnerabilities. A lot of information about web vulnerabilities be found in this book so I'm not going to mention them here.


Dynamic instrumentation toolkit for developers, reverse-engineers, and security researchers. Learn more at It's amazing, you can access running application and hook methods on run time to change the behaviour, change values, extract values, run different code... If you want to pentest Android applications you need to know how to use Frida.

Learn how to use Frida: Frida tutorial Some "GUI" for actions with Frida: Some other abstractions based on Frida: , You can find some Awesome Frida scripts here:

Android Application Analyzer

This tool could help you managing different tools during the dynamic analysis:

Android Client Side Injections and others

Probably you know about this kind of vulnerabilities from the Web. You have to be specially careful with this vulnerabilities in an Android application:

  • SQL Injection: When dealing with dynamic queries or Content-Providers ensure you are using parameterized queries.

  • JavaScript Injection (XSS): Verify that JavaScript and Plugin support is disabled for any WebViews (disabled by default). More info here.

  • Local File Inclusion: Verify that File System Access is disabled for any WebViews (enabled by default) (webview.getSettings().setAllowFileAccess(false);). More info here.

  • Intent Injection/Fuzzing: Verify actions and data are validated via an Intent Filter for all Activities.

  • Eternal cookies: In several cases when the android application finish the session the cookie isn't revoked or it could be even saved to disk

Automatic Analysis


Static analysis

Vulnerability assessment of the application using a nice web-based frontend. You can also perform dynamic analysis (but you need to prepare the environment).

docker pull opensecurity/mobile-security-framework-mobsf
docker run -it -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest

Notice that MobSF can analyse Andoid(apk), IOS(ipa) and Windows(apx) applications (Windows applications must be analyzed from a MobSF installed in a Windows host). Also, if you create a ZIP file with the source code if an Android or an IOS app (go to the root folder of the application, select everything and create a ZIPfile), it will be able to analyse it also.

MobSF also allows you to diff/Compare analysis and to integrate VirusTotal (you will need to set your API key in MobSF/ and enable it: VT_ENABLED = TRUE VT_API_KEY = <Your API key> VT_UPLOAD = TRUE). You can also set VT_UPLOAD to False, then the hash will be upload instead of the file.

Dynamic analysis with MobSF

MobSF can also be very helpful for dynamic analysis in Android, but in that case you will need to install MobSF and genymotion in your host (a VM or Docker won't work). Note: You need to start first a VM in genymotion and then MobSF. The MobSF dynamic analyser can:

  • Dump application data (URLs, logs, clipboard, screenshots made by you, screenshots made by "Exported Activity Tester", emails, SQLite databases, XML files, and other created files). All of this is done automatically except for the screenshots, you need to press when you want a screenshot or you need to press "Exported Activity Tester" to obtain screenshots of all the exported activities.

  • Capture HTTPS traffic

  • Use Frida to obtain runtime information

From android versions > 5, it will automatically start Friday and will set global proxy settings to capture traffic. It will only capture traffic from the tested application.


By default, it will also use some Frida Scripts to bypass SSL pinning, root detection and debugger detection and to monitor interesting APIs. MobSF can also invoke exported activities, grab screenshots of them and save them for the report.

To start the dynamic testing press the green bottom: "Start Instrumentation". Press the "Frida Live Logs" to see the logs generated by the Frida scripts and "Live API Monitor" to see all the invocation to hooked methods, arguments passed and returned values (this will appear after pressing "Start Instrumentation"). MobSF also allows you to load your own Frida scripts (to send the results of your Friday scripts to MobSF use the function send()). It also has several pre-written scripts you can load (you can add more in MobSF/DynamicAnalyzer/tools/frida_scripts/others/), just select them, press "Load" and press "Start Instrumentation" (you will be able to see the logs of that scripts inside "Frida Live Logs").

Moreover, you have some Auxiliary Frida functionalities:

  • Enumerate Loaded Classes: It will print all the loaded classes

  • Capture Strings: It will print all the capture strings while using the application (super noisy)

  • Capture String Comparisons: Could be very useful. It will show the 2 strings being compared and if the result was True or False.

  • Enumerate Class Methods: Put the class name (like "") and it will print all the methods of the class.

  • Search Class Pattern: Search classes by pattern

  • Trace Class Methods: Trace a whole class (see inputs and outputs of all methods of th class). Remember that by default MobSF traces several interesting Android Api methods.

Once you have selected the auxiliary module you want to use you need to press "Start Intrumentation" and you will see all the outputs in "Frida Live Logs".


Mobsf also brings you a shell with some adb commands, MobSF commands, and common shell commands at the bottom of the dynamic analysis page. Some interesting commands:

shell ls

HTTP tools

When http traffic is capture you can see an ugly view of the captured traffic on "HTTP(S) Traffic" bottom or a nicer view in "Start HTTPTools" green bottom. From the second option, you can send the captured requests to proxies like Burp or Owasp ZAP. To do so, power on Burp --> turn off Intercept --> in MobSB HTTPTools select the request --> press "Send to Fuzzer" --> select the proxy address (

Once you finish the dynamic analysis with MobSF you can press on "Start Web API Fuzzer" to fuzz http requests an look for vulnerabilities.

After performing a dynamic analysis with MobSF the proxy settings me be misconfigured and you won't be able to fix them from the GUI. You can fix the proxy settings by doing:

adb shell settings put global http_proxy :0


This tool is designed to look for several security related Android application vulnerabilities, either in source code or packaged APKs. The tool is also capable of creating a "Proof-of-Concept" deployable APK and ADB commands, to exploit some of the found vulnerabilities (Exposed activities, intents, tapjacking...). As with Drozer, there is no need to root the test device.

pip3 install --user qark # --user is only needed if not using a virtualenv
qark --apk path /to/my.apk
qark --java path/to/parent/java/folder
qark --java path/to/specific/java/

  • Displays all extracted files for easy reference

  • Automatically decompile APK files to Java and Smali format

  • Analyze AndroidManifest.xml for common vulnerabilities and behavior

  • Static source code analysis for common vulnerabilities and behavior

    • Device info

    • Intents

    • Command execution

    • SQLite references

    • Logging references

    • Content providers

    • Broadcast recievers

    • Service references

    • File references

    • Crypto references

    • Hardcoded secrets

    • URL's

    • Network connections

    • SSL references

    • WebView references

reverse-apk relative/path/to/APP.apk

SUPER is a command-line application that can be used in Windows, MacOS X and Linux, that analyzes .apk files in search for vulnerabilities. It does this by decompressing APKs and applying a series of rules to detect those vulnerabilities.

All rules are centered in a rules.json file, and each company or tester could create its own rules to analyze what they need.

Download the latest binaries from in the download page

super-analyzer {apk_file}


StaCoAn is a crossplatform tool which aids developers, bugbounty hunters and ethical hackers performing static code analysis on mobile applications*.

The concept is that you drag and drop your mobile application file (an .apk or .ipa file) on the StaCoAn application and it will generate a visual and portable report for you. You can tweak the settings and wordlists to get a customized experience.

Download latest release:



AndroBugs Framework is an Android vulnerability analysis system that helps developers or hackers find potential security vulnerabilities in Android applications. Windows releases

python -f [APK file]
androbugs.exe -f [APK file]


Androwarn is a tool whose main aim is to detect and warn the user about potential malicious behaviours developped by an Android application.

The detection is performed with the static analysis of the application's Dalvik bytecode, represented as Smali, with the androguard library.

This tool looks for common behavior of "bad" applications like: Telephony identifiers exfiltration, Audio/video flow interception, PIM data modification, Arbitrary code execution...

python -i my_application_to_be_analyzed.apk -r html -v 3

MARA is a Mobile Application Reverse engineering and Analysis Framework. It is a tool that puts together commonly used mobile application reverse engineering and analysis tools, to assist in testing mobile applications against the OWASP mobile security threats. Its objective is to make this task easier and friendlier to mobile application developers and security professionals.

It is able to:


Useful to detect malware:

Obfuscating/Deobfuscating code

Note that depending the service and configuration you use to obfuscate the code. Secrets may or may not ended obfuscated.


ProGuard is an open source command-line tool that shrinks, optimizes and obfuscates Java code. It is able to optimize bytecode as well as detect and remove unused instructions. ProGuard is free software and is distributed under the GNU General Public License, version 2.

ProGuard is distributed as part of the Android SDK and runs when building the application in release mode.



DeGuard reverses the process of obfuscation performed by Android obfuscation tools. This enables numerous security analyses, including code inspection and predicting libraries.

You can upload an obfuscated APK to their platform.


It is a generic android deobfuscator. Simplify virtually executes an app to understand its behavior and then tries to optimize the code so it behaves identically but is easier for a human to understand. Each optimization type is simple and generic, so it doesn't matter what the specific type of obfuscation is used.


APKiD gives you information about how an APK was made. It identifies many compilers, packers, obfuscators, and other weird stuff. It's PEiD for Android.


Read this tutorial to learn some tricks on how to reverse custom obfuscation



AndroL4b is an Android security virtual machine based on ubuntu-mate includes the collection of latest framework, tutorials and labs from different security geeks and researchers for reverse engineering and malware analysis.


Git Repos


For more information visit:

iOS References

To Test