npx skills add mukul975/Anthropic-Cybersecurity-SkillsMITRE ATT&CK
When to Use
- A suspicious Android APK has been reported as malicious or flagged by mobile threat detection
- Analyzing Android banking trojans, spyware, SMS stealers, or adware samples
- Determining what data an app collects, where it sends it, and what permissions it abuses
- Extracting C2 server addresses, encryption keys, and configuration data from Android malware
- Understanding overlay attack mechanisms used by banking trojans
Do not use for analyzing obfuscated native (.so) libraries within APKs; use Ghidra or IDA for native ARM binary analysis.
Prerequisites
- JADX 1.5+ installed (download from https://github.com/skylot/jadx/releases)
- Android SDK with
aapt2andadbtools for APK inspection - apktool for full APK disassembly including smali code and resources
- Python 3.8+ with
androguardlibrary for automated APK analysis - Frida for dynamic instrumentation (optional, for runtime analysis)
- Isolated Android emulator (Genymotion or Android Studio AVD) without Google services
Workflow
Step 1: Extract APK Metadata and Permissions
Examine the APK structure and AndroidManifest.xml:
# Get APK basic info
aapt2 dump badging malware.apk
# Extract AndroidManifest.xml
apktool d malware.apk -o apk_extracted/ -f
# Analyze permissions with androguard
python3 << 'PYEOF'
from androguard.core.apk import APK
apk = APK("malware.apk")
print(f"Package: {apk.get_package()}")
print(f"App Name: {apk.get_app_name()}")
print(f"Version: {apk.get_androidversion_name()}")
print(f"Min SDK: {apk.get_min_sdk_version()}")
print(f"Target SDK: {apk.get_target_sdk_version()}")
# Dangerous permissions
dangerous_perms = {
"android.permission.READ_SMS": "SMS theft",
"android.permission.RECEIVE_SMS": "SMS interception",
"android.permission.SEND_SMS": "Premium SMS fraud",
"android.permission.READ_CONTACTS": "Contact harvesting",
"android.permission.READ_CALL_LOG": "Call log theft",
"android.permission.RECORD_AUDIO": "Audio surveillance",
"android.permission.CAMERA": "Camera surveillance",
"android.permission.ACCESS_FINE_LOCATION": "Location tracking",
"android.permission.READ_PHONE_STATE": "Device fingerprinting",
"android.permission.SYSTEM_ALERT_WINDOW": "Overlay attacks",
"android.permission.BIND_ACCESSIBILITY_SERVICE": "Full device control",
"android.permission.REQUEST_INSTALL_PACKAGES": "Sideloading apps",
"android.permission.BIND_DEVICE_ADMIN": "Device admin abuse",
}
print("\nDangerous Permissions:")
for perm in apk.get_permissions():
if perm in dangerous_perms:
print(f" [!] {perm}")
print(f" Risk: {dangerous_perms[perm]}")
elif "android.permission" in perm:
print(f" [*] {perm}")
# Components
print("\nActivities:")
for act in apk.get_activities():
print(f" {act}")
print("\nServices:")
for svc in apk.get_services():
print(f" {svc}")
print("\nReceivers:")
for rcv in apk.get_receivers():
print(f" {rcv}")
PYEOFStep 2: Decompile with JADX
Open the APK in JADX for Java/Kotlin source analysis:
# Open in JADX GUI
jadx-gui malware.apk
# Command-line decompilation for scripted analysis
jadx -d jadx_output/ malware.apk --show-bad-code
# Decompile with all options
jadx -d jadx_output/ malware.apk \
--deobf \
--deobf-min 3 \
--deobf-max 64 \
--show-bad-code \
--threads-count 4
# The output directory structure:
# jadx_output/
# sources/ <- Decompiled Java source code
# com/malware/app/
# MainActivity.java
# C2Service.java
# SMSReceiver.java
# resources/ <- Decoded resources (layouts, strings, assets)
# AndroidManifest.xml
# res/
# assets/Step 3: Identify Malicious Functionality
Search for suspicious code patterns in decompiled sources:
# Search for network communication
grep -rn "HttpURLConnection\|OkHttpClient\|Retrofit\|Volley\|URL(" jadx_output/sources/
# Search for SMS operations
grep -rn "SmsManager\|getDefault().sendTextMessage\|SMS_RECEIVED" jadx_output/sources/
# Search for overlay attack code
grep -rn "SYSTEM_ALERT_WINDOW\|TYPE_APPLICATION_OVERLAY\|WindowManager.LayoutParams" jadx_output/sources/
# Search for accessibility service abuse
grep -rn "AccessibilityService\|onAccessibilityEvent\|performAction" jadx_output/sources/
# Search for data exfiltration
grep -rn "getDeviceId\|getSubscriberId\|getSimSerialNumber\|getLine1Number" jadx_output/sources/
# Search for crypto operations (key storage, encryption)
grep -rn "SecretKeySpec\|Cipher.getInstance\|AES\|DES\|RSA" jadx_output/sources/
# Search for dynamic code loading
grep -rn "DexClassLoader\|PathClassLoader\|loadDex\|loadClass" jadx_output/sources/
# Search for obfuscated strings and decryption
grep -rn "Base64.decode\|decrypt\|decipher\|xor" jadx_output/sources/Step 4: Analyze C2 Communication
Trace the network communication logic:
# Automated C2 extraction from decompiled code
import os
import re
jadx_dir = "jadx_output/sources"
# Patterns for C2 URLs and IPs
url_pattern = re.compile(r'https?://[^\s"\'<>]+')
ip_pattern = re.compile(r'"(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"')
base64_pattern = re.compile(r'"([A-Za-z0-9+/]{20,}={0,2})"')
urls = set()
ips = set()
b64_strings = set()
for root, dirs, files in os.walk(jadx_dir):
for fname in files:
if fname.endswith('.java'):
filepath = os.path.join(root, fname)
with open(filepath, 'r', errors='ignore') as f:
content = f.read()
for match in url_pattern.finditer(content):
urls.add(match.group())
for match in ip_pattern.finditer(content):
ips.add(match.group(1))
for match in base64_pattern.finditer(content):
b64_strings.add(match.group(1))
print("URLs found:")
for u in urls:
print(f" {u}")
print("\nIP addresses:")
for ip in ips:
print(f" {ip}")
# Decode Base64 strings
import base64
print("\nDecoded Base64 strings:")
for b64 in b64_strings:
try:
decoded = base64.b64decode(b64).decode('utf-8', errors='ignore')
if any(c.isprintable() for c in decoded) and len(decoded) > 3:
print(f" {b64[:30]}... -> {decoded[:100]}")
except:
passStep 5: Examine Native Libraries
Check for native code that may contain additional malicious logic:
# List native libraries in the APK
unzip -l malware.apk | grep "\.so$"
# Extract native libraries
unzip malware.apk "lib/*" -d apk_native/
# Check native library properties
file apk_native/lib/armeabi-v7a/*.so
readelf -d apk_native/lib/armeabi-v7a/*.so | grep NEEDED
# Strings from native libraries
strings apk_native/lib/armeabi-v7a/libpayload.so | grep -iE "(http|url|key|encrypt|password)"
# For deep native analysis, import into Ghidra:
# File -> Import -> Select .so file -> Select ARM architectureStep 6: Document Analysis and Extract IOCs
Compile a comprehensive Android malware analysis report:
Analysis documentation should include:
- APK metadata (package name, version, signing certificate)
- Permission analysis with risk assessment
- Component analysis (activities, services, receivers, providers)
- Decompiled code walkthrough of malicious functions
- C2 communication protocol and endpoints
- Data exfiltration methods and targeted data types
- Persistence mechanisms (device admin, accessibility service)
- Evasion techniques (emulator detection, root detection)
- Extracted IOCs (C2 URLs, domains, IPs, signing certificate hash)Key Concepts
| Term | Definition |
|---|---|
| APK (Android Package) | Android application package format containing compiled DEX bytecode, resources, manifest, and native libraries |
| DEX Bytecode | Dalvik Executable format containing compiled Java/Kotlin code; JADX converts this back to readable Java source |
| Overlay Attack | Banking trojan technique displaying a fake UI layer over a legitimate banking app to steal credentials using SYSTEM_ALERT_WINDOW permission |
| Accessibility Service Abuse | Malware registering as an accessibility service to capture screen content, perform actions, and prevent uninstallation |
| Smali | Human-readable representation of DEX bytecode; intermediate representation between bytecode and Java used by apktool |
| Dynamic Code Loading | Loading additional DEX code at runtime using DexClassLoader to hide malicious functionality from static analysis |
| Device Admin Abuse | Malware requesting device administrator privileges to prevent uninstallation and perform device wipe threats |
Tools & Systems
- JADX: Open-source DEX to Java decompiler providing GUI and CLI for Android APK analysis with deobfuscation support
- apktool: Tool for reverse engineering Android APK files to smali code and decoded resources
- androguard: Python framework for automated Android APK analysis including permission, component, and code analysis
- Frida: Dynamic instrumentation toolkit for hooking Java methods and native functions at runtime on Android
- MobSF (Mobile Security Framework): Automated mobile application security testing framework for static and dynamic analysis
Common Scenarios
Scenario: Analyzing an Android Banking Trojan
Context: A banking trojan APK is distributed via SMS phishing targeting customers of a specific bank. The sample needs analysis to identify targeted banks, C2 infrastructure, and data theft mechanisms.
Approach:
- Extract APK metadata and identify requested permissions (SMS, accessibility, overlay, device admin)
- Decompile with JADX and search for overlay activity classes that mimic banking app UIs
- Identify the list of targeted banking apps by searching for package name lists in the code
- Trace the SMS interception receiver to understand how 2FA codes are stolen
- Follow the C2 communication code to extract server URLs and command protocol
- Check for web injection configuration files in assets/ directory
- Extract all IOCs and document the complete attack chain
Pitfalls:
- Not deobfuscating class and method names before analysis (use JADX --deobf flag)
- Missing dynamically loaded DEX files downloaded after installation
- Ignoring native .so libraries that may contain the actual C2 logic or encryption routines
- Overlooking assets/ directory which may contain encrypted configuration or web injects
Output Format
ANDROID MALWARE ANALYSIS REPORT
==================================
APK File: update_bank.apk
Package: com.android.systemupdate
SHA-256: e3b0c44298fc1c149afbf4c8996fb924...
Version: 1.2.3
Min SDK: 21 (Android 5.0)
Signing Cert: SHA-256: abc123... (self-signed)
CLASSIFICATION
Family: Anubis Banking Trojan
Type: Banking Trojan / SMS Stealer / Keylogger
DANGEROUS PERMISSIONS
[!] RECEIVE_SMS - Intercepts incoming SMS (2FA theft)
[!] READ_SMS - Reads SMS messages
[!] SEND_SMS - Sends premium SMS
[!] SYSTEM_ALERT_WINDOW - Overlay attacks on banking apps
[!] BIND_ACCESSIBILITY - Full device control
[!] BIND_DEVICE_ADMIN - Prevents uninstallation
MALICIOUS COMPONENTS
Service: com.android.systemupdate.C2Service (C2 communication)
Receiver: com.android.systemupdate.SmsReceiver (SMS interception)
Activity: com.android.systemupdate.OverlayActivity (credential overlay)
TARGETED APPS (23 banking apps)
com.bank.example1, com.bank.example2, ...
C2 INFRASTRUCTURE
Primary: hxxps://c2-server[.]com/api/bot
Fallback: hxxps://backup-c2[.]net/api/bot
Protocol: HTTPS POST with JSON body
Bot ID: MD5(IMEI + Build.SERIAL)
EXTRACTED IOCs
Domains: c2-server[.]com, backup-c2[.]net
IPs: 185.220.101[.]42
URLs: hxxps://c2-server[.]com/api/bot
hxxps://c2-server[.]com/api/injects
Cert Hash: abc123def456...References and resources
Everything below is rendered for inspection. Script files are read-only and never run.
References 1
api-reference.md2.4 KB
API Reference: Android Malware Reverse Engineering with JADX Agent
Overview
Reverse engineers Android APKs using apktool for manifest extraction, JADX for Java decompilation, and regex-based source code analysis for malicious patterns (C2 URLs, SMS interception, overlay attacks).
Dependencies
| Package | Version | Purpose |
|---|---|---|
| hashlib | stdlib | APK hash computation |
| xml.etree | stdlib | AndroidManifest.xml parsing |
External Tools Required
| Tool | Purpose |
|---|---|
| apktool | APK disassembly and manifest extraction |
| jadx | DEX to Java decompilation with deobfuscation |
Core Functions
compute_apk_hashes(apk_path)
Generates MD5 and SHA-256 hashes for APK identification.
extract_manifest(apk_path, output_dir)
Extracts AndroidManifest.xml and parses permissions, activities, services, receivers.
- Returns:
dictwithpackage,permissions,activities,services,receivers
analyze_permissions(permissions)
Classifies permissions against a list of 16 dangerous Android permissions.
- Risk: CRITICAL if SMS/accessibility/device-admin, HIGH if >5 dangerous
- Returns:
dictwith categorized permission lists and risk level
decompile_with_jadx(apk_path, output_dir)
Runs JADX with --deobf flag for deobfuscated Java source output.
- Timeout: 300 seconds
search_source_code(source_dir, patterns)
Searches decompiled Java source for 10 malicious pattern categories.
- Returns:
dict[str, list[dict]]- pattern name to file/match pairs
analyze_apk(apk_path, output_base)
Full pipeline: hashes -> manifest -> permissions -> decompile -> code analysis.
Malicious Code Patterns
| Pattern | Indicator |
|---|---|
| urls | HTTP/HTTPS C2 server addresses |
| ips | Hardcoded IP addresses |
| exec_commands | Runtime.exec() shell command execution |
| reflection | Class.forName() dynamic class loading |
| dex_loading | DexClassLoader for loading additional code |
| overlay_attack | TYPE_APPLICATION_OVERLAY for phishing overlays |
| accessibility_abuse | AccessibilityService for keylogging/automation |
| sms_intercept | SMS_RECEIVED broadcast interception |
Dangerous Permissions Checked
READ_SMS, SEND_SMS, RECEIVE_SMS, READ_CONTACTS, CAMERA, RECORD_AUDIO, ACCESS_FINE_LOCATION, READ_PHONE_STATE, BIND_ACCESSIBILITY_SERVICE, BIND_DEVICE_ADMIN, REQUEST_INSTALL_PACKAGES
Usage
python agent.py malware.apkScripts 1
agent.py7.6 KB
#!/usr/bin/env python3
"""Android malware reverse engineering agent using jadx and androguard subprocess wrappers."""
import subprocess
import os
import sys
import re
import hashlib
from xml.etree import ElementTree
def compute_apk_hashes(apk_path):
"""Compute hashes for APK identification."""
with open(apk_path, "rb") as f:
data = f.read()
return {
"md5": hashlib.md5(data).hexdigest(),
"sha256": hashlib.sha256(data).hexdigest(),
"size": len(data),
}
def extract_manifest(apk_path, output_dir):
"""Extract and parse AndroidManifest.xml using apktool."""
subprocess.run(
["apktool", "d", apk_path, "-o", output_dir, "-f"],
capture_output=True, text=True, timeout=120
)
manifest_path = os.path.join(output_dir, "AndroidManifest.xml")
if not os.path.exists(manifest_path):
return {"error": "Manifest extraction failed"}
tree = ElementTree.parse(manifest_path)
root = tree.getroot()
ns = {"android": "http://schemas.android.com/apk/res/android"}
permissions = []
for perm in root.findall(".//uses-permission"):
name = perm.get(f"{{{ns['android']}}}name", "")
permissions.append(name)
activities = []
for act in root.findall(".//activity"):
name = act.get(f"{{{ns['android']}}}name", "")
exported = act.get(f"{{{ns['android']}}}exported", "false")
activities.append({"name": name, "exported": exported})
services = []
for svc in root.findall(".//service"):
name = svc.get(f"{{{ns['android']}}}name", "")
services.append(name)
receivers = []
for rcv in root.findall(".//receiver"):
name = rcv.get(f"{{{ns['android']}}}name", "")
intents = []
for intent in rcv.findall(".//intent-filter/action"):
intents.append(intent.get(f"{{{ns['android']}}}name", ""))
receivers.append({"name": name, "intents": intents})
package = root.get("package", "")
return {
"package": package,
"permissions": permissions,
"activities": activities,
"services": services,
"receivers": receivers,
}
DANGEROUS_PERMISSIONS = [
"android.permission.READ_SMS", "android.permission.SEND_SMS",
"android.permission.RECEIVE_SMS", "android.permission.READ_CONTACTS",
"android.permission.CAMERA", "android.permission.RECORD_AUDIO",
"android.permission.ACCESS_FINE_LOCATION", "android.permission.READ_PHONE_STATE",
"android.permission.CALL_PHONE", "android.permission.READ_CALL_LOG",
"android.permission.WRITE_EXTERNAL_STORAGE", "android.permission.READ_EXTERNAL_STORAGE",
"android.permission.SYSTEM_ALERT_WINDOW", "android.permission.BIND_ACCESSIBILITY_SERVICE",
"android.permission.REQUEST_INSTALL_PACKAGES", "android.permission.BIND_DEVICE_ADMIN",
]
def analyze_permissions(permissions):
"""Classify permissions by risk level."""
dangerous = [p for p in permissions if p in DANGEROUS_PERMISSIONS]
sms_related = [p for p in permissions if "SMS" in p]
accessibility = [p for p in permissions if "ACCESSIBILITY" in p]
admin = [p for p in permissions if "DEVICE_ADMIN" in p or "BIND_ADMIN" in p]
risk = "LOW"
if len(dangerous) > 5:
risk = "HIGH"
if sms_related or accessibility or admin:
risk = "CRITICAL"
return {
"total": len(permissions),
"dangerous": dangerous,
"sms_related": sms_related,
"accessibility": accessibility,
"device_admin": admin,
"risk": risk,
}
def decompile_with_jadx(apk_path, output_dir):
"""Decompile APK to Java source using JADX."""
result = subprocess.run(
["jadx", "-d", output_dir, "--deobf", apk_path],
capture_output=True, text=True, timeout=300
)
return {
"output_dir": output_dir,
"returncode": result.returncode,
"stdout": result.stdout[-500:] if result.stdout else "",
}
def search_source_code(source_dir, patterns=None):
"""Search decompiled source for suspicious patterns."""
if patterns is None:
patterns = {
"urls": r'https?://[^\s"\'<>]+',
"ips": r'\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b',
"crypto_keys": r'(?:AES|DES|RSA|key|secret|encrypt).*?["\']([^"\']{8,})["\']',
"base64_strings": r'[A-Za-z0-9+/]{40,}={0,2}',
"exec_commands": r'Runtime\.getRuntime\(\)\.exec|ProcessBuilder',
"reflection": r'Class\.forName|getMethod|getDeclaredMethod',
"dex_loading": r'DexClassLoader|PathClassLoader|InMemoryDexClassLoader',
"overlay_attack": r'TYPE_APPLICATION_OVERLAY|SYSTEM_ALERT_WINDOW',
"accessibility_abuse": r'AccessibilityService|onAccessibilityEvent',
"sms_intercept": r'SmsReceiver|SMS_RECEIVED|sendTextMessage',
}
findings = {p: [] for p in patterns}
for root, dirs, files in os.walk(source_dir):
for filename in files:
if not filename.endswith(".java"):
continue
filepath = os.path.join(root, filename)
try:
with open(filepath, "r", errors="ignore") as f:
content = f.read()
for pattern_name, regex in patterns.items():
matches = re.findall(regex, content)
if matches:
findings[pattern_name].extend([
{"file": filepath, "match": m[:100]} for m in matches[:5]
])
except (OSError, UnicodeDecodeError):
pass
for key in findings:
findings[key] = findings[key][:20]
return findings
def analyze_apk(apk_path, output_base="/tmp/apk_analysis"):
"""Full APK analysis pipeline."""
os.makedirs(output_base, exist_ok=True)
report = {"apk": apk_path}
report["hashes"] = compute_apk_hashes(apk_path)
apktool_dir = os.path.join(output_base, "apktool")
report["manifest"] = extract_manifest(apk_path, apktool_dir)
if "permissions" in report["manifest"]:
report["permission_analysis"] = analyze_permissions(report["manifest"]["permissions"])
jadx_dir = os.path.join(output_base, "jadx_output")
report["decompilation"] = decompile_with_jadx(apk_path, jadx_dir)
if os.path.exists(jadx_dir):
source_dir = os.path.join(jadx_dir, "sources")
if os.path.exists(source_dir):
report["code_analysis"] = search_source_code(source_dir)
return report
def print_report(report):
print("Android Malware Analysis Report")
print("=" * 50)
print(f"APK: {report['apk']}")
print(f"SHA-256: {report['hashes']['sha256']}")
print(f"Size: {report['hashes']['size']} bytes")
manifest = report.get("manifest", {})
print(f"\nPackage: {manifest.get('package', 'N/A')}")
perm = report.get("permission_analysis", {})
print(f"Permissions: {perm.get('total', 0)} (Risk: {perm.get('risk', 'N/A')})")
if perm.get("dangerous"):
print(f" Dangerous: {', '.join(p.split('.')[-1] for p in perm['dangerous'][:8])}")
print(f"Activities: {len(manifest.get('activities', []))}")
print(f"Services: {len(manifest.get('services', []))}")
print(f"Receivers: {len(manifest.get('receivers', []))}")
code = report.get("code_analysis", {})
if code:
print("\nCode Analysis Findings:")
for pattern, matches in code.items():
if matches:
print(f" {pattern}: {len(matches)} match(es)")
for m in matches[:3]:
print(f" -> {m['match'][:80]}")
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python agent.py <apk_file>")
sys.exit(1)
result = analyze_apk(sys.argv[1])
print_report(result)