npx skills add mukul975/Anthropic-Cybersecurity-SkillsMITRE ATT&CK
When to Use
Use this skill when:
- Remediating vulnerabilities identified by scanners (Nessus, Qualys, Rapid7)
- Responding to zero-day CVE advisories requiring immediate patching
- Maintaining compliance with patch management SLAs (critical within 14 days, high within 30 days)
- Building a prioritized remediation plan from vulnerability scan results
Do not use this skill for vulnerability scanning itself (use scanning tools) or for application-layer vulnerability remediation (use DevSecOps processes).
Prerequisites
- Vulnerability scan results (Nessus, Qualys, or Rapid7 export in CSV/XML format)
- Patch management platform (WSUS, SCCM, Intune, or third-party like Automox)
- Administrative access to target endpoints or deployment infrastructure
- Change management process for production endpoint patching
- Testing environment for patch validation before production rollout
Workflow
Step 1: Import and Prioritize Vulnerability Findings
Priority scoring combines:
1. CVSS Base Score (0-10)
2. EPSS (Exploit Prediction Scoring System) - probability of exploitation
3. CISA KEV (Known Exploited Vulnerabilities) catalog membership
4. Asset criticality (business impact of affected endpoint)
5. Network exposure (internet-facing vs. internal)
Priority Matrix:
P1 (Critical - 14 days SLA):
- CVSS >= 9.0 OR
- Listed in CISA KEV OR
- Active exploitation in the wild + CVSS >= 7.0
P2 (High - 30 days SLA):
- CVSS 7.0-8.9 AND
- EPSS > 0.5 (50% probability of exploitation)
P3 (Medium - 60 days SLA):
- CVSS 4.0-6.9 OR
- CVSS 7.0-8.9 with EPSS < 0.1
P4 (Low - 90 days SLA):
- CVSS < 4.0 AND
- No known exploitStep 2: Identify Remediation Actions
For each vulnerability, determine the appropriate remediation:
Remediation Types:
1. Patch: Apply vendor security update (most common)
2. Configuration change: Modify settings to mitigate (registry, GPO)
3. Upgrade: Update to newer software version
4. Workaround: Apply temporary mitigation when patch unavailable
5. Compensating control: Network segmentation, WAF rule, EDR rule
6. Accept risk: Document accepted risk with CISO sign-offStep 3: Deploy Patches via WSUS/SCCM
# WSUS: Approve patches for deployment
# 1. Open WSUS Console
# 2. Navigate to Updates → Security Updates
# 3. Approve selected KBs for target computer groups
# SCCM: Create Software Update Group
# 1. Software Library → Software Updates → All Software Updates
# 2. Select required KBs → Create Software Update Group
# 3. Deploy to target collection with maintenance window
# Intune: Create Windows Update Ring
# Devices → Windows → Update rings
# Configure: Quality updates deferral = 0 days (for critical)
# Feature updates deferral = per policy
# PowerShell: Force Windows Update check
Install-Module PSWindowsUpdate -Force
Get-WindowsUpdate -KBArticleID "KB5034441" -Install -AcceptAll -AutoReboot
# Verify patch installation
Get-HotFix -Id "KB5034441"
systeminfo | findstr "KB5034441"Step 4: Apply Configuration-Based Remediations
# Example: Disable SMBv1 (CVE-2017-0144 - EternalBlue)
Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force
Disable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol -NoRestart
# Example: Disable Print Spooler on non-print servers (CVE-2021-34527 - PrintNightmare)
Stop-Service -Name Spooler -Force
Set-Service -Name Spooler -StartupType Disabled
# Example: Disable LLMNR (credential theft mitigation)
# Via GPO: Computer Configuration → Admin Templates → Network → DNS Client
# Turn off multicast name resolution: Enabled
New-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" `
-Name EnableMulticast -Value 0 -PropertyType DWORD -Force
# Example: Restrict NTLM authentication
# Via GPO: Security Settings → Local Policies → Security Options
# Network security: Restrict NTLM: Audit/DenyStep 5: Handle Zero-Day Vulnerabilities (No Patch Available)
When vendor patch is not yet available:
1. Check vendor advisory for workarounds
- Microsoft: https://msrc.microsoft.com/update-guide
- Adobe: https://helpx.adobe.com/security.html
- Linux: Distribution security trackers
2. Apply temporary mitigations:
- Disable vulnerable feature/service
- Deploy EDR detection rule for exploitation attempt
- Apply network-level blocking (WAF/firewall rules)
- Restrict access to vulnerable application
3. Monitor for patch release:
- Subscribe to vendor security mailing list
- Monitor CISA KEV additions
- Set calendar reminder for next Patch Tuesday
4. Document workaround with expiration dateStep 6: Validate Remediation
# Re-scan remediated endpoints to confirm vulnerability closure
# Option 1: Targeted vulnerability scan
nessuscli scan --target 192.168.1.0/24 --plugin-id 12345
# Option 2: PowerShell verification
# Check specific KB is installed
$kb = Get-HotFix -Id "KB5034441" -ErrorAction SilentlyContinue
if ($kb) {
Write-Host "PASS: KB5034441 installed on $(hostname)" -ForegroundColor Green
} else {
Write-Host "FAIL: KB5034441 missing on $(hostname)" -ForegroundColor Red
}
# Check service is disabled
$svc = Get-Service -Name Spooler
if ($svc.StartType -eq 'Disabled') {
Write-Host "PASS: Print Spooler disabled" -ForegroundColor Green
}
# Check registry configuration
$val = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" `
-Name SMB1 -ErrorAction SilentlyContinue
if ($val.SMB1 -eq 0) {
Write-Host "PASS: SMBv1 disabled" -ForegroundColor Green
}Step 7: Report and Track
Generate remediation status report:
Remediation Metrics:
- Total vulnerabilities: X
- Remediated: Y (Z%)
- Pending (within SLA): A
- Overdue (past SLA): B
- Accepted risk: C
- Mean time to remediate (MTTR): D days
- SLA compliance rate: E%Key Concepts
| Term | Definition |
|---|---|
| CVSS | Common Vulnerability Scoring System; 0-10 severity scale for vulnerabilities |
| EPSS | Exploit Prediction Scoring System; probability (0-1) that a CVE will be exploited in the wild within 30 days |
| CISA KEV | CISA Known Exploited Vulnerabilities catalog; federal mandate to patch these CVEs within specified timeframes |
| SLA | Service Level Agreement for remediation timelines based on vulnerability severity |
| MTTR | Mean Time To Remediate; average days from vulnerability discovery to confirmed fix |
| Compensating Control | Alternative security measure when direct remediation is not feasible |
Tools & Systems
- Nessus/Tenable.io: Vulnerability scanning and remediation tracking
- Qualys VMDR: Vulnerability management, detection, and response platform
- Rapid7 InsightVM: Vulnerability assessment with live dashboards
- WSUS/SCCM/Intune: Microsoft patch deployment infrastructure
- Automox: Cloud-native patch management for Windows, macOS, Linux
- CISA KEV Catalog: https://www.cisa.gov/known-exploited-vulnerabilities-catalog
Common Pitfalls
- Patching without testing: Apply patches to a test group first. Some patches cause application compatibility issues or BSOD.
- Ignoring EPSS scores: A CVSS 9.8 vulnerability with EPSS 0.01 may be less urgent than a CVSS 7.5 with EPSS 0.95 (actively exploited).
- Not validating remediation: Deploying a patch does not guarantee installation. Always re-scan to confirm closure.
- Excluding critical servers from patching: Servers that "cannot be rebooted" accumulate critical vulnerabilities. Schedule maintenance windows.
- Treating all CVEs equally: Risk-based prioritization (CVSS + EPSS + asset criticality + exposure) is more effective than patching all criticals first.
References and resources
Everything below is rendered for inspection. Script files are read-only and never run.
References 3
api-reference.md4.4 KB
API Reference — Performing Endpoint Vulnerability Remediation
Libraries Used
| Library | Purpose |
|---|---|
csv |
Parse vulnerability scan CSV exports (Nessus, Qualys, Rapid7) |
subprocess |
Check installed Windows patches via wmic qfe and PowerShell |
socket |
Validate port-based remediation via TCP connect |
json |
Read/write remediation plans and reports |
argparse |
CLI argument parsing for scan file and host parameters |
datetime |
Track patch dates and SLA deadlines |
CLI Interface
python agent.py parse --scan-file scan.csv
python agent.py patches
python agent.py validate --host 10.0.0.1 --port 445
python agent.py report --scan-file scan.csv [--output plan.json]Core Functions
parse_scan_report(csv_file) — Parse and prioritize vulnerabilities by severity
def parse_scan_report(csv_file):
"""Parse Nessus/Qualys CSV export, group by host, sort by severity."""
with open(csv_file, newline="") as f:
reader = csv.DictReader(f)
vulns = []
for row in reader:
vulns.append({
"host": row.get("Host", row.get("IP")),
"plugin_id": row.get("Plugin ID", row.get("QID")),
"severity": row.get("Risk", row.get("Severity", "Info")),
"name": row.get("Name", row.get("Title")),
"cve": row.get("CVE", ""),
"solution": row.get("Solution", row.get("Fix", "")),
})
severity_order = {"Critical": 0, "High": 1, "Medium": 2, "Low": 3, "Info": 4}
return sorted(vulns, key=lambda v: severity_order.get(v["severity"], 5))check_windows_patches() — List installed Windows hotfixes via WMIC
def check_windows_patches():
"""Query installed patches on a Windows endpoint."""
result = subprocess.run(
["wmic", "qfe", "get", "HotFixID,InstalledOn,Description", "/format:csv"],
capture_output=True, text=True, timeout=30,
)
patches = []
for line in result.stdout.strip().split("\n")[1:]:
parts = line.strip().split(",")
if len(parts) >= 4:
patches.append({
"hotfix_id": parts[1],
"description": parts[2],
"installed_on": parts[3],
})
return patchesvalidate_remediation(host, port) — TCP connect to verify port closure
def validate_remediation(host, port):
"""Verify that a vulnerable port has been closed after remediation."""
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(5)
try:
result = sock.connect_ex((host, int(port)))
return {
"host": host,
"port": port,
"status": "open" if result == 0 else "closed",
"remediated": result != 0,
}
finally:
sock.close()generate_remediation_report(scan_file, output) — Group vulns by host for remediation
def generate_remediation_report(scan_file, output=None):
"""Generate a prioritized remediation plan from scan results."""
vulns = parse_scan_report(scan_file)
by_host = {}
for v in vulns:
by_host.setdefault(v["host"], []).append(v)
report = {
"total_vulns": len(vulns),
"hosts_affected": len(by_host),
"by_severity": {},
"remediation_plan": [],
}
for severity in ["Critical", "High", "Medium", "Low"]:
count = sum(1 for v in vulns if v["severity"] == severity)
report["by_severity"][severity] = count
for host, host_vulns in sorted(by_host.items()):
report["remediation_plan"].append({
"host": host,
"vuln_count": len(host_vulns),
"critical": sum(1 for v in host_vulns if v["severity"] == "Critical"),
"patches": [v["name"] for v in host_vulns[:10]],
})
if output:
with open(output, "w") as f:
json.dump(report, f, indent=2)
return reportOutput Format
{
"total_vulns": 245,
"hosts_affected": 42,
"by_severity": {
"Critical": 8,
"High": 35,
"Medium": 112,
"Low": 90
},
"remediation_plan": [
{
"host": "10.0.0.50",
"vuln_count": 12,
"critical": 2,
"patches": ["MS17-010: EternalBlue", "CVE-2024-21887: Ivanti RCE"]
}
]
}Dependencies
No external packages — Python standard library only.
standards.md2.6 KB
Standards & References - Performing Endpoint Vulnerability Remediation
Primary Standards
NIST SP 800-40 Rev 4 - Guide to Enterprise Patch Management Planning
- Publisher: NIST
- URL: https://csrc.nist.gov/publications/detail/sp/800-40/rev-4/final
- Scope: Enterprise patch management lifecycle, risk-based prioritization, and operational planning
CISA Binding Operational Directive 22-01 - Known Exploited Vulnerabilities
- Publisher: CISA
- URL: https://www.cisa.gov/binding-operational-directive-22-01
- Scope: Federal mandate to remediate CVEs in the Known Exploited Vulnerabilities catalog within specified timelines
- Timelines: Typically 14 days for internet-facing, 28 days for internal systems
FIRST CVSS v3.1 Specification
- Publisher: FIRST (Forum of Incident Response and Security Teams)
- URL: https://www.first.org/cvss/specification-document
- Scope: Scoring methodology for vulnerability severity
FIRST EPSS Model
- Publisher: FIRST
- URL: https://www.first.org/epss/
- Scope: Machine learning model predicting probability of CVE exploitation within 30 days
Compliance Mappings
| Framework | Requirement | Remediation Coverage |
|---|---|---|
| PCI DSS 4.0 | 6.3.3 - Patch within one month of release | Patch SLA tracking and compliance |
| PCI DSS 4.0 | 11.3.1 - Internal vulnerability scans quarterly | Scan-remediate-validate cycle |
| NIST 800-53 | SI-2 Flaw Remediation | Vulnerability identification and patching |
| NIST 800-53 | RA-5 Vulnerability Monitoring and Scanning | Ongoing scan-remediate process |
| HIPAA | 164.308(a)(1)(ii)(B) - Risk Management | Vulnerability remediation as risk reduction |
| ISO 27001 | A.12.6.1 - Management of technical vulnerabilities | Systematic vulnerability remediation |
| SOC 2 | CC7.1 - Detect and address vulnerabilities | Vulnerability management program |
Remediation SLA Benchmarks
| Severity | CVSS Range | Industry Standard SLA | CISA KEV Timeline |
|---|---|---|---|
| Critical | 9.0-10.0 | 14 days | Per directive (usually 14 days) |
| High | 7.0-8.9 | 30 days | Per directive |
| Medium | 4.0-6.9 | 60 days | N/A unless in KEV |
| Low | 0.1-3.9 | 90 days | N/A |
Supporting References
- CISA KEV Catalog: https://www.cisa.gov/known-exploited-vulnerabilities-catalog
- NVD (National Vulnerability Database): https://nvd.nist.gov/
- EPSS Data: https://api.first.org/data/v1/epss
- Microsoft Security Update Guide: https://msrc.microsoft.com/update-guide
workflows.md3.5 KB
Workflows - Performing Endpoint Vulnerability Remediation
Workflow 1: Standard Vulnerability Remediation Cycle
[Vulnerability Scan Complete]
│
▼
[Import scan results into tracking system]
│
▼
[Risk-based prioritization]
│
├── CVSS + EPSS + CISA KEV + Asset criticality
│
▼
[Assign priorities: P1/P2/P3/P4]
│
▼
[Identify remediation action per CVE]
│
├── Patch available ──► [Schedule patch deployment]
├── Config change needed ──► [Create change request]
├── No patch available ──► [Apply workaround/compensating control]
└── Accept risk ──► [Document with CISO approval]
│
▼
[Test patches in staging environment]
│
▼
[Deploy to production (phased rollout)]
│
▼
[Re-scan to validate remediation]
│
├── Vulnerability closed ──► [Mark resolved in tracker]
│
└── Still open ──► [Investigate failure, re-remediate]Workflow 2: Emergency Zero-Day Response
[Zero-day CVE announced (CISA alert / vendor advisory)]
│
▼
[Assess exposure: How many endpoints affected?]
│
▼
[Is patch available?]
│
├── Yes ──► [Emergency patch deployment (skip staging)]
│ │
│ ▼
│ [Monitor for deployment failures]
│ │
│ ▼
│ [Validate patch across fleet]
│
└── No ──► [Apply vendor workaround immediately]
│
├── Disable vulnerable service/feature
├── Deploy network-level mitigation
├── Create EDR detection rule
│
▼
[Monitor for patch release]
│
▼
[Deploy patch when available]
│
▼
[Remove workaround, validate fix]Workflow 3: Patch Deployment Pipeline
[Patch Tuesday (or vendor release)]
│
▼
[Download and catalog new patches]
│
▼
[Risk assessment: Which patches are critical?]
│
▼
[Deploy to test ring (5% of fleet) - Day 1-3]
│
├── Test application compatibility
├── Monitor for BSOD, crashes, performance issues
│
▼
[Deploy to pilot ring (20% of fleet) - Day 4-7]
│
├── Broader application testing
├── User feedback collection
│
▼
[Deploy to production ring (remaining fleet) - Day 8-14]
│
▼
[Generate compliance report]
│
├── Endpoints patched: X%
├── Pending reboot: Y
└── Failed deployments: Z (investigate)Workflow 4: SLA Compliance Tracking
[Weekly SLA Review]
│
▼
[Query open vulnerabilities grouped by SLA status]
│
├── Within SLA ──► [Track progress, no action needed]
│
├── Approaching SLA (7 days) ──► [Escalate to endpoint team]
│
└── Overdue (past SLA) ──► [Escalate to management]
│
├── Remediation feasible ──► [Emergency remediation]
│
└── Blocked (dependency) ──► [Document exception, compensating control]Scripts 2
agent.py4.6 KB
#!/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()
process.py7.8 KB
#!/usr/bin/env python3
"""
Endpoint Vulnerability Remediation Prioritizer
Parses vulnerability scan exports (Nessus CSV), enriches with EPSS scores,
cross-references CISA KEV catalog, and generates prioritized remediation plans.
"""
import json
import csv
import sys
import os
from datetime import datetime, timedelta
from collections import defaultdict
from urllib.request import urlopen
from urllib.error import URLError
CISA_KEV_URL = "https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json"
EPSS_API_URL = "https://api.first.org/data/v1/epss"
def load_nessus_csv(csv_path: str) -> list:
"""Parse Nessus scan export CSV into vulnerability records."""
vulns = []
with open(csv_path, "r", encoding="utf-8-sig") as f:
reader = csv.DictReader(f)
for row in reader:
cvss = 0.0
try:
cvss = float(row.get("CVSS v3.0 Base Score", "0") or
row.get("CVSS v2.0 Base Score", "0") or "0")
except ValueError:
pass
cve_list = [c.strip() for c in row.get("CVE", "").split(",") if c.strip()]
vuln = {
"plugin_id": row.get("Plugin ID", ""),
"plugin_name": row.get("Name", ""),
"severity": row.get("Risk", "None"),
"host": row.get("Host", ""),
"protocol": row.get("Protocol", ""),
"port": row.get("Port", ""),
"cvss_score": cvss,
"cves": cve_list,
"solution": row.get("Solution", ""),
"synopsis": row.get("Synopsis", ""),
"description": row.get("Description", "")[:200],
}
vulns.append(vuln)
return vulns
def fetch_cisa_kev() -> set:
"""Fetch CISA Known Exploited Vulnerabilities catalog."""
try:
with urlopen(CISA_KEV_URL, timeout=15) as resp:
data = json.loads(resp.read())
return {v["cveID"] for v in data.get("vulnerabilities", [])}
except (URLError, json.JSONDecodeError, KeyError) as e:
print(f"Warning: Could not fetch CISA KEV catalog: {e}")
return set()
def fetch_epss_scores(cves: list) -> dict:
"""Fetch EPSS scores for a list of CVEs."""
epss_scores = {}
batch_size = 100
for i in range(0, len(cves), batch_size):
batch = cves[i:i + batch_size]
cve_param = ",".join(batch)
url = f"{EPSS_API_URL}?cve={cve_param}"
try:
with urlopen(url, timeout=15) as resp:
data = json.loads(resp.read())
for item in data.get("data", []):
epss_scores[item["cve"]] = float(item.get("epss", 0))
except (URLError, json.JSONDecodeError) as e:
print(f"Warning: EPSS lookup failed for batch: {e}")
return epss_scores
def prioritize_vulnerabilities(vulns: list, kev_cves: set, epss_scores: dict) -> list:
"""Assign remediation priority based on risk scoring."""
for vuln in vulns:
cvss = vuln["cvss_score"]
cves = vuln["cves"]
in_kev = any(cve in kev_cves for cve in cves)
max_epss = max((epss_scores.get(cve, 0) for cve in cves), default=0)
vuln["in_cisa_kev"] = in_kev
vuln["epss_score"] = round(max_epss, 4)
if cvss >= 9.0 or in_kev or (cvss >= 7.0 and max_epss > 0.7):
vuln["priority"] = "P1"
vuln["sla_days"] = 14
elif cvss >= 7.0 and max_epss > 0.5:
vuln["priority"] = "P2"
vuln["sla_days"] = 30
elif cvss >= 4.0:
vuln["priority"] = "P3"
vuln["sla_days"] = 60
else:
vuln["priority"] = "P4"
vuln["sla_days"] = 90
vuln["sla_deadline"] = (
datetime.utcnow() + timedelta(days=vuln["sla_days"])
).strftime("%Y-%m-%d")
vulns.sort(key=lambda v: (
{"P1": 0, "P2": 1, "P3": 2, "P4": 3}.get(v["priority"], 4),
-v["cvss_score"],
-v["epss_score"],
))
return vulns
def generate_remediation_plan(vulns: list, output_path: str) -> None:
"""Generate prioritized remediation plan in JSON."""
summary = defaultdict(int)
hosts_affected = defaultdict(set)
for vuln in vulns:
summary[vuln["priority"]] += 1
hosts_affected[vuln["priority"]].add(vuln["host"])
plan = {
"report_generated": datetime.utcnow().isoformat() + "Z",
"summary": {
"total_vulnerabilities": len(vulns),
"by_priority": dict(summary),
"unique_hosts": {p: len(h) for p, h in hosts_affected.items()},
},
"kev_vulnerabilities": [v for v in vulns if v.get("in_cisa_kev")],
"remediation_queue": [
{
"priority": v["priority"],
"sla_deadline": v["sla_deadline"],
"host": v["host"],
"plugin_name": v["plugin_name"],
"cvss": v["cvss_score"],
"epss": v["epss_score"],
"cisa_kev": v["in_cisa_kev"],
"cves": v["cves"],
"solution": v["solution"],
}
for v in vulns
],
}
with open(output_path, "w", encoding="utf-8") as f:
json.dump(plan, f, indent=2)
def export_remediation_csv(vulns: list, output_path: str) -> None:
"""Export remediation plan to CSV for team assignment."""
with open(output_path, "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow([
"Priority", "SLA Deadline", "Host", "Vulnerability",
"CVSS", "EPSS", "CISA KEV", "CVEs", "Solution",
"Status", "Assigned To", "Notes",
])
for v in vulns:
writer.writerow([
v["priority"], v["sla_deadline"], v["host"],
v["plugin_name"], v["cvss_score"], v["epss_score"],
v["in_cisa_kev"], "; ".join(v["cves"]),
v["solution"][:200], "Open", "", "",
])
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python process.py <nessus_export.csv>")
print()
print("Parses Nessus CSV export, enriches with EPSS/CISA KEV data,")
print("and generates a prioritized remediation plan.")
sys.exit(1)
csv_path = sys.argv[1]
if not os.path.exists(csv_path):
print(f"Error: File not found: {csv_path}")
sys.exit(1)
print("Parsing vulnerability scan results...")
vulns = load_nessus_csv(csv_path)
print(f"Loaded {len(vulns)} vulnerability findings")
all_cves = list({cve for v in vulns for cve in v["cves"]})
print(f"Unique CVEs: {len(all_cves)}")
print("Fetching CISA KEV catalog...")
kev_cves = fetch_cisa_kev()
print(f"KEV catalog contains {len(kev_cves)} CVEs")
print("Fetching EPSS scores...")
epss_scores = fetch_epss_scores(all_cves) if all_cves else {}
print(f"Retrieved EPSS scores for {len(epss_scores)} CVEs")
print("Prioritizing vulnerabilities...")
vulns = prioritize_vulnerabilities(vulns, kev_cves, epss_scores)
base = os.path.splitext(os.path.basename(csv_path))[0]
out_dir = os.path.dirname(csv_path) or "."
plan_path = os.path.join(out_dir, f"{base}_remediation_plan.json")
generate_remediation_plan(vulns, plan_path)
print(f"Remediation plan: {plan_path}")
csv_out = os.path.join(out_dir, f"{base}_remediation.csv")
export_remediation_csv(vulns, csv_out)
print(f"Remediation CSV: {csv_out}")
print(f"\n--- Remediation Summary ---")
for p in ["P1", "P2", "P3", "P4"]:
count = sum(1 for v in vulns if v["priority"] == p)
if count:
print(f" {p}: {count} vulnerabilities")
kev_count = sum(1 for v in vulns if v.get("in_cisa_kev"))
if kev_count:
print(f"\n CISA KEV matches: {kev_count} (mandatory remediation)")