mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-06-12 14:14:56 +03:00
c47eed6a64
- Fix 25 shell=True subprocess calls with list-based commands - Fix 49 verify=False in defensive skills (env-var override) - Add timeout to 231 HTTP/subprocess/socket calls - Fix 6 SQL injection patterns with whitelist validation - Replace 8 __import__() with standard imports - Remove 701 unused imports across 442 files - Add authorized-testing disclaimers to all offensive skills - Complete 11 incomplete skill directories - Expand 10 stub SKILL.md files with full content - Fix 2 YAML parse errors in frontmatter - Fix 5 pre-existing syntax errors - Convert 22 hardcoded paths/ports to environment variables - Back up 21 redundant skill pairs to .bak - Fix 2 global declaration errors - 724/724 skills with full folder anatomy (SKILL.md + agent.py + api-reference.md + LICENSE) - 0 compile errors across all 724 agent.py files
153 lines
5.7 KiB
Python
153 lines
5.7 KiB
Python
#!/usr/bin/env python3
|
|
"""Autoruns Persistence Analysis Agent - Analyzes Windows autostart entries for malware persistence."""
|
|
|
|
import json
|
|
import csv
|
|
import re
|
|
import logging
|
|
import argparse
|
|
from datetime import datetime
|
|
from collections import Counter
|
|
|
|
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
|
|
logger = logging.getLogger(__name__)
|
|
|
|
SUSPICIOUS_PATHS = [
|
|
r"\\temp\\", r"\\tmp\\", r"\\appdata\\local\\temp",
|
|
r"\\public\\", r"\\programdata\\", r"\\users\\default",
|
|
r"\\recycler\\", r"\\windows\\debug",
|
|
]
|
|
|
|
SUSPICIOUS_COMMANDS = [
|
|
"powershell", "cmd.exe /c", "wscript", "cscript", "mshta",
|
|
"regsvr32", "rundll32", "certutil", "bitsadmin",
|
|
"schtasks", "msiexec /q", "forfiles",
|
|
]
|
|
|
|
KNOWN_PERSISTENCE_LOCATIONS = [
|
|
"HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",
|
|
"HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",
|
|
"HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
|
|
"HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
|
|
"HKLM\\SYSTEM\\CurrentControlSet\\Services",
|
|
"Task Scheduler",
|
|
"Startup Folder",
|
|
"WMI",
|
|
]
|
|
|
|
|
|
def parse_autoruns_csv(csv_file):
|
|
"""Parse Autoruns CSV export file."""
|
|
entries = []
|
|
with open(csv_file, "r", encoding="utf-8-sig", errors="ignore") as f:
|
|
reader = csv.DictReader(f, delimiter=",")
|
|
for row in reader:
|
|
entries.append({
|
|
"time": row.get("Time", ""),
|
|
"entry_location": row.get("Entry Location", ""),
|
|
"entry": row.get("Entry", ""),
|
|
"enabled": row.get("Enabled", ""),
|
|
"category": row.get("Category", ""),
|
|
"profile": row.get("Profile", ""),
|
|
"description": row.get("Description", ""),
|
|
"company": row.get("Company", ""),
|
|
"image_path": row.get("Image Path", ""),
|
|
"version": row.get("Version", ""),
|
|
"launch_string": row.get("Launch String", ""),
|
|
"md5": row.get("MD5", ""),
|
|
"sha1": row.get("SHA-1", ""),
|
|
"sha256": row.get("SHA-256", ""),
|
|
"signer": row.get("Signer", ""),
|
|
"vt_detection": row.get("VT detection", ""),
|
|
})
|
|
logger.info("Parsed %d autoruns entries from %s", len(entries), csv_file)
|
|
return entries
|
|
|
|
|
|
def analyze_entry(entry):
|
|
"""Analyze a single autoruns entry for suspicious indicators."""
|
|
findings = []
|
|
image_path = (entry.get("image_path") or "").lower()
|
|
launch_string = (entry.get("launch_string") or "").lower()
|
|
signer = entry.get("signer") or ""
|
|
vt = entry.get("vt_detection") or ""
|
|
company = entry.get("company") or ""
|
|
|
|
for pattern in SUSPICIOUS_PATHS:
|
|
if re.search(pattern, image_path, re.IGNORECASE):
|
|
findings.append({"type": "Suspicious file path", "severity": "high", "detail": image_path})
|
|
break
|
|
|
|
for cmd in SUSPICIOUS_COMMANDS:
|
|
if cmd.lower() in launch_string:
|
|
findings.append({"type": "LOLBin in launch string", "severity": "high", "detail": cmd})
|
|
break
|
|
|
|
if signer in ("(Not verified)", "") or "(Not verified)" in signer:
|
|
findings.append({"type": "Unsigned binary", "severity": "medium", "detail": signer})
|
|
|
|
if vt and "/" in vt:
|
|
try:
|
|
detections, total = vt.split("/")
|
|
if int(detections.strip()) > 0:
|
|
findings.append({"type": "VirusTotal detections", "severity": "critical", "detail": vt})
|
|
except (ValueError, AttributeError):
|
|
pass
|
|
|
|
if not company and entry.get("enabled") == "enabled":
|
|
findings.append({"type": "No company info", "severity": "low", "detail": "Enabled entry without publisher"})
|
|
|
|
return findings
|
|
|
|
|
|
def analyze_all_entries(entries):
|
|
"""Analyze all autoruns entries and generate findings."""
|
|
all_findings = []
|
|
for entry in entries:
|
|
entry_findings = analyze_entry(entry)
|
|
if entry_findings:
|
|
all_findings.append({
|
|
"entry": entry.get("entry"),
|
|
"location": entry.get("entry_location"),
|
|
"category": entry.get("category"),
|
|
"image_path": entry.get("image_path"),
|
|
"findings": entry_findings,
|
|
"max_severity": max((f["severity"] for f in entry_findings), key=lambda s: {"critical": 4, "high": 3, "medium": 2, "low": 1}.get(s, 0)),
|
|
})
|
|
return all_findings
|
|
|
|
|
|
def generate_report(entries, findings):
|
|
"""Generate persistence analysis report."""
|
|
categories = Counter(e.get("category", "Unknown") for e in entries)
|
|
critical = [f for f in findings if f["max_severity"] == "critical"]
|
|
report = {
|
|
"timestamp": datetime.utcnow().isoformat(),
|
|
"total_entries": len(entries),
|
|
"enabled_entries": len([e for e in entries if e.get("enabled") == "enabled"]),
|
|
"suspicious_entries": len(findings),
|
|
"critical_entries": len(critical),
|
|
"category_breakdown": dict(categories.most_common()),
|
|
"findings": findings,
|
|
}
|
|
print(f"AUTORUNS REPORT: {len(entries)} entries, {len(findings)} suspicious, {len(critical)} critical")
|
|
return report
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description="Autoruns Persistence Analysis Agent")
|
|
parser.add_argument("--csv-file", required=True, help="Autoruns CSV export file")
|
|
parser.add_argument("--output", default="autoruns_report.json")
|
|
args = parser.parse_args()
|
|
|
|
entries = parse_autoruns_csv(args.csv_file)
|
|
findings = analyze_all_entries(entries)
|
|
report = generate_report(entries, findings)
|
|
with open(args.output, "w") as f:
|
|
json.dump(report, f, indent=2)
|
|
logger.info("Report saved to %s", args.output)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|