mcpField
I
implementing-epss-score-for-vulnerability-prioritization

implementing-epss-score-for-vulnerability-prioritization

github.com/mukul975安全35.2k49 次安装8 周前更新
代码仓库

关于 implementing-epss-score-for-vulnerability-prioritization

面向漏洞管理和安全团队的实施指南,利用 FIRST EPSS 评估 CVE 在未来 30 天内遭利用的概率。指南说明如何查询分数、结合 CVSS 排定修复优先级,并分析历史趋势。

主要功能

  1. 01查询单个或批量 CVE 分数
  2. 02下载完整 EPSS 数据集
  3. 03获取历史分数与时间序列
  4. 04结合 CVSS 设定修复优先级
  5. 05分析 EPSS 分数趋势

适用场景

  1. 01按利用概率排列扫描发现的漏洞
  2. 02识别需要紧急修复的 CVE
  3. 03跟踪漏洞利用风险随时间的变化

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mukul975/anthropic-cybersecurity-skills --skill implementing-epss-score-for-vulnerability-prioritization

安装后在 Claude Code 中输入/implementing-epss-score-for-vulnerability-prioritization确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

LICENSE
assets/
template.md
references/
api-reference.md
standards.md
workflows.md
scripts/
agent.py
process.py

详细介绍

为漏洞优先级排序实现 EPSS 评分

概述

漏洞利用预测评分系统(EPSS)是由 FIRST(事件响应与安全团队论坛)开发的一种数据驱动模型,用于估计某个 CVE 在未来 30 天内被在野利用的概率。EPSS 使用基于真实世界漏洞利用数据训练的机器学习,产出 0.0 到 1.0(0% 到 100%)的评分。与衡量严重程度的 CVSS 不同,EPSS 衡量的是被利用的可能性,因此对于基于风险的漏洞优先级排序至关重要。

何时使用

  • 在环境中部署或配置“为漏洞优先级排序实现 EPSS 评分”能力时
  • 在建立符合合规要求的安全控制措施时
  • 在为该领域构建或改进安全架构时
  • 在开展需要此实现的安全评估时

前提条件

  • Python 3.9+,并安装 requests、pandas、matplotlib
  • 可访问 FIRST EPSS API(https://api.first.org/data/v1/epss)
  • 带有 CVE 标识符的漏洞扫描结果
  • 可选:用于 CVSS 增强的 NVD API 密钥

EPSS API 用法

查询单个 CVE
# Get EPSS score for a specific CVE
curl -s "https://api.first.org/data/v1/epss?cve=CVE-2024-3400" | python3 -m json.tool

# Response:
# {
#   "status": "OK",
#   "status-code": 200,
#   "version": "1.0",
#   "total": 1,
#   "data": [
#     {
#       "cve": "CVE-2024-3400",
#       "epss": "0.95732",
#       "percentile": "0.99721",
#       "date": "2024-04-15"
#     }
#   ]
# }
查询多个 CVE
# Batch query up to 100 CVEs
curl -s "https://api.first.org/data/v1/epss?cve=CVE-2024-3400,CVE-2024-21887,CVE-2023-44228" | \
  python3 -c "
import sys, json
data = json.load(sys.stdin)
for item in data['data']:
    pct = float(item['epss']) * 100
    print(f\"{item['cve']}: {pct:.2f}% exploitation probability (percentile: {item['percentile']})\")
"
下载完整 EPSS 数据集
# Download complete daily EPSS scores (CSV format)
curl -s "https://epss.cyentia.com/epss_scores-current.csv.gz" | gunzip > epss_scores_current.csv

# Check size and preview
wc -l epss_scores_current.csv
head -5 epss_scores_current.csv
查询历史 EPSS 评分
# Get EPSS score for a specific date
curl -s "https://api.first.org/data/v1/epss?cve=CVE-2024-3400&date=2024-04-12"

# Get time series data
curl -s "https://api.first.org/data/v1/epss?cve=CVE-2024-3400&scope=time-series"

优先级排序策略

EPSS + CVSS 组合方法
EPSS 评分CVSS 评分优先级操作
> 0.7>= 9.0P0 - 立即24 小时内修复
> 0.7>= 7.0P1 - 紧急48 小时内修复
> 0.4>= 7.0P2 - 高7 天内修复
> 0.1>= 4.0P3 - 中30 天内修复
<= 0.1>= 7.0P3 - 中30 天内修复
<= 0.1< 7.0P4 - 低90 天内修复
EPSS 百分位阈值
  • 前 1%(百分位 >= 0.99):极有可能被利用;视为严重
  • 前 5%(百分位 >= 0.95):利用概率高;优先修复
  • 前 10%(百分位 >= 0.90):风险升高;安排近期修复
  • 后 50%:利用概率低;按正常补丁周期处理

实现

import requests
import pandas as pd
from datetime import datetime

def fetch_epss_scores(cve_list):
    """Fetch EPSS scores for a list of CVEs from FIRST API."""
    scores = {}
    batch_size = 100
    for i in range(0, len(cve_list), batch_size):
        batch = cve_list[i:i + batch_size]
        resp = requests.get(
            "https://api.first.org/data/v1/epss",
            params={"cve": ",".join(batch)},
            timeout=30
        )
        if resp.status_code == 200:
            for entry in resp.json().get("data", []):
                scores[entry["cve"]] = {
                    "epss": float(entry["epss"]),
                    "percentile": float(entry["percentile"]),
                    "date": entry.get("date", ""),
                }
    return scores

def prioritize_vulnerabilities(scan_results_csv, output_csv):
    """Enrich scan results with EPSS scores and assign priorities."""
    df = pd.read_csv(scan_results_csv)
    cve_list = df["cve_id"].dropna().unique().tolist()

    epss_data = fetch_epss_scores(cve_list)

    df["epss_score"] = df["cve_id"].map(lambda c: epss_data.get(c, {}).get("epss", 0))
    df["epss_percentile"] = df["cve_id"].map(lambda c: epss_data.get(c, {}).get("percentile", 0))

    def assign_priority(row):
        epss = row.get("epss_score", 0)
        cvss = row.get("cvss_score", 0)
        if epss > 0.7 and cvss >= 9.0:
            return "P0"
        if epss > 0.7 and cvss >= 7.0:
            return "P1"
        if epss > 0.4 and cvss >= 7.0:
            return "P2"
        if epss > 0.1 or cvss >= 7.0:
            return "P3"
        return "P4"

    df["priority"] = df.apply(assign_priority, axis=1)
    df = df.sort_values(["priority", "epss_score"], ascending=[True, False])
    df.to_csv(output_csv, index=False)
    print(f"[+] Prioritized {len(df)} vulnerabilities -> {output_csv}")
    print(f"    P0: {len(df[df['priority']=='P0'])}")
    print(f"    P1: {len(df[df['priority']=='P1'])}")
    print(f"    P2: {len(df[df['priority']=='P2'])}")
    print(f"    P3: {len(df[df['priority']=='P3'])}")
    print(f"    P4: {len(df[df['priority']=='P4'])}")
    return df

EPSS 趋势分析

def fetch_epss_timeseries(cve_id):
    """Get historical EPSS scores for trend analysis."""
    resp = requests.get(
        "https://api.first.org/data/v1/epss",
        params={"cve": cve_id, "scope": "time-series"},
        timeout=30
    )
    if resp.status_code == 200:
        return resp.json().get("data", [])
    return []

def detect_epss_spikes(cve_id, threshold=0.3):
    """Detect significant EPSS score increases indicating emerging threats."""
    timeseries = fetch_epss_timeseries(cve_id)
    if len(timeseries) < 2:
        return False
    sorted_data = sorted(timeseries, key=lambda x: x.get("date", ""))
    latest = float(sorted_data[-1].get("epss", 0))
    previous = float(sorted_data[-2].get("epss", 0))
    increase = latest - previous
    if increase >= threshold:
        print(f"[!] EPSS spike detected for {cve_id}: {previous:.3f} -> {latest:.3f} (+{increase:.3f})")
        return True
    return False

参考资料

评论

支持 Markdown