Hacktricks-skills android-app-pentesting
Android application security testing and vulnerability assessment. Use this skill whenever the user needs to analyze Android APKs, test for security vulnerabilities, enumerate components, exploit intents/deep links, or assess AIDL/Binder services. Trigger for any Android security testing, mobile pentesting, APK analysis, or Android vulnerability research tasks.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/mobile-pentesting/android-app-pentesting/android-applications-basics/SKILL.MDAndroid Application Pentesting
A comprehensive skill for security testing Android applications, from initial reconnaissance to exploitation of common vulnerabilities.
Quick Start
# Basic APK analysis adb shell pm list packages -f | grep <package-name> # Extract and analyze APK adb pull /data/app/<package-name>/base.apk apktool d base.apk -o <output-dir> # List exported components adb shell dumpsys package <package-name> | grep -A 5 "exported"
Android Security Model
Core Concepts
UID Separation: Each app runs under a unique User ID. Apps can only access their own files or shared files. Only the app itself, OS components, and root can access app data.
Sandboxing: Android 5.0+ enforces SELinux, denying all process interactions by default and only allowing expected ones through policies.
Permissions: Declared in
AndroidManifest.xml via <uses-permission> elements. Types:
- Normal: Auto-granted, no user approval needed
- Dangerous: Requires user approval, grants elevated access
- Signature: Only apps signed with same certificate
- SignatureOrSystem: Same certificate OR system-level access
Permission Analysis
# List app permissions adb shell dumpsys package <package-name> | grep -A 100 "requested permissions" # Check granted permissions adb shell dumpsys package <package-name> | grep -A 100 "granted permissions"
APK Structure Analysis
Extract and Decompile
# Pull APK from device adb pull /data/app/<package-name>/base.apk ./ # Decompile with apktool apktool d base.apk -o decompiled/ # Extract resources unzip -l base.apk | grep -E "(AndroidManifest|classes.dex|META-INF)"
Key Files to Analyze
| File | Purpose | Security Relevance |
|---|---|---|
| App configuration | Exported components, permissions, intent filters |
| Compiled code | Business logic, vulnerability patterns |
| Certificate | App signing verification |
| Native libraries | Native code vulnerabilities |
| Additional files | Hidden code, malware |
Smali Analysis
# Decompile DEX to Smali dex2jar base.apk jad-decompile classes-dex2jar.jar # Or use apktool (includes smali) apktool d base.apk -o decompiled/ # Smali code in decompiled/smali/
Component Enumeration
Activities
# List all activities adb shell dumpsys package <package-name> | grep -A 100 "activities" # Find exported activities adb shell dumpsys package <package-name> | grep "exported=" | grep "true" # Check intent filters adb shell dumpsys package <package-name> | grep -A 5 "intent-filter"
Services
# List services adb shell dumpsys package <package-name> | grep -A 100 "services" # Find exported services adb shell dumpsys package <package-name> | grep "service.*exported" # List running services adb shell service list
Broadcast Receivers
# List receivers adb shell dumpsys package <package-name> | grep -A 100 "receivers" # Find exported receivers adb shell dumpsys package <package-name> | grep "receiver.*exported"
Content Providers
# List providers adb shell dumpsys package <package-name> | grep -A 100 "providers" # Check provider permissions adb shell dumpsys package <package-name> | grep -A 5 "provider"
Intent Vulnerability Testing
Implicit Intent Testing
# Test VIEW intent with custom scheme adb shell am start -a android.intent.action.VIEW \ -d "<scheme>://<host>/<path>" # Test SEND intent adb shell am start -a android.intent.action.SEND \ -t "text/plain" \ -e android.intent.extra.TEXT "test payload"
Deep Link Exploitation
# Generic implicit VIEW (custom scheme) adb shell am start -a android.intent.action.VIEW \ -d "<scheme>://<host>/<path>?param=value" # Explicitly target specific Activity adb shell am start -n <package>/<Activity> \ -a android.intent.action.VIEW \ -d "<scheme>://<host>/<path>" # Test javascript: payload (if scheme validation is weak) adb shell am start -a android.intent.action.VIEW \ -d "<scheme>://<host>/web?url=javascript:alert(1)"
Deep Link Discovery
# Find exported activities with VIEW + BROWSABLE grep -r "android.intent.action.VIEW" decompiled/AndroidManifest.xml grep -r "android.intent.category.BROWSABLE" decompiled/AndroidManifest.xml # Extract custom schemes grep -oP 'android:scheme="\K[^"]+' decompiled/AndroidManifest.xml
Common Deep Link Attack Vectors
- Open Redirect:
myapp://host/path?redirect=https://attacker.tld - Auth Bypass:
myapp://host/login?token=<malicious-token> - WebView Injection:
myapp://host/web?url=javascript:alert(1) - Parameter Pollution:
myapp://host/action?param=value¶m=malicious
AIDL/Binder Service Testing
Service Discovery
# List all running services adb shell service list adb shell am list services # Output format: # 145 mtkconnmetrics: [com.mediatek.net.connectivity.IMtkIpConnectivityMetrics] # 146 wifi : [android.net.wifi.IWifiManager]
Service PING (Interface Check)
# Transaction code 0x5f4e5446 (1598968902) returns interface name adb shell service call <service-name> 1 # Valid response returns interface name as UTF-16 string
Transaction Calling
# Syntax: service call <name> <code> [type value ...] # Types: i32 <int>, i64 <long>, s16 <string> # Example: call transaction 8 with int parameter 1 adb shell service call mtkconnmetrics 8 i32 1
Brute-Force Method Discovery
# Iterate transaction codes to find valid methods for i in $(seq 1 50); do printf "[+] %2d -> " $i adb shell service call <service-name> $i 2>/dev/null | head -1 done
Method Mapping via onTransact()
# Decompile service implementation dex2jar <service-jar> # Search for onTransact switch statement grep -A 100 "onTransact" <decompiled-class> # Look for: case TRANSACTION_methodName: // code data.enforceInterface(DESCRIPTOR); int param = data.readInt(); methodName(param); reply.writeNoException(); return true;
Permission Check Analysis
# Look for missing permission checks in service implementation grep -B 5 -A 10 "updateCtaAppStatus\|startMonitor\|privileged" <smali-file> # Vulnerable pattern (no permission check): private void updateCtaAppStatus(int uid, boolean status) { // No permission check - VULNERABLE /* privileged code */ } # Secure pattern: private void updateCtaAppStatus(int uid, boolean status) { if (!isPermissionAllowed()) { throw new SecurityException("uid " + uid + " rejected"); } /* privileged code */ }
Content Provider Testing
Provider Enumeration
# List all providers for app adb shell dumpsys package <package-name> | grep -A 20 "provider" # Check read/write permissions grep -A 5 "<provider" decompiled/AndroidManifest.xml
Provider Access Testing
# Query provider adb shell content query --uri "content://<authority>/<path>" # Insert test data adb shell content insert --uri "content://<authority>/<path>" \ --bind "column1:string:value1" # Update data adb shell content update --uri "content://<authority>/<path>" \ --bind "column1:string:newvalue" \ --selection "column2=?" --selection-arg "value2" # Delete data adb shell content delete --uri "content://<authority>/<path>" \ --selection "column=?" --selection-arg "value"
SQL Injection Testing
# Test in selection parameter adb shell content query --uri "content://<authority>/<path>" \ --selection "1=1 OR 1=1" # Test in projection grep -r "projection" decompiled/smali/ | grep -v "projectionMap"
WebView Security Testing
WebView Configuration Analysis
# Find WebView usage grep -r "WebView" decompiled/smali/ # Check JavaScript enabled grep -r "setJavaScriptEnabled" decompiled/smali/ # Check file access grep -r "setAllowFileAccess" decompiled/smali/ # Check content access grep -r "setAllowContentAccess" decompiled/smali/
JavaScript Bridge Testing
# Find @JavascriptInterface methods grep -r "@JavascriptInterface" decompiled/smali/ # Test bridge injection adb shell am start -a android.intent.action.VIEW \ -d "<scheme>://<host>/web?callback=javascript:alert(1)"
Pre-Installed App Analysis
System App Discovery
# List system apps adb shell pm list packages -s # List privileged apps adb shell pm list packages -3 # Check /system/app and /system/priv-app adb shell ls -la /system/app/ adb shell ls -la /system/priv-app/
Permission Analysis for System Apps
# Check if system app has excessive permissions adb shell dumpsys package <system-package> | grep -A 100 "requested permissions" # Look for apps with root-level permissions grep -r "android.permission.*ROOT\|android.permission.*SYSTEM" decompiled/AndroidManifest.xml
Digital Signature Analysis
Certificate Extraction
# Extract certificate from APK unzip -p base.apk META-INF/CERT.RSA > cert.pem # View certificate details keytool -printcert -file cert.pem # Check signing key apksigner verify --print-certs base.apk
Signature Verification
# Verify APK signature apksigner verify base.apk # Check for multiple signatures (indicates tampering) keytool -printcert -jarfile base.apk
Common Vulnerability Patterns
1. Exported Components Without Permission
<!-- VULNERABLE: Exported without permission --> <activity android:name=".SensitiveActivity" android:exported="true" /> <!-- SECURE: Exported with permission --> <activity android:name=".SensitiveActivity" android:exported="true" android:permission="com.example.CUSTOM_PERMISSION" />
2. Weak Intent Filter Validation
// VULNERABLE: Weak validation if (uri.toString().contains("myapp://")) { // Process intent } // SECURE: Strict validation if (uri.getScheme().equals("myapp") && uri.getHost().equals("secure")) { // Process intent }
3. Insecure Content Provider
<!-- VULNERABLE: No write permission --> <provider android:name=".MyProvider" android:exported="true" android:readPermission="com.example.READ" android:writePermission="" /> <!-- SECURE: Both permissions defined --> <provider android:name=".MyProvider" android:exported="true" android:readPermission="com.example.READ" android:writePermission="com.example.WRITE" />
4. Sticky Broadcasts
// VULNERABLE: Sticky broadcast (deprecated, data sniffable) sendStickyBroadcast(intent); // SECURE: Use LocalBroadcastManager LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
Testing Workflow
Phase 1: Reconnaissance
- Pull APK from device
- Decompile with apktool
- Analyze AndroidManifest.xml
- List all exported components
- Document permissions
Phase 2: Component Testing
- Test each exported Activity with various intents
- Test each exported Service
- Test each exported Broadcast Receiver
- Test each Content Provider
Phase 3: Deep Link Testing
- Enumerate all custom schemes
- Test each scheme with various payloads
- Check for open redirects
- Test for auth bypass
- Test WebView injection
Phase 4: AIDL/Binder Testing
- List all running services
- PING each service to get interface
- Brute-force transaction codes
- Map methods via onTransact()
- Test for missing permission checks
Phase 5: Reporting
- Document all findings
- Provide PoC for each vulnerability
- Suggest remediation steps
- Prioritize by severity
Tools Reference
| Tool | Purpose | Command |
|---|---|---|
| APK decompilation | |
| DEX to JAR conversion | |
| DEX to Java decompilation | |
| Android Debug Bridge | |
| Activity Manager | |
| Service management | |
| Content provider access | |
| Deep link automation | |
| AIDL service scanning | |
Security Checklist
- All exported components have appropriate permissions
- Intent filters use strict validation
- No sticky broadcasts in use
- Content providers have both read and write permissions
- WebView has JavaScript disabled (if not needed)
- WebView has file access disabled
- No hardcoded secrets in code
- Proper certificate pinning for network calls
- Sensitive data encrypted at rest
- No debug mode enabled in production