mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-06-13 06:34:57 +03:00
c21af3347e
- Add scripts/agent.py and references/api-reference.md to all remaining skills - Update all 648 LICENSE files: copyright now reads 'Mahipal' - Add implementing-security-monitoring-with-datadog (new skill with full anatomy) - All 649 skills now have: SKILL.md, LICENSE, scripts/agent.py, references/api-reference.md
128 lines
5.1 KiB
Python
128 lines
5.1 KiB
Python
#!/usr/bin/env python3
|
|
"""Mobile application penetration testing agent using Frida and objection."""
|
|
|
|
import json
|
|
import sys
|
|
import argparse
|
|
import subprocess
|
|
from datetime import datetime
|
|
|
|
|
|
def run_apktool_decompile(apk_path):
|
|
"""Decompile Android APK for static analysis."""
|
|
cmd = ["apktool", "d", apk_path, "-o", f"{apk_path}_decompiled", "-f"]
|
|
try:
|
|
result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
|
|
return {"status": "completed", "output_dir": f"{apk_path}_decompiled"}
|
|
except FileNotFoundError:
|
|
return {"status": "error", "message": "apktool not installed"}
|
|
|
|
|
|
def check_android_manifest(manifest_path):
|
|
"""Analyze AndroidManifest.xml for security issues."""
|
|
findings = []
|
|
try:
|
|
with open(manifest_path, "r") as f:
|
|
content = f.read()
|
|
checks = [
|
|
("android:debuggable=\"true\"", "App is debuggable", "HIGH"),
|
|
("android:allowBackup=\"true\"", "App allows backup extraction", "MEDIUM"),
|
|
("android:exported=\"true\"", "Exported component found", "MEDIUM"),
|
|
("android:usesCleartextTraffic=\"true\"", "Cleartext traffic allowed", "HIGH"),
|
|
("android.permission.WRITE_EXTERNAL_STORAGE", "External storage write", "LOW"),
|
|
("android.permission.READ_PHONE_STATE", "Phone state access", "MEDIUM"),
|
|
]
|
|
for pattern, desc, severity in checks:
|
|
if pattern.lower() in content.lower():
|
|
findings.append({"finding": desc, "pattern": pattern, "severity": severity})
|
|
except FileNotFoundError:
|
|
findings.append({"error": f"Manifest not found: {manifest_path}"})
|
|
return findings
|
|
|
|
|
|
def scan_hardcoded_secrets(source_dir):
|
|
"""Scan decompiled source for hardcoded secrets."""
|
|
import re
|
|
patterns = {
|
|
"API Key": re.compile(r'["\'](?:api[_-]?key|apikey)["\']?\s*[:=]\s*["\']([^"\']{20,})["\']', re.I),
|
|
"AWS Key": re.compile(r'AKIA[0-9A-Z]{16}'),
|
|
"Private Key": re.compile(r'-----BEGIN (?:RSA )?PRIVATE KEY-----'),
|
|
"Password": re.compile(r'["\'](?:password|passwd|pwd)["\']?\s*[:=]\s*["\']([^"\']+)["\']', re.I),
|
|
"Firebase URL": re.compile(r'https://[a-z0-9-]+\.firebaseio\.com'),
|
|
}
|
|
findings = []
|
|
import os
|
|
for root, _, files in os.walk(source_dir):
|
|
for fname in files:
|
|
if fname.endswith((".smali", ".java", ".xml", ".json", ".properties")):
|
|
fpath = os.path.join(root, fname)
|
|
try:
|
|
with open(fpath, "r", errors="ignore") as f:
|
|
content = f.read()
|
|
for secret_type, pattern in patterns.items():
|
|
matches = pattern.findall(content)
|
|
for match in matches:
|
|
findings.append({
|
|
"type": secret_type,
|
|
"file": os.path.relpath(fpath, source_dir),
|
|
"severity": "CRITICAL" if "key" in secret_type.lower() else "HIGH",
|
|
})
|
|
except OSError:
|
|
pass
|
|
return findings
|
|
|
|
|
|
def check_ssl_pinning(package_name):
|
|
"""Check for SSL pinning implementation."""
|
|
cmd = ["objection", "-g", package_name, "run", "android", "sslpinning", "disable"]
|
|
try:
|
|
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
|
|
return {"ssl_pinning": "enabled" if "error" not in result.stdout.lower() else "not_detected"}
|
|
except FileNotFoundError:
|
|
return {"status": "error", "message": "objection not installed: pip install objection"}
|
|
|
|
|
|
def run_pentest(apk_path):
|
|
"""Execute mobile application penetration test."""
|
|
print(f"\n{'='*60}")
|
|
print(f" MOBILE APP PENETRATION TEST")
|
|
print(f" APK: {apk_path}")
|
|
print(f" Generated: {datetime.utcnow().isoformat()} UTC")
|
|
print(f"{'='*60}\n")
|
|
|
|
decomp = run_apktool_decompile(apk_path)
|
|
print(f"--- DECOMPILATION ---")
|
|
print(f" Status: {decomp['status']}")
|
|
|
|
if decomp["status"] == "completed":
|
|
manifest = check_android_manifest(f"{decomp['output_dir']}/AndroidManifest.xml")
|
|
print(f"\n--- MANIFEST ANALYSIS ({len(manifest)} findings) ---")
|
|
for f in manifest:
|
|
if "error" not in f:
|
|
print(f" [{f['severity']}] {f['finding']}")
|
|
|
|
secrets = scan_hardcoded_secrets(decomp["output_dir"])
|
|
print(f"\n--- HARDCODED SECRETS ({len(secrets)} findings) ---")
|
|
for s in secrets[:10]:
|
|
print(f" [{s['severity']}] {s['type']} in {s['file']}")
|
|
|
|
return {"decompilation": decomp, "manifest": manifest, "secrets": secrets}
|
|
return {"decompilation": decomp}
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description="Mobile App Pentest Agent")
|
|
parser.add_argument("--apk", required=True, help="Path to APK file")
|
|
parser.add_argument("--output", help="Save report to JSON file")
|
|
args = parser.parse_args()
|
|
|
|
report = run_pentest(args.apk)
|
|
if args.output:
|
|
with open(args.output, "w") as f:
|
|
json.dump(report, f, indent=2, default=str)
|
|
print(f"\n[+] Report saved to {args.output}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|