mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-19 22:19:39 +03:00
Complete folder anatomy for all 649 cybersecurity skills + update LICENSE to Mahipal
- Add scripts/agent.py and references/api-reference.md to all remaining skills - Update all 648 LICENSE files: copyright now reads 'Mahipal' - Add implementing-security-monitoring-with-datadog (new skill with full anatomy) - All 649 skills now have: SKILL.md, LICENSE, scripts/agent.py, references/api-reference.md
This commit is contained in:
@@ -0,0 +1,219 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Agent for triaging vulnerabilities with the SSVC framework.
|
||||
|
||||
Implements CISA's Stakeholder-Specific Vulnerability Categorization
|
||||
decision tree to produce actionable priorities: Track, Track*,
|
||||
Attend, or Act based on exploitation status, technical impact,
|
||||
automatability, and mission prevalence.
|
||||
"""
|
||||
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
|
||||
try:
|
||||
import requests
|
||||
except ImportError:
|
||||
requests = None
|
||||
|
||||
|
||||
class ExploitationStatus:
|
||||
NONE = "none"
|
||||
POC = "poc"
|
||||
ACTIVE = "active"
|
||||
|
||||
|
||||
class TechnicalImpact:
|
||||
PARTIAL = "partial"
|
||||
TOTAL = "total"
|
||||
|
||||
|
||||
class Automatability:
|
||||
NO = "no"
|
||||
YES = "yes"
|
||||
|
||||
|
||||
class MissionPrevalence:
|
||||
MINIMAL = "minimal"
|
||||
SUPPORT = "support"
|
||||
ESSENTIAL = "essential"
|
||||
|
||||
|
||||
class SSVCDecision:
|
||||
TRACK = "Track"
|
||||
TRACK_STAR = "Track*"
|
||||
ATTEND = "Attend"
|
||||
ACT = "Act"
|
||||
|
||||
|
||||
SSVC_DECISION_TREE = {
|
||||
(ExploitationStatus.ACTIVE, TechnicalImpact.TOTAL): SSVCDecision.ACT,
|
||||
(ExploitationStatus.ACTIVE, TechnicalImpact.PARTIAL, Automatability.YES): SSVCDecision.ACT,
|
||||
(ExploitationStatus.ACTIVE, TechnicalImpact.PARTIAL, Automatability.NO, MissionPrevalence.ESSENTIAL): SSVCDecision.ACT,
|
||||
(ExploitationStatus.ACTIVE, TechnicalImpact.PARTIAL, Automatability.NO, MissionPrevalence.SUPPORT): SSVCDecision.ATTEND,
|
||||
(ExploitationStatus.ACTIVE, TechnicalImpact.PARTIAL, Automatability.NO, MissionPrevalence.MINIMAL): SSVCDecision.ATTEND,
|
||||
(ExploitationStatus.POC, TechnicalImpact.TOTAL, Automatability.YES): SSVCDecision.ATTEND,
|
||||
(ExploitationStatus.POC, TechnicalImpact.TOTAL, Automatability.NO): SSVCDecision.TRACK_STAR,
|
||||
(ExploitationStatus.POC, TechnicalImpact.PARTIAL): SSVCDecision.TRACK_STAR,
|
||||
(ExploitationStatus.NONE, TechnicalImpact.TOTAL): SSVCDecision.TRACK_STAR,
|
||||
(ExploitationStatus.NONE, TechnicalImpact.PARTIAL): SSVCDecision.TRACK,
|
||||
}
|
||||
|
||||
|
||||
class SSVCTriageAgent:
|
||||
"""Triages vulnerabilities using the SSVC decision tree."""
|
||||
|
||||
def __init__(self, output_dir="./ssvc_triage"):
|
||||
self.output_dir = Path(output_dir)
|
||||
self.output_dir.mkdir(parents=True, exist_ok=True)
|
||||
self.results = []
|
||||
|
||||
def check_cisa_kev(self, cve_id):
|
||||
"""Check if CVE is in CISA Known Exploited Vulnerabilities catalog."""
|
||||
if not requests:
|
||||
return None
|
||||
resp = None
|
||||
try:
|
||||
resp = requests.get(
|
||||
"https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json",
|
||||
timeout=15,
|
||||
)
|
||||
except Exception:
|
||||
return None
|
||||
if resp and resp.status_code == 200:
|
||||
data = resp.json()
|
||||
for vuln in data.get("vulnerabilities", []):
|
||||
if vuln.get("cveID") == cve_id:
|
||||
return {
|
||||
"in_kev": True,
|
||||
"vendor": vuln.get("vendorProject"),
|
||||
"product": vuln.get("product"),
|
||||
"date_added": vuln.get("dateAdded"),
|
||||
"due_date": vuln.get("dueDate"),
|
||||
}
|
||||
return {"in_kev": False}
|
||||
|
||||
def get_epss_score(self, cve_id):
|
||||
"""Get EPSS probability score from FIRST API."""
|
||||
if not requests:
|
||||
return None
|
||||
try:
|
||||
resp = requests.get(f"https://api.first.org/data/v1/epss?cve={cve_id}", timeout=10)
|
||||
if resp and resp.status_code == 200:
|
||||
data = resp.json().get("data", [])
|
||||
if data:
|
||||
return {
|
||||
"cve": cve_id,
|
||||
"epss": float(data[0].get("epss", 0)),
|
||||
"percentile": float(data[0].get("percentile", 0)),
|
||||
}
|
||||
except Exception:
|
||||
pass
|
||||
return None
|
||||
|
||||
def determine_exploitation(self, cve_id):
|
||||
"""Determine exploitation status using KEV and EPSS."""
|
||||
kev = self.check_cisa_kev(cve_id)
|
||||
if kev and kev.get("in_kev"):
|
||||
return ExploitationStatus.ACTIVE, kev
|
||||
epss = self.get_epss_score(cve_id)
|
||||
if epss and epss.get("epss", 0) > 0.5:
|
||||
return ExploitationStatus.POC, epss
|
||||
if epss and epss.get("epss", 0) > 0.1:
|
||||
return ExploitationStatus.POC, epss
|
||||
return ExploitationStatus.NONE, epss
|
||||
|
||||
def evaluate_decision(self, exploitation, technical_impact, automatability=None,
|
||||
mission_prevalence=None):
|
||||
"""Walk the SSVC decision tree to produce a prioritization."""
|
||||
if (exploitation, technical_impact) in SSVC_DECISION_TREE:
|
||||
return SSVC_DECISION_TREE[(exploitation, technical_impact)]
|
||||
if automatability:
|
||||
key = (exploitation, technical_impact, automatability)
|
||||
if key in SSVC_DECISION_TREE:
|
||||
return SSVC_DECISION_TREE[key]
|
||||
if mission_prevalence:
|
||||
key = (exploitation, technical_impact, automatability, mission_prevalence)
|
||||
if key in SSVC_DECISION_TREE:
|
||||
return SSVC_DECISION_TREE[key]
|
||||
return SSVCDecision.TRACK
|
||||
|
||||
def triage_cve(self, cve_id, technical_impact=TechnicalImpact.PARTIAL,
|
||||
automatability=Automatability.NO,
|
||||
mission_prevalence=MissionPrevalence.SUPPORT):
|
||||
"""Full SSVC triage for a single CVE."""
|
||||
exploitation, enrichment = self.determine_exploitation(cve_id)
|
||||
decision = self.evaluate_decision(exploitation, technical_impact,
|
||||
automatability, mission_prevalence)
|
||||
result = {
|
||||
"cve_id": cve_id,
|
||||
"exploitation_status": exploitation,
|
||||
"technical_impact": technical_impact,
|
||||
"automatability": automatability,
|
||||
"mission_prevalence": mission_prevalence,
|
||||
"decision": decision,
|
||||
"enrichment": enrichment,
|
||||
"remediation_timeline": self._get_timeline(decision),
|
||||
}
|
||||
self.results.append(result)
|
||||
return result
|
||||
|
||||
def _get_timeline(self, decision):
|
||||
timelines = {
|
||||
SSVCDecision.ACT: "Immediate - remediate within 24-48 hours",
|
||||
SSVCDecision.ATTEND: "Urgent - remediate within 1-2 weeks",
|
||||
SSVCDecision.TRACK_STAR: "Scheduled - remediate in next patch cycle",
|
||||
SSVCDecision.TRACK: "Monitor - include in regular vulnerability management",
|
||||
}
|
||||
return timelines.get(decision, "Unknown")
|
||||
|
||||
def triage_batch(self, cves, defaults=None):
|
||||
"""Triage a list of CVEs with optional default parameters."""
|
||||
defaults = defaults or {}
|
||||
for cve in cves:
|
||||
self.triage_cve(
|
||||
cve,
|
||||
technical_impact=defaults.get("technical_impact", TechnicalImpact.PARTIAL),
|
||||
automatability=defaults.get("automatability", Automatability.NO),
|
||||
mission_prevalence=defaults.get("mission_prevalence", MissionPrevalence.SUPPORT),
|
||||
)
|
||||
return self.results
|
||||
|
||||
def generate_report(self, cves=None):
|
||||
if cves:
|
||||
self.triage_batch(cves)
|
||||
by_decision = {}
|
||||
for r in self.results:
|
||||
d = r["decision"]
|
||||
by_decision[d] = by_decision.get(d, 0) + 1
|
||||
|
||||
report = {
|
||||
"report_date": datetime.utcnow().isoformat(),
|
||||
"framework": "SSVC (CISA Stakeholder-Specific Vulnerability Categorization)",
|
||||
"total_triaged": len(self.results),
|
||||
"by_decision": by_decision,
|
||||
"triage_results": self.results,
|
||||
}
|
||||
out = self.output_dir / "ssvc_triage_report.json"
|
||||
with open(out, "w") as f:
|
||||
json.dump(report, f, indent=2)
|
||||
print(json.dumps(report, indent=2))
|
||||
return report
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 2:
|
||||
print("Usage: agent.py <CVE-ID> [CVE-ID2 ...] [--impact total|partial]")
|
||||
sys.exit(1)
|
||||
cves = [a for a in sys.argv[1:] if a.startswith("CVE-")]
|
||||
impact = TechnicalImpact.PARTIAL
|
||||
if "--impact" in sys.argv:
|
||||
val = sys.argv[sys.argv.index("--impact") + 1]
|
||||
impact = TechnicalImpact.TOTAL if val == "total" else TechnicalImpact.PARTIAL
|
||||
agent = SSVCTriageAgent()
|
||||
agent.generate_report(cves)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user