mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-06-26 03:34:37 +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,206 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Ransomware Attack Artifact Investigation Agent
|
||||
Collects and analyzes ransomware artifacts including ransom notes, encrypted
|
||||
file samples, registry modifications, and event logs to identify the variant,
|
||||
attack vector, and encryption scope.
|
||||
"""
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
|
||||
import requests
|
||||
|
||||
|
||||
RANSOMWARE_ID_URL = "https://id-ransomware.malwarehunterteam.com/api/"
|
||||
VT_API_KEY = ""
|
||||
|
||||
|
||||
def collect_ransom_notes(search_root: str) -> list[dict]:
|
||||
"""Search filesystem for common ransom note filenames."""
|
||||
ransom_note_patterns = [
|
||||
"README.txt", "DECRYPT*.txt", "HOW_TO_DECRYPT*", "RECOVER*",
|
||||
"_readme.txt", "!README!*", "HELP_DECRYPT*", "YOUR_FILES*",
|
||||
"ATTENTION*.txt", "RESTORE*FILES*", "#DECRYPT#*", "info.hta",
|
||||
]
|
||||
found_notes = []
|
||||
root = Path(search_root)
|
||||
|
||||
for pattern in ransom_note_patterns:
|
||||
for match in root.rglob(pattern):
|
||||
if match.is_file() and match.stat().st_size < 1_000_000:
|
||||
with open(match, "r", errors="ignore") as f:
|
||||
content = f.read(4096)
|
||||
found_notes.append({
|
||||
"path": str(match),
|
||||
"filename": match.name,
|
||||
"size": match.stat().st_size,
|
||||
"content_preview": content[:500],
|
||||
"sha256": hashlib.sha256(content.encode()).hexdigest(),
|
||||
})
|
||||
|
||||
return found_notes
|
||||
|
||||
|
||||
def identify_encrypted_files(search_root: str) -> dict:
|
||||
"""Identify encrypted files by extension and calculate scope."""
|
||||
known_extensions = [
|
||||
".encrypted", ".locked", ".crypto", ".crypt", ".enc",
|
||||
".locky", ".zepto", ".cerber", ".dharma", ".phobos",
|
||||
".ryuk", ".conti", ".lockbit", ".blackcat", ".hive",
|
||||
".akira", ".royal", ".play", ".clop", ".alphv",
|
||||
]
|
||||
encrypted_files = []
|
||||
extension_counts = {}
|
||||
total_size = 0
|
||||
|
||||
root = Path(search_root)
|
||||
for filepath in root.rglob("*"):
|
||||
if filepath.is_file():
|
||||
ext = filepath.suffix.lower()
|
||||
if ext in known_extensions:
|
||||
encrypted_files.append(str(filepath))
|
||||
extension_counts[ext] = extension_counts.get(ext, 0) + 1
|
||||
total_size += filepath.stat().st_size
|
||||
|
||||
return {
|
||||
"total_encrypted_files": len(encrypted_files),
|
||||
"total_encrypted_size_gb": round(total_size / (1024**3), 2),
|
||||
"extensions_found": extension_counts,
|
||||
"sample_files": encrypted_files[:20],
|
||||
}
|
||||
|
||||
|
||||
def analyze_ransom_note_content(notes: list[dict]) -> dict:
|
||||
"""Extract IOCs and payment details from ransom notes."""
|
||||
bitcoin_pattern = re.compile(r"[13][a-km-zA-HJ-NP-Z1-9]{25,34}|bc1[a-z0-9]{39,59}")
|
||||
monero_pattern = re.compile(r"4[0-9AB][1-9A-HJ-NP-Za-km-z]{93}")
|
||||
tor_pattern = re.compile(r"[a-z2-7]{16,56}\.onion")
|
||||
email_pattern = re.compile(r"[\w.+-]+@[\w-]+\.[a-zA-Z]{2,}")
|
||||
|
||||
iocs = {"bitcoin_addresses": set(), "monero_addresses": set(),
|
||||
"tor_sites": set(), "email_contacts": set(), "ransom_amounts": []}
|
||||
|
||||
for note in notes:
|
||||
content = note.get("content_preview", "")
|
||||
for match in bitcoin_pattern.findall(content):
|
||||
iocs["bitcoin_addresses"].add(match)
|
||||
for match in monero_pattern.findall(content):
|
||||
iocs["monero_addresses"].add(match)
|
||||
for match in tor_pattern.findall(content):
|
||||
iocs["tor_sites"].add(match)
|
||||
for match in email_pattern.findall(content):
|
||||
iocs["email_contacts"].add(match)
|
||||
|
||||
amount_match = re.search(r"\$\s?([\d,]+)", content)
|
||||
if amount_match:
|
||||
iocs["ransom_amounts"].append(amount_match.group(0))
|
||||
|
||||
return {k: sorted(v) if isinstance(v, set) else v for k, v in iocs.items()}
|
||||
|
||||
|
||||
def check_hash_virustotal(file_hash: str, api_key: str) -> dict:
|
||||
"""Look up file hash on VirusTotal for ransomware identification."""
|
||||
if not api_key:
|
||||
return {"error": "VT_API_KEY not configured"}
|
||||
resp = requests.get(
|
||||
f"https://www.virustotal.com/api/v3/files/{file_hash}",
|
||||
headers={"x-apikey": api_key}, timeout=30,
|
||||
)
|
||||
if resp.status_code == 200:
|
||||
attrs = resp.json().get("data", {}).get("attributes", {})
|
||||
return {
|
||||
"threat_label": attrs.get("popular_threat_classification", {}).get(
|
||||
"suggested_threat_label", "unknown"),
|
||||
"detection_ratio": f"{attrs.get('last_analysis_stats', {}).get('malicious', 0)}"
|
||||
f"/{sum(attrs.get('last_analysis_stats', {}).values())}",
|
||||
"first_seen": attrs.get("first_submission_date", ""),
|
||||
"names": attrs.get("names", [])[:5],
|
||||
}
|
||||
return {"error": f"VT lookup failed: {resp.status_code}"}
|
||||
|
||||
|
||||
def parse_windows_event_logs(evtx_export_path: str) -> list[dict]:
|
||||
"""Parse exported Windows event log CSV for ransomware indicators."""
|
||||
events = []
|
||||
if not os.path.exists(evtx_export_path):
|
||||
return events
|
||||
|
||||
import csv
|
||||
with open(evtx_export_path, "r", newline="", errors="ignore") as f:
|
||||
reader = csv.DictReader(f)
|
||||
for row in reader:
|
||||
event_id = row.get("EventID", row.get("event_id", ""))
|
||||
suspicious_ids = ["1102", "4688", "4697", "7045", "1116", "4624"]
|
||||
if str(event_id) in suspicious_ids:
|
||||
events.append({
|
||||
"timestamp": row.get("TimeCreated", row.get("timestamp", "")),
|
||||
"event_id": event_id,
|
||||
"source": row.get("ProviderName", row.get("source", "")),
|
||||
"message": row.get("Message", row.get("message", ""))[:300],
|
||||
})
|
||||
|
||||
return events
|
||||
|
||||
|
||||
def generate_report(notes: list, encrypted: dict, iocs: dict, events: list) -> str:
|
||||
"""Generate ransomware investigation report."""
|
||||
lines = [
|
||||
"RANSOMWARE ATTACK ARTIFACT INVESTIGATION REPORT",
|
||||
"=" * 55,
|
||||
f"Investigation Date: {datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M UTC')}",
|
||||
"",
|
||||
"RANSOM NOTES:",
|
||||
f" Notes Found: {len(notes)}",
|
||||
]
|
||||
for note in notes[:5]:
|
||||
lines.append(f" - {note['filename']} ({note['path']})")
|
||||
|
||||
lines.extend([
|
||||
"",
|
||||
"ENCRYPTION SCOPE:",
|
||||
f" Encrypted Files: {encrypted['total_encrypted_files']}",
|
||||
f" Total Size: {encrypted['total_encrypted_size_gb']} GB",
|
||||
f" Extensions: {json.dumps(encrypted['extensions_found'])}",
|
||||
"",
|
||||
"EXTRACTED IOCs:",
|
||||
f" Bitcoin Addresses: {len(iocs.get('bitcoin_addresses', []))}",
|
||||
f" Tor Sites: {len(iocs.get('tor_sites', []))}",
|
||||
f" Contact Emails: {len(iocs.get('email_contacts', []))}",
|
||||
"",
|
||||
f"SUSPICIOUS EVENTS: {len(events)}",
|
||||
])
|
||||
for evt in events[:10]:
|
||||
lines.append(f" [{evt['event_id']}] {evt['timestamp']} - {evt['message'][:80]}")
|
||||
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
VT_API_KEY = os.getenv("VT_API_KEY", VT_API_KEY)
|
||||
search_root = sys.argv[1] if len(sys.argv) > 1 else "."
|
||||
evtx_path = sys.argv[2] if len(sys.argv) > 2 else "events.csv"
|
||||
|
||||
print(f"[*] Investigating ransomware artifacts in: {search_root}")
|
||||
|
||||
notes = collect_ransom_notes(search_root)
|
||||
print(f"[*] Found {len(notes)} ransom notes")
|
||||
|
||||
encrypted = identify_encrypted_files(search_root)
|
||||
print(f"[*] Found {encrypted['total_encrypted_files']} encrypted files")
|
||||
|
||||
iocs = analyze_ransom_note_content(notes)
|
||||
events = parse_windows_event_logs(evtx_path)
|
||||
|
||||
report = generate_report(notes, encrypted, iocs, events)
|
||||
print(report)
|
||||
|
||||
output = f"ransomware_investigation_{datetime.now(timezone.utc).strftime('%Y%m%d')}.json"
|
||||
with open(output, "w") as f:
|
||||
json.dump({"ransom_notes": notes, "encrypted_files": encrypted, "iocs": iocs, "events": events}, f, indent=2)
|
||||
print(f"\n[*] Results saved to {output}")
|
||||
Reference in New Issue
Block a user