安全情报收集自动化:CVE/NVD数据源接入、威胁情报源配置、自动化爬虫与API采集

设备漏洞响应的第一步,不是去修漏洞,而是先知道漏洞在哪。

我见过太多团队,漏洞公告都发布三天了,安全运维还在手动刷网页。说实话,这种效率根本跟不上攻击者的节奏。自动化情报收集,就是给你的响应流程装上雷达——提前发现、提前准备。

2.1 核心数据源:CVE与NVD

CVE(Common Vulnerabilities and Exposures)是全球通用的漏洞编号体系。每个漏洞都有一个唯一的CVE ID,比如CVE-2024-3094。NVD(National Vulnerability Database)则是美国国家标准与技术研究院维护的增强版数据库,它给每个CVE打了CVSS评分、加了影响产品列表、补丁链接等元数据。

我个人习惯把NVD当作主数据源。为什么?因为它的API最成熟,数据最结构化。你直接去拉CVE列表,还得自己解析描述文本,但NVD直接给你JSON格式的评分和影响范围。

核心数据字段清单:
  • CVE ID —— 漏洞唯一标识
  • CVSS v3.1 评分 —— 严重程度(0-10)
  • 影响产品(CPE) —— 匹配你设备库的关键
  • 漏洞描述 —— 理解攻击原理
  • 参考链接 —— 补丁、PoC、厂商公告
  • 发布时间 & 最后修改时间 —— 时效性判断

2.2 NVD API 接入实战

NVD在2.0版本后提供了RESTful API,不需要API Key就能用。但注意,它有速率限制——每30秒最多5个请求。嗯,这里要注意,如果你要批量拉取历史数据,必须加sleep。

下面是我常用的Python采集脚本骨架:

import requests
import time
import json

def fetch_nvd_cves(start_index=0, results_per_page=20):
    base_url = "https://services.nvd.nist.gov/rest/json/cves/2.0"
    params = {
        "startIndex": start_index,
        "resultsPerPage": results_per_page,
        "pubStartDate": "2024-01-01T00:00:00.000",
        "pubEndDate": "2024-12-31T23:59:59.999"
    }
    
    try:
        resp = requests.get(base_url, params=params, timeout=30)
        resp.raise_for_status()
        data = resp.json()
        
        vulnerabilities = data.get("vulnerabilities", [])
        total_results = data.get("totalResults", 0)
        
        print(f"获取到 {len(vulnerabilities)} 条记录,总计 {total_results} 条")
        return vulnerabilities, total_results
    except requests.exceptions.RequestException as e:
        print(f"请求失败: {e}")
        return [], 0

# 分页采集示例
all_cves = []
start = 0
page_size = 20

while True:
    cves, total = fetch_nvd_cves(start, page_size)
    if not cves:
        break
    all_cves.extend(cves)
    start += page_size
    time.sleep(6)  # 严格遵守速率限制
    if start >= total:
        break

print(f"共采集 {len(all_cves)} 条CVE记录")
避坑指南:我曾经在生产环境忘了加time.sleep,结果IP被NVD临时封了半小时。后来我改用异步请求+令牌桶限流,既保证速率合规,又提升了采集效率。

2.3 威胁情报源配置

光靠NVD不够。NVD的数据更新有延迟,而且它只收录已公开的漏洞。真正的威胁情报源,能告诉你哪些漏洞正在被野外利用、哪些PoC已经流出。

我常用的几个情报源:

情报源 数据类型 接入方式 更新频率
Exploit-DB PoC/Exp代码 API + RSS 每日
VulnCheck 漏洞利用情报 REST API 实时
GreyNoise 互联网扫描数据 API Key 实时
Twitter/X 安全账号 零日预警 爬虫/API 分钟级

你想想看,如果NVD还没收录某个漏洞,但GreyNoise已经检测到全球有5000个IP在扫描相关端口,这意味着什么?意味着你的设备可能已经被盯上了。这就是情报源互补的价值。

2.4 自动化爬虫与API采集架构

把多个数据源整合到一起,需要一个统一的采集层。我习惯用三层架构:

  1. 采集适配层 —— 每个数据源一个适配器,统一输出标准格式
  2. 数据清洗层 —— 去重、字段映射、时间标准化
  3. 存储层 —— 写入Elasticsearch或时序数据库,供后续匹配使用

下面是我画的一个采集架构图,你看一眼就明白了:

自动化情报采集架构 NVD API Exploit-DB GreyNoise 采集适配层(统一格式、限流、重试) 数据清洗层(去重、字段映射、时间标准化) 存储层(Elasticsearch / 时序数据库) 输出:标准化情报事件流

2.5 爬虫采集的注意事项

有些情报源没有API,或者API收费太贵。这时候就得靠爬虫。但爬虫不是乱爬的,有几个原则必须遵守:

  • 遵守robots.txt —— 别给自己惹法律麻烦
  • 设置合理的User-Agent —— 别用默认的Python-urllib
  • 控制请求频率 —— 加随机延迟,别把人家服务器打挂了
  • 处理反爬机制 —— 验证码、IP封禁、动态渲染页面
重要提醒:我曾经爬一个安全论坛,没注意频率控制,结果对方直接封了我整个C段。后来我改用代理池+随机User-Agent+请求间隔3-8秒随机化,才稳定下来。记住,爬虫的目的是获取数据,不是搞破坏。

2.6 情报去重与关联

同一个漏洞,NVD有记录,Exploit-DB有PoC,Twitter上有人在讨论。如果你不做去重,同一个CVE会在你的系统里出现三次,后续的匹配和告警就会乱套。

我的做法是:以CVE ID为唯一主键,所有情报源的数据都挂载到这个主键下。比如:

{
  "cve_id": "CVE-2024-3094",
  "nvd": {
    "cvss_score": 9.8,
    "published": "2024-03-29",
    "affected_products": ["cpe:2.3:a:xz:utils:*:*:*:*:*:*:*:*"]
  },
  "exploit_db": {
    "has_poc": true,
    "poc_url": "https://www.exploit-db.com/exploits/51970"
  },
  "grey_noise": {
    "scanning_ips": 12400,
    "first_seen": "2024-03-30"
  },
  "twitter_mentions": [
    {"user": "@security_alerts", "tweet": "CVE-2024-3094 正在被大规模利用"}
  ]
}

这样,后续的漏洞匹配只需要查这一个文档,效率高得多。

2.7 自动化调度与监控

采集任务不能只跑一次。你得让它定时跑、持续跑。我一般用Celery或APScheduler做定时调度:

  • NVD全量采集:每天凌晨2点跑一次
  • NVD增量采集:每30分钟跑一次
  • Exploit-DB:每小时检查一次新提交
  • GreyNoise:实时推送(Webhook)
  • Twitter爬虫:每5分钟扫描一次关键词
个人经验:我建议给每个采集任务加一个健康检查接口。如果某个数据源连续3次采集失败,自动发告警到钉钉/企业。别等到漏洞爆发了,才发现情报源已经断了好几天。

好了,情报收集这块就讲这么多。说白了,自动化采集的核心就三件事:知道去哪拿数据、怎么稳定地拿、拿回来后怎么整理好。下一层,我们就要用这些情报去匹配你的设备资产了——那才是真正产生价值的地方。