
ماسح ضوئي لـ CVE مفتوح المصدر بملف نصي واحد للأساطيل المُدارة عبر RMM. يعمل بنظام PowerShell 7 الخالص — يربط مخزون برامج RMM الخاص بك بقواعد NVD و CISA KEV و EPSS و SSVC للإجابة: هل هذا الإصدار معرض للخطر، وكم هو مستوى الإلحاح؟
ماسح ثغرات (CVE) مفتوح المصدر بملف نصي واحد للأساطيل المُدارة بواسطة RMM. يعمل بـ PowerShell 7 النقي، لا وكلاء، لا أجهزة، لا رسوم ترخيص.
يجيب على سؤال واحد لكل قطعة برمجية على كل نقطة نهاية تديرها: هل الإصدار المثبت معروف بكونه ضعيفًا، وكم هي درجة الاستعجال؟ — من خلال ربط جرد البرمجيات الخاص بـ RMM الخاص بك مع مصادر التغذية الأمنية الموثوقة والمجانية:
المخرجات: تقرير CSV لكل جهاز، سجل SQLite مع ساعات SLA وأحداث التغيير أسبوعيًا، لوحة تحكم HTML ذاتية الاحتواء، وتقرير تعرض اختياري بتنسيق Markdown.
الإصدار v1.0.0. تم نقل المحرك بطريقة نظيفة من ماسح كان يُشغل أسبوعيًا في الإنتاج ضد أسطول ويندوز (انظر docs/HISTORY.md). قبل هذا الإصدار، تم تشغيل الاثنين ضد نفس الأسطول المباشر ومقارنتهما صفًا بصف: عبر عشرات الآلاف من النتائج حيث رأى كلاهما نفس (الجهاز، البرمجيات، الإصدار)، كل حقل محسوب — الحالة، CVSS، الخطورة، علامة KEV، قرار SSVC، إصدار الإصلاح — تطابق تمامًا.
تغطي تلك المقارنة منطق الحكم. لم تختبر طبقة السجل/SLA، وليست بديلاً عن التحقق من صحة الأداة في بيئتك الخاصة. اقرأ docs/known-limitations.md قبل الثقة بها — فهي مكتوبة لتكون صادقة لا ممجدة.
تحتاج PowerShell 7 (pwsh). طريقتان للتشغيل:
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
صدر جردك إلى 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.
brew install powershell; ويندوز: winget install Microsoft.PowerShell; دبيان/أوبونتو: قم بالتثبيت من مستودع حزم Microsoft (packages.microsoft.com).brew install sqlite; دبيان/أوبونتو: apt-get install sqlite3; ويندوز: قم بتنزيل حزمة "أدوات" SQLite من sqlite.org وضع sqlite3.exe في PATH أو بجانب السكربت. بدونه لا يزال المسح يعمل؛ first_seen يتراجع إلى تاريخ التشغيل.first_seen في SLA. في حالة الغياب = يتم تخطي تلك الميزات، يكتمل المسح.epss.empiricalsecurity.com (مضيف نتيجة EPSS المجمعة — نقل FIRST استضافة بيانات EPSS هناك)، MSRC، endoflife.date، و GitHub raw (برنامج CVE cvelistV5) — بالإضافة إلى واجهة NinjaOne API في الوضع المباشر.الإعدادات هي ملف JSON (افتراضيًا config.json بجانب السكربت؛ تجاوز بـ -ConfigPath). ابدأ من config.example.json. كل مفتاح يقرؤه الماسح، قيمته الافتراضية عند حذفه، وما يفعله:
ninjaone (الوضع المباشر)nvd| المفتاح | الإفتراضي | الغرض |
|---|---|---|
nvd.api_key | "" | مفتاح NVD API، يُرسل كرأس apiKey. تركه فارغًا يعمل بدون مصادقة، مما يخفض الإعدادات الافتراضية لـ nvd_rate_limit و nvd_min_spacing_ms إلى سقف NVD المجهول (4/30s، 6500ms) بدلاً من السقف الموثق (48/30s، 700ms). مجاني، وأسرع بحوالي 10 مرات. |
nvd_min_spacing_ms و nvd_rate_limit و parallel_throttle تُقرأ بواسطة الماسح لكنها غير موجودة في config.example.json — أضفها فقط إذا احتجت للضبط. انظر docs/rate-limiting.md.
outputكل ما يلي يقع في output.report_dir.
vuln-report-YYYY-MM-DD.csv — تقرير النتائج لكل بحث. 28 عمودًا (المخطط أدناه).vuln-history.db — سجل SQLite (يتطلب sqlite3): runs (إجماليات لكل تشغيل)، findings (تاريخ النتائج المفتوحة لكل (device, software, cve) مع first_seen / last_seen / resolved_date / epss_score)، و changes (أحداث أسبوعية مصنفة).cve-dashboard.html — لوحة تحكم HTML ذاتية الاحتواء (مكتبة الرسم البياني مضمنة، لا طلبات خارجية). يُنسخ اختياريًا إلى output.dashboard_share.مجموعة الأعمدة ثابتة ومطبقة بواسطة البوابة. بالترتيب:
Run-WeeklyScan.ps1 هو غلاف للتشغيل المجدول: يشغل الماسح من دليله الخاص، يلتقط كل تيارات المخرجات إلى سجل مؤرخ تحت <script dir>/logs/ (تجاوز بـ -LogDir)، وينشر كود خروج الماسح حتى يرى المجدول الإخفاقات.
مجدول مهام ويندوز:
schtasks /Create /TN "CVE-Scan-Weekly" ^
/TR "pwsh -NoProfile -File C:\path\to\Run-WeeklyScan.ps1" ^
/SC WEEKLY /D SUN /ST 22:00 /RU SYSTEM
cron (لينكس/ماك):
0 22 * * 0 pwsh -File /path/to/Run-WeeklyScan.ps1
cve-dashboard.html ذاتية الاحتواء بالكامل — افتحها مباشرة، ضعها على أي مضيف ثابت أو مشاركة ملفات، أو انسخها تلقائيًا كل تشغيل عبر output.dashboard_share. للاستضافة المقيدة بالوصول، يوفر دليل dashboard-auth/ مضيف ASP.NET صغير مع مصادقة Microsoft Entra (Azure AD)؛ انظر README و RUNBOOK.
-InputCsv يسمح لأي تصدير RMM/SCCM/Intune بتغذيته، لكن فقط محول NinjaOne تم تشغيله في الإنتاج.القائمة الكاملة غير المترددة — معدل تخطي CPE، إخفاء مفتاح التكرار، totalResults في الصفحة الأولى، فجوات تجاوز MSRC، والمزيد — موجودة في docs/known-limitations.md.
بعض الخيارات الهيكلية التي تبدو غير تقليدية هي مقصودة:
ForEach-Object -Parallel، وهذه المساحات لا يمكنها رؤية دوال النطاق الخارجي — ولهذا يتم تكرار عدد قليل من المساعدين عمدًا داخل الكتلة المتوازية. تخطيط وحدة بدالة لكل ملف لن يزيل ذلك التكرار (الجسم المتوازي سيظل بحاجة إلى المصدر المحقون لكل مساحة تشغيل)؛ سيضيف فقط خطوة بناء ويكسر نموذج نشر نسخ ملف واحد. إذا تجاوز المشروع يومًا ما الملف الواحد، فالتغليف هو التغيير الذي يناسب v2، وليس تصحيحًا.[PSCustomObject]، وليس فئات. يتم إنتاج سجلات النتائج داخل مساحات تشغيل متوازية وإعادتها إلى مساحة التشغيل الرئيسية. مثيلات فئة PowerShell لا تبقى موثوقة عبر تلك الحدود؛ [PSCustomObject] يبقى، وعقد عمود CSV يُفرض بواسطة بوابة الإصدار بدلاً من نظام الأنواع.tests/ هي نصوص بدون تبعيات مع افتراضات كود الخروج، قابلة للتشغيل في أي مكان يوجد فيه pwsh — بما في ذلك خادم المسح — دون تثبيت أي شيء. CI يشغلها جميعًا على ويندوز وأوبونتو.الطلبات مرحب بها — محولات RMM قبل كل شيء. انظر CONTRIBUTING.md للقواعد الأساسية ومتطلبات الاتجاه الآمن (منطق الحالة يجب أن يخطئ فقط نحو المزيد من الرؤية، أبدًا بصمت نحو PATCHED).
هذه الأداة مفيدة فقط بقدر التغذية المجانية والموثوقة التي تربطها. كل من التالي يتم الاستعلام عنه وقت المسح؛ يُرجى احترام شروطهم إذا بنيت على هذا.
cvelistV5 — سجلات CVE بالإضافة إلى بيانات SSVC / vulnrichment المقدمة من CISA ADP. CVE® علامة تجارية مسجلة لمؤسسة MITRE. https://github.com/CVEProject/cvelistV5Apache-2.0 — انظر LICENSE.
| المفتاح | الإفتراضي | الغرض |
|---|
ninjaone.client_id | "" | معرف العميل OAuth2 لواجهة NinjaOne API. مطلوب للمسح المباشر؛ اتركه فارغًا لـ -InputCsv. |
ninjaone.client_secret | "" | سر العميل OAuth2 لواجهة NinjaOne API. |
ninjaone.base_url | — (المثال يرسل https://app.ninjarmm.com) | عنوان URL الأساسي لواجهة NinjaOne API؛ مطلوب للمسح المباشر، لا يوجد افتراضي مدمج. استخدم مضيف منطقتك (مثل eu.ninjarmm.com، oc.ninjarmm.com). |
| المفتاح | الإفتراضي | الغرض |
|---|
cvss_threshold | 7.0 | الحد الأدنى لدرجة CVSS الأساسية ليتم الإبلاغ عن ثغرة ذات نتيجة VULNERABLE. الثغرات المدرجة في KEV تتجاوز هذا الحد. |
ssvc_mission_prevalence | high | مدخل أصحاب المصلحة في SSVC Mission Prevalence (low / medium / high). |
ssvc_public_wellbeing | high | مدخل أصحاب المصلحة في SSVC Public Well-being (low / medium / high). |
| المفتاح | الإفتراضي | الغرض |
|---|
nvd_cache_ttl_days | 7 | الأيام التي تبقى فيها نتيجة NVD (لكل اسم برمجية) مخبأة قبل إعادة الاستعلام. |
nvd_cache_flush_every | 500 | نقطة تفتيش ذاكرة التخزين المؤقت لـ NVD على القرص كل N من العناصر المكتملة، بحيث يحتفظ المسح المتوقف بعمليات الجلب الخاصة به. 0 يعطل (الحفظ في نهاية المسح لا يزال يعمل). |
nvd_min_spacing_ms | 700 مع مفتاح API، 6500 بدونه | الحد الأدنى للميلي ثوان بين استدعاءات NVD. القيود الملزمة للمعدل — اضبط هذا أولاً. |
nvd_rate_limit | 48 مع مفتاح API، 4 بدونه | الحد الأعلى للإطار المنزلق لاستدعاءات NVD لكل 30 ثانية (شبكة أمان). الحد الأدنى 1. |
parallel_throttle | 20 | عدد مساحات التشغيل ForEach-Object -Parallel. استدعاءات NVD مسلسلة بغض النظر؛ هذا فقط يحد من التوازي في ضربات الذاكرة المؤقتة. الحد الأدنى 1. |
kev_cache_ttl_hours | 24 | مدة بقاء كتالوج CISA KEV المخبأ. |
epss_cache_ttl_hours | 24 | مدة بقاء ملف نتيجة FIRST.org EPSS المخبأ. |
eol_cache_ttl_days | 7 | مدة بقاء استعلامات endoflife.date المخبأة. |
msrc_cache_ttl_days | 30 | مدة بقاء بيانات MSRC CVRF المخبأة. |
cvelist_cache_ttl_days | 7 | مدة بقاء بيانات SSVC / برنامج CVE (cvelistV5) / CISA-ADP المخبأة. |
cvelist_fetch_budget | 300 | الحد الأقصى لعدد جلب سجلات CVE لكل تشغيل لإثراء SSVC/vulnrichment؛ الباقي يؤجل للتشغيل التالي. |
| المفتاح | الإفتراضي | الغرض |
|---|
epss_spike_threshold | 0.10 | الحد الأدنى للارتفاع في نتيجة EPSS للبحث بين المسوحات لإصدار حدث تغيير EPSS_SPIKE. |
sla_days_critical | 14 | نافذة SLA (أيام من first_seen) للنتائج CRITICAL. |
sla_days_high | 30 | نافذة SLA لبقية الخطورة المسجلة. |
denied_software_csv | "" | مسار إلى ملف CSV اختياري للبرمجيات الممنوعة للتحقق المتقاطع. فارغ يعطل الفحص. |
| المفتاح | الإفتراضي | الغرض |
|---|
output.report_dir | (مطلوب) | دليل لجميع المخرجات — CSV، قاعدة بيانات السجل، لوحة التحكم، والتخزين المؤقت. |
output.wiki_security_page | "" | مسار اختياري لصفحة تعرض Markdown. تُكتب فقط عند تعيينها. |
output.dashboard_share | "" | مسار/مشاركة اختيارية تستقبل نسخة من لوحة التحكم كل تشغيل. فارغ = محلي فقط. |
eol-report-YYYY-MM-DD.csv — يُكتب عند اكتشاف عائلات وصلت لنهاية العمر.denied-report-YYYY-MM-DD.csv — يُكتب عندما يكون denied_software_csv مُعدًا ويطابق.nvd-cache.json، kev-cache.json، epss-cache.json، eol-cache.json، msrc-cache.json، cvelist-cache.json (كلها في .gitignore).output.wiki_security_page، فقط عند تعيينها.| # | العمود | المعنى |
|---|
| 1 | device_id | معرف الجهاز في RMM (أو معرف اصطناعي حتمي في وضع -InputCsv). |
| 2 | hostname | اسم مضيف الجهاز. |
| 3 | os | سلسلة نظام التشغيل (قد تكون فارغة). |
| 4 | software | اسم المنتج كما هو في الجرد. |
| 5 | installed_version | سلسلة الإصدار كما هو في الجرد. |
| 6 | cve_id | معرّف CVE. |
| 7 | cvss_score | درجة CVSS الأساسية (0 إذا لا يوجد). |
| 8 | severity | تسمية خطورة CVSS. |
| 9 | cvss_version | أي معيار CVSS أنتج النتيجة (4.0/3.1/3.0/2.0/فارغ). |
| 10 | epss_score | احتمال EPSS من FIRST.org (فارغ إذا كانت CVE غائبة عن الكتالوج). |
| 11 | epss_percentile | النسبة المئوية لـ EPSS (فارغ إذا غائب). |
| 12 | ssvc_exploitation | خيار استغلال SSVC الخام من CISA (none/poc/active؛ فارغ بدون بيانات ADP). |
| 13 | ssvc_decision | قرار SSVC Act/Attend/Track (فارغ بدون بيانات ADP). |
| 14 | status | VULNERABLE / PATCHED / UNKNOWN. |
| 15 | published_date | تاريخ نشر CVE. |
| 16 | unknown_reason | لماذا الصف UNKNOWN (SUSPECT_VERSION / NO_VERSION_BOUND / VERSION_PARSE_ERROR؛ فارغ غير ذلك). |
| 17 | is_kev | True عندما تكون CVE في كتالوج CISA KEV. |
| 18 | kev_due_date | تاريخ استحقاق تصحيح CISA KEV. |
| 19 | kev_ransomware_use | علامة استخدام حملات الفدية في KEV. |
| 20 | fix_version | إصدار حد الإصلاح المحسوب. |
| 21 | fix_boundary_inclusive | ما إذا كان حد الإصلاح شاملاً. |
| 22 | advisory_url | عنوان URL للاستشارة البائعة أو تفاصيل NVD. |
| 23 | patch_evidence | دليل عندما تم تحويل UNKNOWN من Microsoft إلى PATCHED. |
| 24 | triage_status | حالة التصنيف من triage.json (فارغ إذا لا يوجد). |
| 25 | triage_note | ملاحظة التصنيف. |
| 26 | first_seen | تاريخ أول مشاهدة للنتيجة (من قاعدة بيانات السجل). |
| 27 | sla_due | تاريخ استحقاق SLA. |
| 28 | sla_breach | ما إذا كان SLA منتهكًا. |