mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-06-12 22:24: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
123 lines
4.6 KiB
Python
123 lines
4.6 KiB
Python
#!/usr/bin/env python3
|
|
"""Agent for performing endpoint vulnerability remediation tracking and validation."""
|
|
|
|
import json
|
|
import argparse
|
|
import subprocess
|
|
import csv
|
|
from datetime import datetime
|
|
|
|
|
|
def parse_scan_report(csv_file):
|
|
"""Parse a vulnerability scan CSV report and prioritize remediation."""
|
|
with open(csv_file, "r", encoding="utf-8", errors="replace") as f:
|
|
reader = csv.DictReader(f)
|
|
rows = list(reader)
|
|
vulns = []
|
|
for row in rows:
|
|
severity = row.get("Severity", row.get("severity", row.get("Risk", ""))).lower()
|
|
vulns.append({
|
|
"host": row.get("Host", row.get("IP", row.get("ip", ""))),
|
|
"port": row.get("Port", row.get("port", "")),
|
|
"cve": row.get("CVE", row.get("cve", row.get("Plugin ID", ""))),
|
|
"title": row.get("Name", row.get("title", row.get("Summary", "")))[:200],
|
|
"severity": severity,
|
|
"solution": row.get("Solution", row.get("Fix", ""))[:300],
|
|
})
|
|
by_severity = {}
|
|
for v in vulns:
|
|
s = v["severity"]
|
|
by_severity[s] = by_severity.get(s, 0) + 1
|
|
critical_high = [v for v in vulns if v["severity"] in ("critical", "high")]
|
|
return {
|
|
"total_vulns": len(vulns),
|
|
"by_severity": by_severity,
|
|
"critical_high_count": len(critical_high),
|
|
"remediation_queue": sorted(critical_high, key=lambda x: 0 if x["severity"] == "critical" else 1),
|
|
}
|
|
|
|
|
|
def check_windows_patches():
|
|
"""Check installed Windows patches and identify missing ones."""
|
|
try:
|
|
result = subprocess.run(
|
|
["wmic", "qfe", "get", "HotFixID,InstalledOn,Description", "/format:csv"],
|
|
capture_output=True, text=True, timeout=30
|
|
)
|
|
from io import StringIO
|
|
reader = csv.DictReader(StringIO(result.stdout))
|
|
patches = [{"id": r.get("HotFixID"), "date": r.get("InstalledOn"), "desc": r.get("Description")}
|
|
for r in reader if r.get("HotFixID")]
|
|
return {"installed_patches": len(patches), "patches": patches}
|
|
except Exception as e:
|
|
return {"error": str(e)}
|
|
|
|
|
|
def validate_remediation(host, port, check_type="port_open"):
|
|
"""Validate that a vulnerability has been remediated."""
|
|
import socket
|
|
result = {"host": host, "port": int(port), "check_type": check_type}
|
|
if check_type == "port_open":
|
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
sock.settimeout(5)
|
|
try:
|
|
sock.connect((host, int(port)))
|
|
result["status"] = "STILL_OPEN"
|
|
result["remediated"] = False
|
|
except (socket.timeout, ConnectionRefusedError, OSError):
|
|
result["status"] = "CLOSED"
|
|
result["remediated"] = True
|
|
finally:
|
|
sock.close()
|
|
return result
|
|
|
|
|
|
def generate_remediation_report(scan_file, output=None):
|
|
"""Generate a remediation plan from scan results."""
|
|
parsed = parse_scan_report(scan_file)
|
|
plan = {"generated": datetime.utcnow().isoformat(), "source": scan_file}
|
|
plan["summary"] = parsed["by_severity"]
|
|
plan["total"] = parsed["total_vulns"]
|
|
hosts = {}
|
|
for v in parsed["remediation_queue"]:
|
|
h = v["host"]
|
|
if h not in hosts:
|
|
hosts[h] = []
|
|
hosts[h].append(v)
|
|
plan["by_host"] = {h: {"count": len(vs), "vulns": vs} for h, vs in hosts.items()}
|
|
if output:
|
|
with open(output, "w") as f:
|
|
json.dump(plan, f, indent=2)
|
|
return plan
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description="Endpoint Vulnerability Remediation Agent")
|
|
sub = parser.add_subparsers(dest="command")
|
|
p = sub.add_parser("parse", help="Parse vulnerability scan report")
|
|
p.add_argument("--scan-file", required=True)
|
|
sub.add_parser("patches", help="Check installed Windows patches")
|
|
v = sub.add_parser("validate", help="Validate remediation")
|
|
v.add_argument("--host", required=True)
|
|
v.add_argument("--port", required=True)
|
|
r = sub.add_parser("report", help="Generate remediation report")
|
|
r.add_argument("--scan-file", required=True)
|
|
r.add_argument("--output", help="Output JSON file")
|
|
args = parser.parse_args()
|
|
if args.command == "parse":
|
|
result = parse_scan_report(args.scan_file)
|
|
elif args.command == "patches":
|
|
result = check_windows_patches()
|
|
elif args.command == "validate":
|
|
result = validate_remediation(args.host, args.port)
|
|
elif args.command == "report":
|
|
result = generate_remediation_report(args.scan_file, args.output)
|
|
else:
|
|
parser.print_help()
|
|
return
|
|
print(json.dumps(result, indent=2, default=str))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|