
fleet-cve-scanner v1.1.0
Открытый сканер CVE с одним скриптом для парков управляемых через RMM. Чистый PowerShell 7 — сопоставляет инвентарь программного обеспечения вашего RMM с NVD, CISA KEV, EPSS и SSVC, чтобы ответить: уязвима ли эта версия и насколько это срочно?
fleet-cve-scanner
Сканер CVE с открытым исходным кодом для флотов, управляемых через RMM. Один скрипт на чистом PowerShell 7, без агентов, без серверных компонентов, без лицензионных отчислений.
Он отвечает на один вопрос для каждого программного обеспечения на каждом управляемом устройстве: известно ли, что установленная версия уязвима, и насколько это срочно? — объединяя инвентаризацию ПО вашего RMM с бесплатными авторитетными источниками безопасности:
- NIST NVD — известные CVE + затронутые версионные диапазоны
- CISA KEV — активно эксплуатируемые в реальных атаках (обходит порог оценки)
- EPSS — вероятность эксплуатации в ближайшие 30 дней
- CISA SSVC — решения о приоритете: действовать / обратить внимание / отслеживать
- MSRC — подтверждение, что патч Microsoft уже покрывает находку
- endoflife.date — ПО, для которого больше не будет патчей
Результаты: отчёт CSV по каждому устройству, история SQLite с часами SLA и событиями изменений неделя к неделе, самодостаточная HTML-панель управления и опциональный отчёт об уязвимостях в формате Markdown.
Статус
v1.0.0. Движок был перенесён «изолированно» со сканера, который еженедельно выполнялся в продакшене для Windows-флота (см. docs/HISTORY.md). Перед этим релизом оба сканера запускались на одном и том же живом флоте и сравнивались построчно: по десяткам тысяч находок, где оба видели одинаковую тройку (устройство, ПО, версия), каждое вычисленное поле — статус, CVSS, уровень серьёзности, флаг KEV, решение SSVC, версия исправления — полностью совпало.
Это сравнение покрывает логику вердикта. Оно не тестировало слой истории/SLA и не заменяет проверку инструмента в вашем окружении. Прочтите docs/known-limitations.md, прежде чем доверять ему — он написан честно, а не лестно.
Быстрый старт
Вам понадобится PowerShell 7 (pwsh). Два способа запуска:
A. Живое сканирование через NinjaOne
cp config.example.json config.json
# отредактируйте config.json: укажите ninjaone.client_id / client_secret / base_url,
# установите output.report_dir и (рекомендуется) nvd.api_key
pwsh -File fleet-cve-scan.ps1
B. Офлайн — любой RMM, SCCM или Intune (без доступа к API)
Экспортируйте инвентаризацию в CSV с колонками hostname, software, version (опционально device_id, os), затем:
cp config.example.json config.json # здесь нужен только output.report_dir
pwsh -File fleet-cve-scan.ps1 -InputCsv inventory.csv
-InputCsv не выполняет ни одного вызова NinjaOne — никакого OAuth, никакого API. Он всё равно запрашивает NVD и другие публичные каналы, поэтому вам также понадобится nvd.api_key в config.json и корректный output.report_dir. См. docs/rmm-adapters.md для описания контракта входных данных и инструкций по экспорту для каждого RMM.
Установка предварительных компонентов
- PowerShell 7 — macOS:
brew install powershell; Windows:winget install Microsoft.PowerShell; Debian/Ubuntu: установка из репозитория Microsoft (packages.microsoft.com). - sqlite3 (опционально, для истории/трендов) — macOS: предустановлен или
brew install sqlite; Debian/Ubuntu:apt-get install sqlite3; Windows: скачайте пакет «tools» SQLite с sqlite.org и поместитеsqlite3.exeвPATHили рядом со скриптом. Без него сканирование всё равно выполняется;first_seenбудет установлен на дату запуска.
Требования
- PowerShell 7 (рекомендуется 7.4+). Параллельное сканирование требует 7.0+.
- sqlite3 — опционально; включает базу данных истории, тренды и отслеживание
first_seenдля SLA. Отсутствует = эти функции пропускаются, сканирование завершается. - Исходящий сетевой трафик к NVD, CISA (KEV),
epss.empiricalsecurity.com(хост массовых оценок EPSS — FIRST переместил хостинг данных EPSS туда), MSRC, endoflife.date и GitHub raw (CVE ProgramcvelistV5) — плюс API NinjaOne в живом режиме. - Учётные данные — живому режиму требуется OAuth2-идентификатор/секрет клиента NinjaOne; офлайн-режиму нужен только CSV инвентаризации. API-ключ NVD технически не обязателен, но фактически требуется для масштаба флота: NVD разрешает 50 запросов за 30 секунд с ключом и только 5 за 30 секунд без него. Сканер определяет, какой у вас ключ, и подстраивает троттлинг, так что запуск без ключа корректен, но примерно в 10 раз медленнее — нормально для нескольких продуктов, но непрактично для реального флота. Ключи бесплатны.
Справочник по конфигурации
Конфигурация — это JSON-файл (по умолчанию config.json рядом со скриптом; можно переопределить с помощью -ConfigPath). Начните с config.example.json. Все ключи, которые читает сканер, значения по умолчанию при их отсутствии и что они делают:
ninjaone (живой режим)
| Ключ | По умолчанию | Назначение |
|---|---|---|
ninjaone.client_id | "" | OAuth2-идентификатор клиента API NinjaOne. Обязателен для живого сканирования; оставьте пустым для -InputCsv. |
ninjaone.client_secret | "" | Секрет клиента API NinjaOne. |
ninjaone.base_url | — (в примере указано https://app.ninjarmm.com) | Базовый URL API NinjaOne; обязателен для живого сканирования, встроенного запасного варианта нет. Используйте хост вашего региона (например, eu.ninjarmm.com, oc.ninjarmm.com). |
nvd
| Ключ | По умолчанию | Назначение |
|---|---|---|
nvd.api_key | "" | API-ключ NVD, отправляется как заголовок apiKey. Пустое значение — неаутентифицированный доступ, который понижает значения по умолчанию для nvd_rate_limit и nvd_min_spacing_ms до анонимных лимитов NVD (4/30с, 6500 мс) вместо аутентифицированных (48/30с, 700 мс). Бесплатный и ~в 10 раз быстрее. |
Сканирование и оценка
| Ключ | По умолчанию | Назначение |
|---|---|---|
cvss_threshold | 7.0 | Минимальная базовая оценка CVSS для того, чтобы CVE с оценкой считался УЯЗВИМЫМ. CVE из списка KEV обходят этот порог. |
ssvc_mission_prevalence | high | Входные данные заинтересованной стороны для Mission Prevalence в SSVC (low / medium / high). |
ssvc_public_wellbeing | high | Входные данные заинтересованной стороны для Public Well-being в SSVC (low / medium / high). |