mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-21 11:21:22 +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,161 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Patch Tuesday Response Agent - Tracks Microsoft patches, assesses risk, and prioritizes deployment."""
|
||||
|
||||
import json
|
||||
import logging
|
||||
import argparse
|
||||
from datetime import datetime
|
||||
|
||||
import requests
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
MSRC_API_BASE = "https://api.msrc.microsoft.com/cvrf/v3.0"
|
||||
|
||||
|
||||
def fetch_patch_tuesday_updates(api_key, year_month):
|
||||
"""Fetch Microsoft Security Update Guide data via MSRC API."""
|
||||
headers = {"api-key": api_key, "Accept": "application/json"}
|
||||
resp = requests.get(f"{MSRC_API_BASE}/Updates('{year_month}')", headers=headers, timeout=30)
|
||||
resp.raise_for_status()
|
||||
data = resp.json()
|
||||
logger.info("Fetched MSRC update for %s", year_month)
|
||||
return data
|
||||
|
||||
|
||||
def parse_vulnerabilities(cvrf_data):
|
||||
"""Parse CVRF data to extract vulnerability details."""
|
||||
vulns = []
|
||||
for vuln in cvrf_data.get("Vulnerability", []):
|
||||
cve_id = vuln.get("CVE", "")
|
||||
title = vuln.get("Title", {}).get("Value", "")
|
||||
severity = "unknown"
|
||||
cvss_score = 0.0
|
||||
exploited = False
|
||||
for threat in vuln.get("Threats", []):
|
||||
desc = threat.get("Description", {}).get("Value", "")
|
||||
if "Exploited:Yes" in desc:
|
||||
exploited = True
|
||||
if threat.get("Type") == 3:
|
||||
severity = desc
|
||||
for score_set in vuln.get("CVSSScoreSets", []):
|
||||
base = score_set.get("BaseScore", 0.0)
|
||||
if base > cvss_score:
|
||||
cvss_score = base
|
||||
affected_products = []
|
||||
for product_status in vuln.get("ProductStatuses", []):
|
||||
for pid in product_status.get("ProductID", []):
|
||||
affected_products.append(pid)
|
||||
vulns.append({
|
||||
"cve": cve_id, "title": title, "severity": severity,
|
||||
"cvss_score": cvss_score, "exploited_in_wild": exploited,
|
||||
"affected_product_ids": affected_products[:10],
|
||||
})
|
||||
logger.info("Parsed %d vulnerabilities", len(vulns))
|
||||
return vulns
|
||||
|
||||
|
||||
def check_cisa_kev(cve_list):
|
||||
"""Check CVEs against CISA Known Exploited Vulnerabilities catalog."""
|
||||
try:
|
||||
resp = requests.get("https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json", timeout=15)
|
||||
resp.raise_for_status()
|
||||
kev_data = resp.json()
|
||||
kev_cves = {v["cveID"] for v in kev_data.get("vulnerabilities", [])}
|
||||
in_kev = [cve for cve in cve_list if cve in kev_cves]
|
||||
logger.info("Found %d CVEs in CISA KEV", len(in_kev))
|
||||
return in_kev
|
||||
except requests.RequestException as e:
|
||||
logger.warning("Failed to check CISA KEV: %s", e)
|
||||
return []
|
||||
|
||||
|
||||
def prioritize_patches(vulns, kev_cves):
|
||||
"""Prioritize patches based on CVSS, exploitation status, and CISA KEV."""
|
||||
for vuln in vulns:
|
||||
priority_score = 0
|
||||
if vuln["exploited_in_wild"]:
|
||||
priority_score += 40
|
||||
if vuln["cve"] in kev_cves:
|
||||
priority_score += 30
|
||||
if vuln["cvss_score"] >= 9.0:
|
||||
priority_score += 20
|
||||
elif vuln["cvss_score"] >= 7.0:
|
||||
priority_score += 10
|
||||
if vuln["severity"].lower() == "critical":
|
||||
priority_score += 10
|
||||
vuln["priority_score"] = priority_score
|
||||
if priority_score >= 60:
|
||||
vuln["deployment_urgency"] = "emergency"
|
||||
vuln["sla_hours"] = 24
|
||||
elif priority_score >= 40:
|
||||
vuln["deployment_urgency"] = "critical"
|
||||
vuln["sla_hours"] = 72
|
||||
elif priority_score >= 20:
|
||||
vuln["deployment_urgency"] = "standard"
|
||||
vuln["sla_hours"] = 168
|
||||
else:
|
||||
vuln["deployment_urgency"] = "routine"
|
||||
vuln["sla_hours"] = 720
|
||||
return sorted(vulns, key=lambda v: v["priority_score"], reverse=True)
|
||||
|
||||
|
||||
def generate_deployment_plan(prioritized_vulns):
|
||||
"""Generate phased deployment plan."""
|
||||
phases = {"emergency_24h": [], "critical_72h": [], "standard_7d": [], "routine_30d": []}
|
||||
for vuln in prioritized_vulns:
|
||||
urgency = vuln.get("deployment_urgency", "routine")
|
||||
entry = {"cve": vuln["cve"], "title": vuln["title"], "cvss": vuln["cvss_score"],
|
||||
"exploited": vuln["exploited_in_wild"]}
|
||||
if urgency == "emergency":
|
||||
phases["emergency_24h"].append(entry)
|
||||
elif urgency == "critical":
|
||||
phases["critical_72h"].append(entry)
|
||||
elif urgency == "standard":
|
||||
phases["standard_7d"].append(entry)
|
||||
else:
|
||||
phases["routine_30d"].append(entry)
|
||||
return phases
|
||||
|
||||
|
||||
def generate_report(vulns, kev_cves, deployment_plan, year_month):
|
||||
"""Generate Patch Tuesday response report."""
|
||||
report = {
|
||||
"timestamp": datetime.utcnow().isoformat(),
|
||||
"patch_tuesday": year_month,
|
||||
"total_vulnerabilities": len(vulns),
|
||||
"actively_exploited": sum(1 for v in vulns if v.get("exploited_in_wild")),
|
||||
"in_cisa_kev": len(kev_cves),
|
||||
"critical_cvss": sum(1 for v in vulns if v.get("cvss_score", 0) >= 9.0),
|
||||
"deployment_plan": deployment_plan,
|
||||
"top_10_priority": [{"cve": v["cve"], "title": v["title"], "cvss": v["cvss_score"],
|
||||
"exploited": v["exploited_in_wild"], "priority": v["priority_score"]}
|
||||
for v in vulns[:10]],
|
||||
}
|
||||
print(f"PATCH TUESDAY REPORT ({year_month}): {len(vulns)} vulns, "
|
||||
f"{report['actively_exploited']} exploited, {len(kev_cves)} in KEV")
|
||||
return report
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Patch Tuesday Response Process Agent")
|
||||
parser.add_argument("--api-key", required=True, help="MSRC API key")
|
||||
parser.add_argument("--month", required=True, help="Year-Month (e.g., 2024-Jan)")
|
||||
parser.add_argument("--output", default="patch_tuesday_report.json")
|
||||
args = parser.parse_args()
|
||||
|
||||
cvrf_data = fetch_patch_tuesday_updates(args.api_key, args.month)
|
||||
vulns = parse_vulnerabilities(cvrf_data)
|
||||
cve_list = [v["cve"] for v in vulns]
|
||||
kev_cves = check_cisa_kev(cve_list)
|
||||
prioritized = prioritize_patches(vulns, set(kev_cves))
|
||||
deployment_plan = generate_deployment_plan(prioritized)
|
||||
report = generate_report(prioritized, kev_cves, deployment_plan, args.month)
|
||||
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()
|
||||
Reference in New Issue
Block a user