Android Pentesting 101: A Novice’s Handbook to Getting Started
Android pentesting is the process of evaluating the security of an Android application by identifying its vulnerabilities and weaknesses. It involves analyzing the application’s source code, binary files, and network traffic to find security flaws. There are mainly 2 parts Static and Dynamic analysis
Static analysis involves examining an application’s code and configuration files without executing it, while dynamic analysis involves testing the application in a running state to observe its behavior and interactions. Both approaches are important for testing the security of an Android application.
This blog will be covering all these aspects.
Table of contents
- Setting up the testing environment
a. Emulators
b. How to install and access the application
c. Useful adb commands
d. Extracting the APK from the device - Static Analysis
a. Reverse Engineering
i. DEX → JAR → JAVA
ii. APK → JAVA
iii. What to check in the code
b. Decompiling and Recompiling
i. APK Tool
c.Manifest file analysis - Dynamic Analysis
a. Setting up the proxy
i. Configure the Burp Proxy listener
ii. Configure your device to use the proxy
iii. Install a CA certificate on your Android device
iv. Test the configuration / Intercept the traffic - Local Data Storage Enumeration
- Open Source Frameworks
- References
Set up the Environment
Emulators
To start Android pentesting, you need to set up a virtual environment for the Android device. Multiple android emulators are available like Genymotion, QEMU,Memu, NOX_Player etc.
Compared to others the setp-up is more easy in Memu and Nox. So, I personally prefer Memu or Nox_Player for testing.
An emulator provides a complete virtual environment that mimics the actual device, while a simulator only simulates the behavior of the device.
How to install the application
- Install from playstore — straightforward
- Open the filename.apk using memu apk install option / Drag and drop the apk in the memu/nox player
3. adb install filename.apk
ADB and ADB commands
ADB (Android Debug Bridge) is a command-line tool that enables communication between a computer and an Android device. ADB provides a variety of commands that allow developers and security testers to interact with an Android device, transfer files, install or remove applications, and collect information for debugging or security testing purposes.
Here are some common ADB commands:
adb devices
: Lists all connected Android devices and their status.adb shell
: Opens a shell on the Android device, allowing the user to execute commands directly on the device.adb install [path to APK]
: Installs an Android application on the connected device.adb uninstall [package name]
: Uninstalls an application from the connected device.adb pull [remote file path] [local file path]
: Copies a file from the Android device to the local computer.adb push [local file path] [remote file path]
: Copies a file from the local computer to the Android device.adb bugreport
: Generates a detailed bug report of the Android device, including system logs, application data, and device information.adb screenrecord
: Records the Android device’s screen in real-time and saves it as a video file on the local computer.- Start/ Stop ADB server: If a device is connected start the adb server to be able to interact with the device.
adb start-server
adb kill-server adb logcat
: Displays the Android device’s system log in real-time.adb logcat
Print the current device log to the console.adb logcat -d > [path_to_file]
Save the logcat output to a file on the local system.adb logcat -c
The parameter -c will clear the current logs on the device.
To capture logs of a specific app:adb shell pidof com.example.app
(gives you pid of specific app)adb logcat --pid 15236
displays log of that app's pid only) you can also append -f <filename> to adb logcat commandadb logcat packagename:[priority level: V, D, I, W, E, F, S]
Filter log files by priority e.g. adb logcat com.myapp:E which prints all error logsadb shell
Allow you to interact with an Android device’s command-line interface directly from your computeradb shell pm list packages
: Lists all installed packages on the Android device.adb shell am start [intent]
: Starts an activity on the Android device using an intent.adb shell am force-stop com.android.settings:
Stops an activity on the Android device using an intent.adb shell input text [text]
: Simulates typing text on the Android device’s keyboard.
Extracting the APK from the device
Let’s now assume that the application is not available in the Google Play store. When an application is already installed on the device:
- The APK file of an installed application is stored in the directory
/data/app/<package name>-1/base.apk
. - To get the package name, use the command
adb shell pm list packages | grep sampleapp
since the app name is often part of the package name. - Once you have the package name, use the command
adb shell pm path com.example.sampleapp
to get the full path of the APK file. - Finally, retrieve the
base.apk
file usingadb pull /data/app/com.example.sampleapp-1/base.apk
.
Static Analysis
Static analysis involves analyzing an application’s code, resources, and configuration files without executing the application. This type of analysis is typically performed by analyzing the application’s source code or its compiled binary file (APK) using tools like APKtool, dex2jar. The goal of static analysis is to identify potential vulnerabilities in the code, such as insecure coding practices, data leakage, or hard-coded credentials.
Android Package (APK)
The Android Package (APK) file is a compressed archive file that contains all the files needed to run an Android application on an Android device. The APK file is essentially a ZIP file that contains several components, including:
- AndroidManifest.xml: This file contains information about the application, including its package name, version number, required permissions, and components such as activities, services, and broadcast receivers.
- Classes.dex: This file contains the compiled Java bytecode for the application’s classes, which are executed by the Android Runtime (ART).
- Resources.arsc: This file contains compiled resources such as strings, images, and layouts that are used by the application.
- lib/: This folder contains compiled native code libraries for specific device architectures, such as ARM or x86.
- META-INF/: This folder contains the manifest file, the certificate of the APK signature, and a list of all the files in the APK, along with their checksums.
- assets/: This folder contains additional application data files, such as sound and video files, that are not compiled into the APK.
- res/: This folder contains the application resources, such as layouts, strings, and images, in their original format before being compiled into the Resources.arsc file.
- Android System Files: This folder contains system-level files such as the Android runtime, framework libraries, and system components that the application may use.
Reverse Engineering
Mainly there are 2 Methods : DEX → JAR → JAVA and APK → JAVA
- DEX -> JAR -> JAVA
Dex2Jar
The dex files are Dalvik executable files format, and are not human readable. So, we need to convert it back to some human eye friendly language.
https://sourceforge.net/projects/dex2jar/
How to get the .dex file?
UNZIP, WINRAR
Convert the .apk file into .zip file then Extract the zipped file and under extracted folder we find classes.dex file along with other files
We will use a tool called dex2jar which can be used to convert .dex to JAR files
https://github.com/pxb1988/dex2jar
We get a executable jar file as shown below
jd-gui
Now in order to open the classes.dex2jar file we need a tool called jdgui.
For that we just open the tool and add the classes.dex2jar file in it.
APK → JAVA
We convert the APK file directly into the corresponding Java files. The biggest advantage of this method is, that on one hand it’s less complicated,
To decompile the app from binary code directly into Java classes, we use the Android decompiler JADX. With JADX, we can simply open the APK file and view the source code.
What to check in the code?
- Cryptography: Look for any use of encryption algorithms and verify that they are implemented correctly. Check for any hardcoded keys, weak encryption methods, or use of insecure cryptographic algorithms.
- Code Obfuscation: Check for obfuscation techniques used to hide the code and make it difficult to understand. Obfuscation techniques make it harder for reverse engineering, but it can also hide any malicious code.
- API Usage: Verify that the application does not use any insecure APIs or APIs with known vulnerabilities. Look for any APIs that allow unauthorized access or data leakage.
- Reflection: Check for reflection, a feature that allows dynamic code execution. Verify that reflection is not used in a way that can allow an attacker to inject malicious code.
- Dynamic Code Loading: Check for dynamic code loading, a feature that allows an application to load code at runtime. Verify that the application does not load code from untrusted sources or execute any code that is not verified.
- Access Control: Verify that the application has implemented proper access control to sensitive functionality and data. Look for any hardcoded credentials or access tokens.
- Hardcoded sensitive information: Check for any insecure storage of sensitive data such as passwords, user credentials, or personal information. Search for harcoded database(SQL queries), password, keys, sensitive information,URLs.
- External Libraries: Verify that the application does not use any insecure third-party libraries or libraries with known vulnerabilities.
- Integrity Checks: Look for any integrity checks that the application performs to ensure that the code has not been tampered with.
- Native Code: If the application uses native code, verify that the native code is compiled securely and does not contain any vulnerabilities.
- Web view related checks:
setJavaScriptEnabled()
: This method enables or disables the use of JavaScript in a web view. If this method is set to true, the web view can execute JavaScript code, which can be used to manipulate the web page or to communicate with the native Android code. However, if the application does not properly validate the input data sent to the web view, it could allow an attacker to inject malicious JavaScript code.setAllowFileAccess()
: This method allows or denies access to local files in the device file system from the web view. If this method is set to true, the web view can access local files, which can be useful for displaying local HTML files or accessing data stored in the device file system. However, if the application does not properly validate the input data sent to the web view, it could allow an attacker to access or modify local files.addJavascriptInterface()
: This method allows JavaScript code in the web view to access the native Android code by exposing a Java object to JavaScript. This feature can be used to provide additional functionality or to interact with the native Android code. However, if the application does not properly validate the input data sent to the web view, it could allow an attacker to execute arbitrary Java code.runtime.exec()
: This method is used to execute shell commands on the device. If an attacker can inject malicious input data into a web view and exploit an application vulnerability, it could allow the attacker to execute arbitrary shell commands on the device. - Root Detection Implementation details
- SSL Pinning Implementation details
Decompiling and Recompiling
APKTool is an application which decompiles android APKs. It also allows you to debug the smali code step by step. It will enable us to build a language pack by translating the .xml strings inside APK files.
- Download the prepackaged APKTool zip.
- Extract them to a directory.
- Copy the apk file to the apktool folder.
Open command prompt and change the working directory to the apktool installed folder. Eg. “E:\APK_Tool>l”
Set java path(if not set)using following command: Set path=<PATH TO JAVA>
Decompile an APK
Run command (for example consider dvba.apk) apktool d dvba.apk
A new folder will be created by the same name of the apk file (here example dvba.apk)
This apk folder contains AndroidManifest.xml file, apktool.yml file and smali folder. This is decompiled form of apk.
Re-compiling and Signing
- Smali file before modification
2. Smali file after modification
3. Recompile / re-build the apk : apktool d <folder>
4. Sign the APK jarsigner.
Before the modified APK can be installed onto a device it needs to be cryptographically signed. To sign the app_modified.apk APK file the following steps should be taken:
Set java path(if not set)using following command: Set path=<PATH TO JAVA>
1.Generate the private key.
$ keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000
2.Sign the APK using the generated private key.
$ jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.keystore <app_modified.apk>
If you get the Please specify alias name use the following command instead:
$ jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.keystore <app_modified.apk> alias_name
The modified APK should now be signed for 10,000 days and ready to be installed onto the Android device. To do this, ensure the device has USB debugging enabled then attach the device to the computer’s USB port and run:
$ jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.keystore PayGoWithSSL.apk alias_name
Manifest File Analysis
Open AndroidManifest.xml using any text editor
Here we check for:-
- Permissions: Check if the application requests any sensitive permissions like camera, microphone, location, SMS, or call logs. If the app is requesting unnecessary permissions, it could be a red flag for privacy violations or potential security risks.
- Components: Android components like activities, services, receivers, and providers can be exploited by attackers to gain unauthorized access or to launch attacks. Check if any of the components are exposed to other applications or if they are exported with overly permissive access.
android:exported: The default value of the attribute is true. (should be set to false) - Intents: Intents are messages used by different Android components to communicate with each other. They can be used to launch activities, services, or broadcast messages. Check if the app is using any implicit intents that could be intercepted or manipulated by attackers.
- Allow debugable: true — Without a rooted phone it is possible to extract the data or run an arbitrary code using application permission (Should be false) The default value is “false”
- Allow backup: true — The default value of this attribute is true. This setting defines whether application data can be backed up and restored by a user who has enabled usb debugging.(Should be false)
- Application information: Check if the application has any hard-coded credentials, sensitive information, or debugging features that could be exploited by attackers.
- Malware signatures: Check if the application has any malware signatures that could indicate that the app is malicious or potentially harmful.
- Target SDK version: Check if the app is targeting an older version of the Android SDK. If the app is not targeting the latest version, it could be vulnerable to known security vulnerabilities.
NOTE: All the permissions that the application requests should be reviewed to ensure that they don’t introduce a security risk.
Dynamic Analysis
How to setup proxy
Configure the Burp Proxy Listener
To configure the proxy settings for Burp Suite Professional:
- Open Burp Suite Professional and click Settings to open the Settings dialog.
- Go to Tools > Proxy.
- In Proxy Listeners, click Add.
- In the Binding tab, set Bind to port to
8083
(or another port that is not in use). - Select All interfaces and click OK.
- At the prompt, click Yes.
Configure your device to use the proxy
In your Android device, go to Settings > Network & internet.
- Select Internet and long-press the name of your Wi-Fi network.
- Select Modify.
- From the Advanced options menu, select Proxy > Manual.
- Set Proxy hostname to the IP of the computer running Burp Suite Professional.
- Set Proxy port to the port value that you configured for the Burp Proxy listener, in this example
8083
. - Touch Save
Install a CA certificate on your Android device
In order to interact with HTTPS traffic, you need to install a CA certificate from Burp Suite Professional on your Android device.
To download the CA certificate
- In your Android device, Open any browser and Enter http://burp
- Click on the CA certificate
- cacert.der is available for download
- rename the file as cacert.cer
- Click on Download
To install the CA certificate
- In your Android device, go to Settings > Network & internet.
- Click on the 3 dots in the upper right corner and select Advanced
- Select Install Certificates from Advanced Wi-Fi
- Select the downloaded cacert.cer file
- Enter a name to the certificate and click on OK
- Certificate installed successfully.
Depending upon the android version and device version there are multiple methods to install the CA certificate. Please refer the below links if this method not worked for your version.
- External link: Installing a CA certificate on your Android device.
- https://blog.yarsalabs.com/setting-up-burp-for-android-application-testing/
- External link: Configuration for a Chrome browser at version 99 or above.
Test the configuration/ Intercepting the request
To test the configuration:
- Open Burp Suite Professional.
- Go to Proxy > Intercept and click Intercept is off to switch intercept on.
- Open the browser on your Android device and go to an HTTPS web page.
The page should load without any security warnings. You should see the corresponding requests within Burp Suite Professional.
Local Data Storage Enumeration
In order to enumerate the file structure of an installed application, we need to have access to a real or emulated device. This could be achieved by using the Android Debug Bridge (ADB), a command-line tool that lets you communicate directly with the device. Using ADB, we can install and debug applications, while the Unix shell it provides can be used to run commands on the device.
Connecting via ADB
Enable the USB Debugging option on the device
Settings, then About Device or About Phone, depending on the device, and then we scroll down and tap on the Build Number seven times until the message “You are now a developer!” pops up.
Next, tap the back button one time and navigate to Developer Options.
Once we get the IP of the device connect it using adb connect. adb connect <ip>:5555
adb connect <ip>:21503
Memuadb connect <ip>:62001
Nox
Since we are using emulator we can use localhost ip 127.0.0.1 as well.
This command will also start an adb server locally, waiting for new connections. According to the official ADB documentation , port 5555 is used by the adb server, and it is the first port in a sequence that the emulator will attempt to connect to. Once the connection is established, we can use adb devices
to list the connected devices.
Important directories
Below are some important directories to be aware of on an Android device:
/data/data
: This directory contains all user-installed applications./data/user/0
: This directory contains data that is private to a specific app and cannot be accessed by other apps./data/app
: This directory contains APK files of user-installed applications./system/app
: This directory contains pre-installed system applications./system/bin
: This directory contains binary files./data/local/tmp
: This directory is world-writable, which can be a potential security issue./data/system
: This directory contains system configuration files./etc/apns-conf.xml
: This directory contains default Access Point Name (APN) configurations for the device to connect with the current carrier’s network./data/misc/wifi
: This directory contains WiFi configuration files./data/misc/user/0/cacerts-added
: This directory contains user-added certificates./etc/security/cacerts/
: This directory contains the system certificate store, which can only be accessed by root users./sdcard
: This directory contains a symbolic lin
In Android, the directory /data/data/
contains the installation directories of every application that is installed on the device. This directory is private and cannot be accessed by other apps or by non-root users. Having root access via ADB, we can list the contents of this directory.
Applications that are stored in the internal memory of the device reside in the directory /data/data/
.
Directories like databases
and shared_prefs
are created as part of the installation process.
The databases directory is usually populated when the app is first run, storing structured data in a private database.
Having access to the device via ADB, we can enumerate any available databases using the sqlite3
client. Or else we can pull the data to the system and analyze using sqlite viewers
For example /data/data/com.app.damnvulnerablebank
package is installed, and a database is used for storing data. In that case, the database can be found under the directory /data/data/com.app.damnvulnerablebank/databases/
.
Once the database is identified, we can use the sqlite3
tool to read its content.https://sqlitebrowser.org/dl/
Databases are not the only place where data is stored. In the source code, SharedPreferences are objects that point to XML files in order to read and write on them. These XML files eventually will contain a collection of key-value pairs, and will be stored in a directory called shared_prefs.
Open Source Frameworks
Drozer is an Android security testing framework that allows security researchers to find vulnerabilities and potential exploits in Android applications.
Ghidra is a software reverse engineering framework that helps to analyze the security of Android applications.
Androbugs is a static code analysis tool that identifies security issues and potential vulnerabilities in Android applications.
QARK is a dynamic analysis tool that automatically scans Android applications for security vulnerabilities.
MobSF is a dynamic and static analysis tool that provides an all-in-one solution for mobile application security testing on Android and iOS platforms.
References
https://www.maketecheasier.com/run-android-on-desktop-with-genymotion-android-emulator/
https://azurecloudai.blog/2020/09/22/setting-up-an-android-emulator-for-testing-intune-features/