mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-18 21:49:40 +03:00
Add folder anatomy (scripts/agent.py + references/api-reference.md) for 648 cybersecurity skills
Complete skill folder anatomy across all cybersecurity skills: - scripts/agent.py: 80-150 line Python agents using real libraries (impacket, boto3, azure-mgmt-*, kubernetes, pefile, yara, scapy, shodan, stix2, etc.) - references/api-reference.md: real API documentation with method signatures - LICENSE: MIT license for all skill folders
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Anthropic Agent Skills Contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,67 @@
|
||||
# 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**: `dict` with `package`, `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**: `dict` with 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
|
||||
|
||||
```bash
|
||||
python agent.py malware.apk
|
||||
```
|
||||
@@ -0,0 +1,198 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Android malware reverse engineering agent using jadx and androguard subprocess wrappers."""
|
||||
|
||||
import subprocess
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import re
|
||||
import hashlib
|
||||
import zipfile
|
||||
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)
|
||||
Reference in New Issue
Block a user