Android Application Penetration Testing
Android applications are distributed as APK packages that can be decompiled, inspected and modified. This section covers setting up an Android testing environment, reverse engineering and static analysis, runtime instrumentation with Frida, backend and cloud storage checks, and a practical methodology for the most common Android application vulnerabilities.
Setup and Preparation
Before testing an Android application you need an environment to run it in and a way to intercept its traffic. The tooling below covers emulators, physical/cloud devices, certificate installation and static analysis frameworks.
Genymotion
Genymotion is an Android emulator that runs on VirtualBox and is convenient for installing and interacting with APKs.
# Install Genymotionhttps://www.genymotion.com/
# Install VirtualBoxhttps://www.virtualbox.org/wiki/DownloadsGenymotion SaaS
Genymotion also offers cloud-hosted devices driven from the gmsaas command-line tool.
# Install gmsaaspip install gmsaas
# Android SDK setuphttps://developer.android.com/tools/releases/platform-tools
# Copy and extract the platform-tools zip, then point gmsaas at the SDKgmsaas config set android-sdk-path C:\Users\user\AndroidPlatformTools\platform-tools
# In Windows Terminal add adb to your PATH (temporary - make it permanent if you want)$env:PATH += ";C:\Users\user\AndroidPlatformTools"
# Login to gmsaas
# Start a virtual device from the Genymotion GUIhttps://cloud.geny.io/launchpad
# Start a virtual device from the Genymotion CLIgmsaas recipes listgmsaas instances start <RECIPE-UUID> 'Example Test Phone Android 13' --no-wait --max-run-duration 30
# Connect to the virtual device using ADBgmsaas instances listgmsaas instances adbconnect <INSTANCE-UUID>Configure the Burp certificate on the cloud device:
# Export the Burp certificateopenssl x509 -inform DER -in Burp_cert.cer -out Burp_cert.pemopenssl x509 -inform PEM -subject_hash_old -in Burp_cert.pem | head -1mv Burp_cert.pem 9a5ba575.0
# Remount the system partitionadb remount
# Upload the certificateadb push C:\Users\user\Downloads\9a5ba575.0 /system/etc/security/cacerts/
# If you get a "system is read-only" error use:adb shellmount -o rw,remount /system
# If still not working, use the below firstmount -o rw,remount /
# Once donemount -o ro,remount /# Change the certificate rights
adb shell chmod 664 /system/etc/security/cacerts/9a5ba575.0adb rebootInstall the APK and proxy traffic to Burp:
# Install APKadb install 'C:\path\to\example.apk'
# Proxy to Burpadb shell settings put global http_proxy localhost:3333adb reverse tcp:3333 tcp:8080
adb shell settings put global http_proxy :0 # Disable proxy
# Proxy multiple instances to Burpgmsaas instances listgmsaas instances adbconnect <INSTANCE-UUID-1>adb -s localhost:33819 shell settings put global http_proxy localhost:3333adb -s localhost:33819 reverse tcp:3333 tcp:8080
gmsaas instances adbconnect <INSTANCE-UUID-2>adb -s localhost:41549 shell settings put global http_proxy localhost:4444adb -s localhost:41549 reverse tcp:4444 tcp:8080
# If not root on the emulatoradb shellsetprop persist.sys.root_access 3gmsaas instances adbconnect <INSTANCE-UUID>adb shellsuARM Translation for Genymotion
Some apps ship only ARM native libraries and will not run on an x86 Genymotion image without an ARM translation layer.
# The virtual device you add in Genymotion must be Android 8.0 (e.g. the Pixel 2, Android 8.0)
# Step 1: Download v8.0 from https://github.com/m9rco/Genymotion_ARM_Translation# Step 2: Open an administrative CMD and cd to C:\Program Files\Genymobile\Genymotion\tools# Step 3: Push the zip to the deviceadb push C:\Users\user\Downloads\Genymotion-ARM-Translation_for_8.0.zip /sdcard/Download
# Step 4: Open an adb shelladb shell
# Step 5: Flash the archivesh /system/bin/flash-archive.sh /sdcard/Download/Genymotion-ARM-Translation_for_8.0.zip
# Step 6: Exit the adb shell and reboot (also close Genymotion and re-open)adb reboot
# Step 7: Install GAppsAndroid Studio
Android Studio’s emulator is a rooted-capable alternative that supports installing the Burp certificate into the system store.
# Install Android Studiohttps://developer.android.com/studio
# Create a virtual device# 1. Open Android Studio# 2. Click More Actions --> Virtual Device Manager# 3. Choose a device (a Pixel 3XL without Google Play keeps the device rooted)# 4. Choose a system image (e.g. API 29 x86 Android 10 with Google APIs - needed if the app talks to Firebase etc.)
# Make the system partition mountablecd C:\Users\user\AppData\Local\Android\Sdk\emulator.\emulator.exe -writable-system -no-snapshot-load -avd Example -gpu host
# In another terminal while the above is running:cd C:\Users\user\AppData\Local\Android\Sdk\platform-tools.\adb.exe root.\adb.exe shell avbctl disable-verification.\adb.exe reboot #Wait for this to complete - the emulator will look frozen.\adb.exe root.\adb.exe remountPush the Burp certificate to the device and install it as a system certificate (a user certificate will not be trusted by most apps):
# First on the machine running Burp# 1. Proxy tab --> Options --> Import/export CA certificate --> Certificate in DER format --> save as burp.deropenssl x509 -inform DER -in burp.der -out burp.pemopenssl x509 -inform PEM -subject_hash_old -in burp.pem | head -1mv burp.pem 9a5ba575.0
# Copy 9a5ba575.0 to the machine running the emulator
# On the emulator machine.\adb.exe push C:\Users\user\Downloads\9a5ba575.0 /sdcard/.\adb.exe shellmv /sdcard/9a5ba575.0 /system/etc/security/cacerts/chmod 644 /system/etc/security/cacerts/9a5ba575.0
# Run the AVD with the internal laptop webcam enabledcd C:\Users\user\AppData\Local\Android\Sdk\emulator.\emulator.exe -writable-system -no-snapshot-load -camera-front webcam0 -avd Example -gpu hostCheck Connected Devices
Confirm the correct device is attached before running any tooling.
adb devicesInstall an APK via ADB
adb installadb install 'C:\path\to\example.apk'If the app is distributed as a split APK, install all the parts together:
adb install-multiple 'C:\path\to\com.example.app-base.apk' 'C:\path\to\com.example.app-split_config.en.apk' 'C:\path\to\com.example.app-split_config.x86.apk' 'C:\path\to\com.example.app-split_config.xxhdpi.apk'Android Device Architecture
You need the device architecture to download the matching Frida server build.
adb shellgetprop ro.product.cpu.abiInstall the Burp Certificate
The steps below install the Burp CA into the Genymotion system trust store.
# In Burp# Proxy tab --> Options --> Import/export CA certificate --> Certificate in DER format --> save as burp.der
# On the machine with Burpopenssl x509 -inform DER -in burp.der -out burp.pemopenssl x509 -inform PEM -subject_hash_old -in burp.pem | head -1
# 9a5ba575mv burp.pem 9a5ba575.0
# On Windowsadb push 9a5ba575.0 /sdcard/adb shellmv /sdcard/9a5ba575.0 /system/etc/security/cacerts/chmod 644 /system/etc/security/cacerts/9a5ba575.0
# If you get a "system is read-only" error use:adb shellmount -o rw,remount /system
# If still not working, use the below firstmount -o rw,remount /
# Once donemount -o ro,remount /Alternatively, install from the device UI:
# On the emulated device# Drag and drop the .cer file to the SD card# Go to Settings --> Security & Location --> Encryption & credentials --> Install from SD card --> /sdcard/DownloadMobSF
The Mobile Security Framework (MobSF) performs automated static and dynamic analysis of APKs.
https://github.com/MobSF/Mobile-Security-Framework-MobSF
# Install MobSFcd C:\path\to\Mobile-Security-Framework-MobSF.\setup.bat
# Run MobSFcd C:\path\to\Mobile-Security-Framework-MobSF.\run.bat 127.0.0.1:8000Troubleshooting
# If you get a "system is read-only" error use:adb shellmount -o rw,remount /system
# If still not working, use the below firstmount -o rw,remount /# Once donemount -o ro,remount /# If you get connection issues, restore internet access with:adb shellsettings put global http_proxy :0# Upload files to the SD cardadb push C:\path\to\example_resigned.apk /sdcardReverse Engineering and Static Analysis
Reverse engineering an APK exposes the application’s source, resources and manifest, which is where hardcoded secrets, API keys and insecure configuration are usually found.
Reverse Engineering Tools
# Tools# APKTool# Dex2Jar (built into Kali) # d2j-dex2jar app-release.apk# JD-GUI# SQLite DB Browser# Keytool (comes with Java)APKTool unpacks resources and decodes the manifest:
# https://ibotpeaches.github.io/Apktool/install/apktool d C:\path\to\example.apk
.\apktool.bat -r d .\example\app.apk -o .\example\temp
# Searching for strings in the decompiled appfindstr /SIN "firebase" 'C:\path\to\example\*' # Apply the same logic for keys and passwordsfindstr /SIN "API_KEY" *findstr /SIN "secret" *findstr /SIN firebase secret api_key password *Dex2Jar converts .dex/.apk to a .jar you can browse in JD-GUI:
# Dex2Jar (built into Kali, or Windows https://github.com/pxb1988/dex2jar)d2j-dex2jar example.apk
.\d2j-dex2jar.bat C:\path\to\example.apk
# Open the resulting .jar with JD-GUI - http://java-decompiler.github.io/Keytool shows the details of the signing certificate found in the original folder after using APKTool:
keytool -printcert -file "C:\path\to\example\original\META-INF\CERT.RSA"Static Code Analysis (StaCoAn)
StaCoAn scans decompiled code for interesting lines such as hardcoded credentials, API keys, API URLs, decryption keys and major coding mistakes.
https://github.com/vincentcox/StaCoAn
# StaCoAn looks for interesting lines in the code which can contain:# - Hardcoded credentials# - API keys# - URLs of APIs# - Decryption keys# - Major coding mistakes# Requires 64-bit Java.The AndroidManifest.xml File
The manifest contains detailed information about the application, including its declared permissions, exported components and security-relevant flags such as android:debuggable and android:allowBackup. On a device you can inspect it with an app such as ManifestViewer, or extract it during static analysis with APKTool.
Modifying Smali
Decompiling to Smali lets you modify application behaviour (for example to disable a client-side control) and recompile and re-sign the APK.
# Decompile, modify Smali, recompile and sign an APKhttps://www.hebunilhanli.com/wonderland/mobile-security/decompile-modify-smali-recompile-and-sign-apk/https://book.hacktricks.xyz/mobile-apps-pentesting/android-app-pentesting/smali-changeshttps://github.com/skylot/jadxReact Native Apps
If you see an index.android.bundle file in /assets after unpacking with APKTool, the app is a React Native app.
# Decompile the APK# https://ibotpeaches.github.io/Apktool/install/.\apktool.bat -r d '.\example.apk' -o .\example
# Extract the index.android.bundle file from the /assets folder
# Decompile index.android.bundle (may not work if built with webpack v5 etc.)https://github.com/numandev1/react-native-decompilersudo apt install npmnpm install -g react-native-decompilernpx react-native-decompiler -i ~/clients/example/index.android.bundle -o ~/clients/example/output
# Decompile index.android.bundle if based on the Hermes enginehttps://github.com/bongtrop/hbctoolgit clone https://github.com/bongtrop/hbctool.gitcd hbctoolpoetry buildpip install --force-reinstall dist/hbctool-0.1.5-py3-none-any.whl
hbctool disasm index.android.bundle example_hasm
# Decompile index.android.bundle if based on the Hermes engine (option 2)https://github.com/P1sec/hermes-decgit clone https://github.com/P1sec/hermes-dec.gitcd hermes-dechbc-disassembler ~/clients/example/index.android.bundle ~/clients/example/example_hermes.hasmhbc-decompiler ~/clients/example/index.android.bundle ~/clients/example/example_hermes.jsXamarin Apps
Xamarin apps store their .NET assemblies (DLLs) in /unknown/assemblies. Decompile these to review source for database credentials, encryption keys and other secrets.
# Find security vulnerabilities in Xamarin.Android appshttps://github.com/wesleydekraker/xamarin-security-scannerhttps://dotnet.microsoft.com/download/dotnet-core/thank-you/sdk-3.1.401-windows-x64-installer
"C:\path\to\xamarin-security-scanner" dotnet run --project ./XamarinSecurityScanner\XamarinSecurityScanner.App --path C:\path\to\example\
# The tool reports issues such as:# - Certificate validation overwritten# - Permissions may not be enforced# - Unsafe cipher mode used# - External storage is used# - Hardcoded HTTP URL found# - JavaScript enabled in WebView# - JavascriptInterface added to a WebView# - Logging was found# - Access to phone number# - WorldReadable file found# - Backups are enabled# - App has debugging enabled# - App supports an outdated Android version# - App contains a private key
# Xamarin apps store DLLs in /unknown/assemblies# Use https://www.jetbrains.com/decompiler/ to view the DLL source for DB credentials, encryption keys etc.Runtime Analysis with Objection and Frida
Frida instruments a running application and Objection builds on it to provide a runtime mobile exploration toolkit, useful for tasks such as bypassing SSL pinning or root detection.
Installing Frida and Objection
# Install Frida (Windows)pip install frida-tools
# Install Objection (Windows)pip install objection
# Add the above tools to the Windows PATHpip show frida-tools # Note the locationpip show objection # Note the location# The above shows ...\site-packages. Add the directory one level up, e.g.# ...\AppData\Local\Programs\Python\Python311\Scripts, to the PATH
# Testfrida psobjectionRunning Frida Server
# Get the device architectureadb shellgetprop ro.product.cpu.abi # For example x86_64
# Download the matching Frida server versionhttps://github.com/frida/frida/releases# Usually https://github.com/frida/frida/releases/download/16.1.4/frida-server-16.1.4-android-x86_64.xz
# Extract and push the server to /data/local/tmpadb push .\Downloads\frida\frida-server-16.1.4-android-x86_64 /data/local/tmpadb shellcd /data/local/tmpchmod 777 frida-server-16.1.4-android-x86_64./frida-server-16.1.4-android-x86_64
# List apps installed, using Fridafrida-ps -UaiRuntime Changes with Objection
# Perform runtime changes using Objection on one of the apps listed abovehttps://book.hacktricks.xyz/mobile-pentesting/android-app-pentesting/frida-tutorial/objection-tutorialobjection -g com.example.app exploreBackend and Cloud Storage
Mobile apps frequently talk to cloud backends. Misconfigured Firebase databases and storage buckets are a common source of high-impact findings.
Firebase
Methodology to search for and exploit poorly configured Firebase databases:
# https://book.hacktricks.xyz/pentesting/pentesting-web/buckets/firebase-database
# 1. Get the APK of the app (any method to pull the APK from the device works)
# 2. Decompile the APK with apktool.\apktool.bat d C:\path\to\example.apk
# 3. In res/values/strings.xml search for the "firebase" keyword. You may find a URL# such as https://xyz.firebaseio.com/Get-ChildItem -Path .\example\ -Recurse | Select-String -Pattern "firebase"findstr.exe /SIN "firebaseio" .\app-release\*
# 4. Navigate to the found URL with .json appended: https://xyz.firebaseio.com/.json
# 5. Two responses can appear:# "Permission Denied" -> it is well configured# "null" or a block of JSON -> the database is public and you have at least read access
# 6. If readable, check for write privileges using:# https://github.com/MuhammadKhizerJaved/Insecure-Firebase-ExploitGoogle Storage Buckets
https://github.com/RhinoSecurityLabs/GCPBucketBrute
# Brute forcing bucket namescd ~/tools/GCPBucketBrutesudo python3 gcpbucketbrute.py -k example -u
# URL format for buckets# www.googleapis.com/storage/v1/b/<BUCKET NAME>/o# error 404 -> does not exist# error 401 -> exists but configured properly# a list of files -> the bucket is vulnerable and misconfigured
# Get the bucket policyhttps://www.googleapis.com/storage/v1/b/<BUCKET NAME>/iamhttps://www.googleapis.com/storage/v1/b/example-app-production.appspot.com/iam
# Check strings in the decompiled APK for a storage bucket referenceGet-ChildItem -Path .\app\ -Recurse | Select-String -Pattern "google_storage_bucket"# "google_storage_bucket" : "example-app-production.appspot.com"# gsutilhttps://cloud.google.com/storage/docs/gsutil_install
# List the contents of a bucket (needs auth, but use it to check if anonymous access is allowed)gsutil ls gs://example-app-production.appspot.comPulling Databases
App data is stored under /data/data/<package>; apps can also store data in external storage under /mnt/sdcard.
# Enter an ADB shelladb shellcd /data/datacd com.android.providers.telephonycd databases
# In a new terminal, pull the databases.\adb.exe pull /data/data/com.android.providers.telephony/databases
# Open the .db files with DB Browser for SQLite# https://sqlitebrowser.org/dl/
# App-specific data is stored in:# /data/data/****# Apps can also store data in external storage:# /mnt/sdcardSSL Pinning
Apps that implement certificate pinning will reject Burp’s certificate. The references below cover testing and bypassing pinning (often via Frida/Objection).
# Testing SSL pinninghttps://medium.com/globant/testing-ssl-pinning-in-a-mobile-application-44e0175f9244https://medium.com/@evilprince007/ssl-pinning-bypass-simplified-48c0d5294a6cMobile Application Methodology
The checklist below walks through the most common Android application weaknesses.
1. Insecure Data Storage
Check for sensitive user data stored insecurely in shared preferences, databases and temporary files.
# Insecure data storageadb shellcd /data/datacd mntcd /mnt/sdcard
# Check for insecure user data storage in:# 1. Shared Preferences/data/data/com.example.app/shared_prefs/UserInfo.xml# 2. Databases# 3. Temporary files2. Hardcoding Issues
# Use JD-GUI to view .jar source code for hardcoded API keys etc.3. Insecure Logging
# Use logcat to view logs of app activityadb logcat
.\adb.exe -s 192.168.1.100:5555 logcat | Select-String -Pattern com.example.app
# Look for cleartext logging of sensitive data, for example:# - Credit card details# - Login credentials4. Input Validation Issues
# Classic SQL injection' OR '1'='1'--
# Check WebViews for possible input validation flaws# Web addresses e.g. http://www.example.com# Files e.g. file:///data/data/com.example.app/shared_prefs/UserInfo.xml
# Enter these in places like search fields5. Re-signing the Application
An attacker may inject malicious code into an app and re-sign it so a device will install it.
# Tools: jarsigner (comes with the JDK)jarsigner -verify -verbose C:\path\to\example.apk# Remove the existing certificate and signature# 1. Unpack the apk with APKTool# 2. Remove the META-INF folder# Now you can re-sign the application
# Set up a keystore to hold the private key used to sign the applicationkeytool -genkey -v -keystore [name of keystore] -alias [your key alias] -keyalg RSA -keysize 2048 -validity [number of days]keytool -genkey -v -keystore example-keystore -alias example -keyalg RSA -keysize 2048 -validity 10000# Sign the application with jarsigner (admin cmd)jarsigner -verbose -sigalg MD5withRSA -digestalg SHA1 -keystore [name of your keystore] [your .apk file] [your key alias]jarsigner -verbose -sigalg MD5withRSA -digestalg SHA1 -keystore example-keystore C:\path\to\example_resigned.apk example6. Access Control Issues
Exported activities can sometimes be launched directly, bypassing intended access controls.
https://tools.androidtamer.com/Training/DIVA/10_Access_Control_Issues_P2/
# Activity manageradb shell am start [action from intent filter]adb shell am start -W -a android.intent.action.MAIN7. Backup Vulnerabilities
If the manifest sets allowBackup="true", application data can be extracted through the backup mechanism.
https://resources.infosecinstitute.com/topic/android-hacking-security-part-15-hacking-android-apps-using-backup-techniques/# Look for: allowBackup="true"https://vishwarajbhattrai.wordpress.com/2017/07/17/finding-backup-vulnerabilities-in-android-apps/
adb backup -f C:\path\to\example.ab com.example.app
# Convert the .ab file into .tar using Android Backup Extractor# https://github.com/nelenkov/android-backup-extractor/# Get abe-all.jar from releases, rename it to abe and copy it to your working foldercd C:\path\to\android-backup-extractorabe.jar unpack example.ab example.tar
# Copy the tar file to Kali and extract ittar xvf example.tar
# Explore the extracted files, including assets like .db and sharedprefs.xml, for sensitive# information - developers sometimes leave secrets, passwords, or API auth tokens here.# Use sqlite to view .db files.8. Permissions
List all requested permissions and look for dangerous ones.
https://aaptdownload.com/
# List all permissions for the APKaapt d permissions 'C:\path\to\example.apk'9. Free Security Features are Activated
Check the native libraries for PIE and stack-smashing protections (canary and pic must both be true).
https://github.com/radareorg/radare2/
# Test a single native library.\rabin2.exe -I 'C:\path\to\example\lib\x86_64\libexample.so' | Select-String "canary|pic"# Repeat for all .so files in the \lib\x86_64\ folder
# In PowerShell ISE, run rabin2 across every file in the \lib\x86_64\ folder$PrevErrorActionPreference = $ErrorActionPreference$ErrorActionPreference = 'silentlycontinue'Get-ChildItem -Path 'C:\path\to\example\lib\x86_64\' -Recurse | ForEach-Object {$_.FullNameC:\path\to\radare2\bin\rabin2.exe -I $_.Fullname | Select-String 'canary|pic'}$ErrorActionPreference = $PrevErrorActionPreference10. Testing if the App is Debuggable
# Manual# Check AndroidManifest.xml for the android:debuggable attribute and its value
# Using adbadb shell dumpsys package com.example.app | Select-String "DEBUGGABLE"
# Using aapt (if the result is 1, the directive is present)aapt d xmltree 'example.apk' AndroidManifest.xml | Select-String -Pattern 'android:debuggable\(0x[0-9a-f]+\)=\(type\s0x[0-9a-f]+\)0xffffffff'Additional Tools to Test
# QARK - https://github.com/linkedin/qark (Quick Android Review Kit)# Drozer - https://labs.f-secure.com/tools/drozer# PentDroid - https://github.com/vishwaraj101/PentDroid# Mobile Nuclei templates - https://github.com/optiv/mobile-nuclei-templates
# Using the Android USB driver to extract data as a USB mass storage device# https://seclists.org/fulldisclosure/2021/Jun/50
# General# https://github.com/sensepost/objection


