Asi performing-cve-prioritization-with-kev-catalog
Leverage the CISA Known Exploited Vulnerabilities catalog alongside EPSS and CVSS to prioritize CVE remediation based on real-world exploitation evidence.
git clone https://github.com/plurigrid/asi
T=$(mktemp -d) && git clone --depth=1 https://github.com/plurigrid/asi "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/asi/skills/performing-cve-prioritization-with-kev-catalog" ~/.claude/skills/plurigrid-asi-performing-cve-prioritization-with-kev-catalog && rm -rf "$T"
plugins/asi/skills/performing-cve-prioritization-with-kev-catalog/SKILL.mdPerforming CVE Prioritization with KEV Catalog
Overview
The CISA Known Exploited Vulnerabilities (KEV) catalog, established through Binding Operational Directive (BOD) 22-01, is a living list of CVEs that have been actively exploited in the wild and carry significant risk. As of early 2026, the catalog contains over 1,484 entries, growing 20% in 2025 alone with 245 new additions. This skill covers integrating the KEV catalog into vulnerability prioritization workflows alongside EPSS (Exploit Prediction Scoring System) and CVSS to create a risk-based approach that prioritizes vulnerabilities with confirmed exploitation activity over theoretical severity alone.
When to Use
- When conducting security assessments that involve performing cve prioritization with kev catalog
- When following incident response procedures for related security events
- When performing scheduled security testing or auditing activities
- When validating security controls through hands-on testing
Prerequisites
- Access to vulnerability scan results (Qualys, Nessus, Rapid7, etc.)
- Familiarity with CVE identifiers and NVD
- Understanding of CVSS scoring (v3.1 and v4.0)
- API access to CISA KEV, EPSS, and NVD endpoints
- Python 3.8+ with requests and pandas libraries
Core Concepts
CISA KEV Catalog Structure
Each KEV entry contains:
- CVE ID: The CVE identifier (e.g., CVE-2024-3094)
- Vendor/Project: Affected vendor and product name
- Vulnerability Name: Short description of the vulnerability
- Date Added: When CISA added it to the catalog
- Short Description: Brief technical description
- Required Action: Recommended remediation action
- Due Date: Deadline for federal agencies (FCEB) to remediate
- Known Ransomware Campaign Use: Whether ransomware groups exploit it
BOD 22-01 Remediation Timelines
| CVE Publication Date | Remediation Deadline |
|---|---|
| 2021 or later | 2 weeks from KEV listing |
| Before 2021 | 6 months from KEV listing |
Multi-Factor Prioritization Model
| Factor | Weight | Data Source | Rationale |
|---|---|---|---|
| CISA KEV Listed | 30% | CISA KEV JSON feed | Confirmed active exploitation |
| EPSS Score | 25% | FIRST EPSS API | Predicted exploitation probability |
| CVSS Base Score | 20% | NVD API v2.0 | Intrinsic vulnerability severity |
| Asset Criticality | 15% | CMDB/Asset inventory | Business impact context |
| Network Exposure | 10% | Network architecture | Attack surface accessibility |
KEV + EPSS Decision Matrix
| KEV Listed | EPSS > 0.5 | CVSS >= 9.0 | Priority | SLA |
|---|---|---|---|---|
| Yes | Any | Any | P1-Emergency | 48 hours |
| No | Yes | Yes | P1-Emergency | 48 hours |
| No | Yes | No | P2-Critical | 7 days |
| No | No | Yes | P2-Critical | 7 days |
| No | No | No (>= 7.0) | P3-High | 14 days |
| No | No | No (>= 4.0) | P4-Medium | 30 days |
| No | No | No (< 4.0) | P5-Low | 90 days |
Workflow
Step 1: Fetch and Parse the KEV Catalog
import requests import json from datetime import datetime KEV_URL = "https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json" def fetch_kev_catalog(): """Download and parse the CISA KEV catalog.""" response = requests.get(KEV_URL, timeout=30) response.raise_for_status() data = response.json() catalog = {} for vuln in data.get("vulnerabilities", []): cve_id = vuln["cveID"] catalog[cve_id] = { "vendor": vuln.get("vendorProject", ""), "product": vuln.get("product", ""), "name": vuln.get("vulnerabilityName", ""), "date_added": vuln.get("dateAdded", ""), "description": vuln.get("shortDescription", ""), "action": vuln.get("requiredAction", ""), "due_date": vuln.get("dueDate", ""), "ransomware_use": vuln.get("knownRansomwareCampaignUse", "Unknown"), } print(f"[+] Loaded {len(catalog)} CVEs from CISA KEV catalog") print(f" Catalog version: {data.get('catalogVersion', 'N/A')}") print(f" Last updated: {data.get('dateReleased', 'N/A')}") return catalog kev = fetch_kev_catalog()
Step 2: Enrich with EPSS Scores
EPSS_API = "https://api.first.org/data/v1/epss" def get_epss_scores(cve_list): """Fetch EPSS scores for a batch of CVEs.""" scores = {} batch_size = 100 for i in range(0, len(cve_list), batch_size): batch = cve_list[i:i + batch_size] cve_param = ",".join(batch) response = requests.get(EPSS_API, params={"cve": cve_param}, timeout=30) if response.status_code == 200: for entry in response.json().get("data", []): scores[entry["cve"]] = { "epss": float(entry.get("epss", 0)), "percentile": float(entry.get("percentile", 0)), } return scores
Step 3: Build the Prioritization Engine
import pandas as pd def prioritize_vulnerabilities(scan_results, kev_catalog, epss_scores): """Apply multi-factor prioritization to scan results.""" prioritized = [] for vuln in scan_results: cve_id = vuln.get("cve_id", "") cvss_score = float(vuln.get("cvss_score", 0)) asset_criticality = float(vuln.get("asset_criticality", 3)) exposure = float(vuln.get("network_exposure", 3)) in_kev = cve_id in kev_catalog kev_data = kev_catalog.get(cve_id, {}) epss_data = epss_scores.get(cve_id, {"epss": 0, "percentile": 0}) epss_score = epss_data["epss"] # Composite risk score calculation risk_score = ( (1.0 if in_kev else 0.0) * 10 * 0.30 + epss_score * 10 * 0.25 + cvss_score * 0.20 + (asset_criticality / 5.0) * 10 * 0.15 + (exposure / 5.0) * 10 * 0.10 ) # Assign priority level if in_kev or (epss_score > 0.5 and cvss_score >= 9.0): priority = "P1-Emergency" sla_days = 2 elif epss_score > 0.5 or cvss_score >= 9.0: priority = "P2-Critical" sla_days = 7 elif cvss_score >= 7.0: priority = "P3-High" sla_days = 14 elif cvss_score >= 4.0: priority = "P4-Medium" sla_days = 30 else: priority = "P5-Low" sla_days = 90 prioritized.append({ "cve_id": cve_id, "cvss_score": cvss_score, "epss_score": round(epss_score, 4), "epss_percentile": round(epss_data["percentile"], 4), "in_cisa_kev": in_kev, "ransomware_use": kev_data.get("ransomware_use", "N/A"), "kev_due_date": kev_data.get("due_date", "N/A"), "risk_score": round(risk_score, 2), "priority": priority, "sla_days": sla_days, "asset": vuln.get("asset", ""), "asset_criticality": asset_criticality, }) df = pd.DataFrame(prioritized) df = df.sort_values("risk_score", ascending=False) return df
Step 4: Generate Prioritization Report
def generate_report(df, output_file="kev_prioritized_report.csv"): """Generate summary report from prioritized vulnerabilities.""" print("\n" + "=" * 70) print("VULNERABILITY PRIORITIZATION REPORT - KEV + EPSS + CVSS") print("=" * 70) print(f"\nTotal vulnerabilities analyzed: {len(df)}") print(f"KEV-listed vulnerabilities: {df['in_cisa_kev'].sum()}") print(f"Ransomware-associated: {(df['ransomware_use'] == 'Known').sum()}") print("\nPriority Distribution:") print(df["priority"].value_counts().to_string()) print("\nTop 15 Highest Risk Vulnerabilities:") top = df.head(15)[["cve_id", "cvss_score", "epss_score", "in_cisa_kev", "risk_score", "priority"]] print(top.to_string(index=False)) df.to_csv(output_file, index=False) print(f"\n[+] Full report saved to: {output_file}")
Best Practices
- Update the KEV catalog daily since CISA adds new entries multiple times per week
- Always cross-reference KEV with EPSS; a CVE may have high EPSS but not yet be in KEV
- Treat all KEV-listed CVEs as P1-Emergency regardless of CVSS score
- Pay special attention to KEV entries flagged with "Known Ransomware Campaign Use"
- Automate KEV comparison against your vulnerability scan results in CI/CD pipelines
- Track KEV due dates separately for FCEB compliance requirements
- Use KEV as a leading indicator for threat hunting; if a CVE is added, check for prior exploitation in your environment
Common Pitfalls
- Relying solely on CVSS scores without checking KEV or EPSS data
- Not updating the KEV catalog frequently enough (CISA updates multiple times weekly)
- Treating non-KEV CVEs as safe; they may be exploited but not yet cataloged
- Ignoring the "ransomware use" field which indicates highest-urgency threats
- Using KEV only for compliance instead of integrating into overall risk management
Related Skills
- prioritizing-vulnerabilities-with-cvss-scoring
- building-vulnerability-data-pipeline-with-api
- implementing-threat-intelligence-scoring
- implementing-vulnerability-remediation-sla