安全软件
点击放大

An open-source, single-script C for RMM-managed fleets. Pure
PowerShell 7, no agents, no appliances, no license fees.
It answers one question for every piece of software on every endpoint you
manage: **is the installed known to be , and how urgent is
it?** — by joining your RMM's software in against free, authoritative
security feeds:
Outputs: a per-device CS, a SQLite history with SLA clocks and
week-o change events, a self-contained HTML dashboard, and an optional
markdown exposure report.
v1.0.0. The engine was ported clean-room from a scanner that ran weekly in
production against a Windows fleet (see
docs/HISTORY.md). Before this release the two were run
against the same li and compared row-for-row: across tens of thousands
of findings where both saw an identical *(device, software, )*, every
computed field — status, CVSS, se, KEV flag, SS, fix —
matched exactly.
That comparison covers the logic. It did not exercise the
history/SLA layer, and it is not a substitute for the tool in your
own en. Read docs/known-limitations.md
before trusting it — it is written to be honest rather than flattering.
You need PowerShell 7 (pwsh). Two ways to run:
Export your in to a CSV with columns hostname, software,
(optional de, os), then:
-InputCsv makes zero NinjaOne calls — no OAuth, no API. It still queries
NVD and the other public feeds, so you still want an n inconfig.json and a valid output.report_dir. See
docs/rmm-adapters.md for the input contract and
per-RMM export recipes.
brew install powershell; Windows:winget install Microsoft.PowerShell; Debian/Ubuntu: install from thepackages.microsoft.com).brew install sqlite; Debian/Ubuntu: apt-get install sqlite3; Windows:sqlite3.exe onPATH or beside the script. Without it the scan still runs; first_seenfirst_seen tracking. Absent = those features skip, scan still completes.epss.empiricalsecurity.comc) — plus the NinjaOneConfig is a JSON file (default config.json beside the script; o with-ConfigPath). Start from config.example.json. Every
key the scanner reads, its default when omitted, and what it does:
ninjaone (live mode)| Key | Default | Purpose |
| --- | --- | --- |
| ninjaone.client_id | "" | NinjaOne API OAuth2 client id. Required for li; lea for -InputCsv. |
| ninjaone.client_secret | "" | NinjaOne API OAuth2 client secret. |
| ninjaone.base_url | — (example ships ) | NinjaOne API base URL; required for li, no built-in fallback. Use your region's host (e.g. eu.ninjarmm.com, oc.ninjarmm.com). |
nvd| Key | Default | Purpose |
| --- | --- | --- |
| n | "" | NVD API key, sent as the apiKey header. Blank runs unauthenticated, which drops the defaults for n and n to NVD's anonymous ceiling (4/30s, 6500ms) instead of the authenticated one (48/30s, 700ms). Free, and ~10x faster. |
| Key | Default | Purpose |
| --- | --- | --- |
| c | 7.0 | Minimum CVSS base score for a scored CVE to be reported . KE C this floor. |
| ss | high | SS Pre stakeholder input (low / medium / high). |
| ss | high | SS Well-being stakeholder input (low / medium / high). |
| Key | Default | Purpose |
| --- | --- | --- |
| n | 7 | Days an N (per software name) stays cached before re-query. |
| n | 500 | Checkpoint the N to disk every N completed items, so a killed scan keeps its fetches. 0 disables (end-of-scan sa runs). |
| n | 700 with an API key, 6500 without | Minimum milliseconds between N. The binding rate constraint — tune this first. |
| n | 48 with an API key, 4 without | Sliding-window cap on N per 30s (a backstop). Floor of 1. |
| parallel_throttle | 20 | ForEach-Object -Parallel runspace count. N are serialized regardless; this only bounds cache-hit concurrency. Floor of 1. |
| ke | 24 | TTL for the cached CISA KE. |
| epss_cache_ttl_hours | 24 | TTL for the cached FIRST.org EPSS score file. |
| eol_cache_ttl_days | 7 | TTL for cached endoflife.date lookups. |
| msrc_cache_ttl_days | 30 | TTL for cached MSRC CVRF data. |
| c | 7 | TTL for cached C (c) / CISA-ADP SSVC data. |
| c | 300 | Max C fetches per run for SS enrichment; the rest defer to the next run. |
n, n, and parallel_throttle are read by the
scanner but not present in config.example.json — add them only if you need to
tune. See docs/rate-limiting.md.
| Key | Default | Purpose |
| --- | --- | --- |
| epss_spike_threshold | 0.10 | Minimum rise in a finding's EPSS score between scans to emit an EPSS_SPIKE change event. |
| sla_days_critical | 14 | SLA window (days from first_seen) for CRITICAL findings. |
| sla_days_high | 30 | SLA window for other scored se. |
| denied_software_csv | "" | Path to an optional denied-software CS. Empty disables the check. |
output| Key | Default | Purpose |
| --- | --- | --- |
| output.report_dir | *(required)* | Directory for all outputs — CS DB, dashboard, and caches. |
| output.wiki_security_page | "" | Optional path to a markdown exposure page. Written only when set. |
| output.dashboard_share | "" | Optional path/share that receives a copy of the dashboard each run. Empty = local-only. |
E below lands in output.report_dir.
.csv — the per-finding report. 28 columns.db — SQLite history (requires sqlite3): runs (per-runfindings (per (device, software, cve) open-finding historyfirst_seen / last_seen / resol / epss_score), andchanges (typed week-o events).c.html — self-contained HTML dashboard (charting libraryoutput.dashboard_share.eol-report-YYYY-MM-DD.csv — written when end-of-life families aredenied-report-YYYY-MM-DD.csv — written when denied_software_csv isn.json, ke.json, epss-cache.json,eol-cache.json, msrc-cache.json, c.json (all gitignored).output.wiki_security_page, only when set.The column set is fixed and gate-enforced. In order:
| # | Column | Meaning |
| --- | --- | --- |
| 1 | de | RMM device id (or a deterministic synthetic id in -InputCsv mode). |
| 2 | hostname | Device hostname. |
| 3 | os | Operating system string (may be blank). |
| 4 | software | Product name as in. |
| 5 | installed_ | string as in. |
| 6 | cve_id | C. |
| 7 | c | CVSS base score (0 if none). |
| 8 | se | C label. |
| 9 | c | Which C produced the score (4.0/3.1/3.0/2.0/blank). |
| 10 | epss_score | FIRST.org EPSS probability (blank if the CVE is absent from the catalog). |
| 11 | epss_percentile | EPSS percentile (blank if absent). |
| 12 | ss | Raw CISA SS option (none/poc/active; blank without ADP data). |
| 13 | ss | SS Act/Attend/Track (blank without ADP data). |
| 14 | status | / PATCHED / UNKNOWN. |
| 15 | published_date | C date. |
| 16 | unknown_reason | Why a row is UNKNOWN (SUSPECT_ / NO_ / ; blank otherwise). |
| 17 | is_kev | True when the CVE is on the CISA KE. |
| 18 | ke | CISA KE due date. |
| 19 | ke | KE use flag. |
| 20 | fix_ | Computed fix-boundary . |
| 21 | fix_boundary_inclusive | Whether the fix boundary is inclusive. |
| 22 | ad | ad or N URL. |
| 23 | patch_e | E when a Microsoft UNKNOWN was flipped to PATCHED. |
| 24 | triage_status | Triage disposition from triage.json (blank if none). |
| 25 | triage_note | Triage note. |
| 26 | first_seen | Date the finding was first observed (from the history DB). |
| 27 | sla_due | SLA due date. |
| 28 | sla_breach | Whether the SLA is breached. |
Run-WeeklyScan.ps1 is a wrapper for scheduled runs: it runs the scanner from
its own directory, captures all output streams to a dated log under<script dir>/logs/ (o with -LogDir), and propagates the scanner's
exit code so the scheduler sees failures.
Windows Task Scheduler:
cron (Linux/macOS):
c.html is fully self-contained — open it directly, drop it on any
static host or file share, or copy it automatically each run viaoutput.dashboard_share. For access-controlled hosting, thedashboard-auth/ directory ships a minimal ASP.NET host
with Microsoft Entra (Azure AD) authentication; see its
README and RUNBOOK.
-InputCsv mode lets anyThe full, unflinching list — the CPE skip rate, dedup-key masking, page-1totalResults, MSRC supersedence gaps, and more — is in
docs/known-limitations.md.
A few structural choices that look uncon are deliberate:
ForEach-Object -Parallel, and those runspaces cannot see outer-scope[PSCustomObject] records, not classes. Finding records are produced[PSCustomObject] does, and the CS contract is enforced by thetests/ arepwsh exists — including the scan server — with nothing to install. CIPRs welcome — RMM adapters most of all. See
CONTRIBUTING.md for the ground rules and the
safe-direction requirement (status logic may only err toward *more*
, ne toward PATCHED).
This tool is only as useful as the free, authoritati it joins against.
Each of the following is queried at scan time; please honor their terms if you
build on this.
c — C plus the SSVC / dataApache-2.0 — see LICENSE.
开发语言:PowerShell
Star 数:12
该项目属于安全软件方向的开源资源,代码结构清晰,适合安全研究人员学习参考。项目围绕An open-source, single-script CVE scanner for RMM-managed fleets. Pure PowerShell 7 — joins your RMM software inventory against NVD, CISA KEV, EPSS and SSVC to answer: is this version vulnerable, and how urgent is it?展开,提供了可运行的实现,对理解相关安全机制、工具原理与攻防技术具有较高的研究价值。
从技术实现角度看,此类项目的核心在于对底层原理的深入理解与工程化落地。开发者在研究过程中可以结合官方文档与社区讨论,梳理项目的初始化流程、核心模块职责与数据流转,逐步掌握其中的技术细节与设计思路。
1. 下载源码压缩包,解压到本地环境。
2. 根据项目类型准备对应的运行环境与依赖。
3. 按照 README 中的步骤完成配置与部署。
4. 在隔离的测试环境中运行验证,避免影响生产系统。
本资源来源于开源社区,仅供安全研究、技术学习与合法授权范围内的攻防演练使用,请勿用于任何非法或侵害他人权益的用途。使用本项目产生的一切后果由使用者自行承担。
| 资源标题 | fleet-cve-scanner - An open-source, single-script CVE scanner for RMM- |
| 所属分类 | 安全软件 |
| 发布作者 | admin |
| 发布时间 | 2026-10-05 23:00:44 |
| 下载权限 | 免费下载 |
| 附件数量 | 2 个下载链接 |
| 浏览次数 | 467 |
| 讨论数量 | 0 |
| 主题状态 | 正常讨论中 |