מודיעין חולשות
קריאת CVE: מה רשומת CVE אומרת ומה היא לא אומרת
רשומת CVE נותנת שם לפגם ומפנה לספק, וההודעה של הספק היא שקובעת את הגרסה המתוקנת.
דירוג CVEs עם קטלוג KEV של CISA וציוני EPSS של FIRST לצד CVSS, ובניית טבלת עדיפויות משני הפידים החינמיים.
הסורק מחזיר 400 ממצאים ויש לך שבוע. CVSS יכול למיין אותם לפי חומרה, אבל 9.8 שאף אחד לא מנצל יכול לחכות, ו-7.5 שתוקפים כבר מנצלים לא אמור לחכות. שני מקורות חינמיים מראים אילו חולשות מנוצלות בפועל. קטלוג Known Exploited Vulnerabilities (KEV) של CISA מונה חולשות עם ניצול מאומת. Exploit Prediction Scoring System (EPSS) של FIRST מעריך מה הסיכוי שכל חולשה תנוצל ב-30 הימים הקרובים.
המאמר מסביר את שניהם, מראה איך הם משתלבים עם CVSS, ואז עובר על מעבדה שבה שולפים משני הפידים את אותם CVEs ובונים טבלת עדיפויות קטנה. מה שכדאי לקחת ממנו: חומרה, ראיות לניצול והחשיפה שלך קובעים יחד את סדר התיקונים. כל אחד מהם לבדו נותן סדר שגוי.
למי ש-CVSS חדש לו, כדאי לקרוא קודם מה זה CVSS. ההבדל בין חולשה, איום ואקספלויט מוסבר ב-מה זו חולשה.
Common Vulnerability Scoring System מדרג חולשה לפי הווקטור שלה: איך תוקף מגיע אליה, כמה מאמץ זה דורש, אם התוקף צריך הרשאות או פעולה של משתמש, ובמה החולשה יכולה לפגוע. ציון הבסיס הוא מספר מ-0 עד 10 שנבנה מהמאפיינים האלה.
ציון הבסיס עונה על שאלה אחת: כמה זה יכול להיות גרוע אם מישהו ינצל את זה? הוא לא עונה על השאלה אם מישהו מנצל את זה. ל-CVSS יש מדדים זמניים שיכולים לכלול בשלות אקספלויט, אבל רוב לוחות הבקרה מציגים קודם את ציון הבסיס, והמספר הזה לא משתנה אחרי פרסום ה-CVE.
שני CVEs מהמעבדה למטה מראים את הפער. ל-CVE-2021-44228 (Log4Shell) יש ציון בסיס 10.0 ב-NVD. ל-CVE-2023-44487 (HTTP/2 Rapid Reset) יש 7.5. מיון לפי ציון בלבד שם את Log4Shell ראשון, וזה נכון. הבעיה מתגלה ברשימה של ארבעים חולשות עם ציון 9.8 בלי סימן שמישהו ניצל אחת מהן. ציון נותן נקודת התחלה, וסדר הוא לא נותן.
קטלוג KEV הוא הרשימה של CISA של חולשות שנוצלו בפועל (in the wild). לדברי CISA, היא מתחזקת את המקור הסמכותי לרשימה הזו, והיא ממליצה לארגונים להשתמש בקטלוג כקלט למסגרת התעדוף שלהם. הכניסה לקטלוג תלויה בראיות אמינות לכך שהחולשה מנוצלת באופן פעיל. רשומות נכנסות כשהראיות מגיעות.
קובץ הקטלוג שהורדתי למאמר הזה (גרסת קטלוג 2026.11.06, פורסם ב-2026-11-06) מכיל 1,769 רשומות. בכל רשומה יש את השדות האלה:
cveID, vendorProject, product וגם vulnerabilityNamedateAdded, היום שבו CISA הוסיפה את ה-CVEdueDate, המועד האחרון ש-CISA קבעהrequiredAction, בדרך כלל תיקון של היצרן או הפחתת סיכוןknownRansomwareCampaignUse, שערכו Known או Unknownnotes וגם cwesמתוך 1,769 הרשומות, 361 מסומנות Known לשימוש בכופרה. 285 נוספו ב-2026 עד תאריך הפרסום.
יש שתי מגבלות חשובות. ראשית, הקטלוג אינו שלם. ניצול מתחיל הרבה פעמים לפני ש-CISA מאמתת אותו, ויש חולשות מנוצלות שאף פעם לא מקבלות רשומה. CVE שלא מופיע ב-KEV הוא CVE לא מאומת, וזה לא אותו דבר כמו בטוח. שנית, KEV לא אומר אם העותק שלך של מוצר מושפע. את התשובה הזו נותן המצאי שלך.
רוב האנשים מכירים את המועדים של KEV מ-BOD 22-01, הנחיה תפעולית מחייבת ש-CISA פרסמה ב-3 בנובמבר 2021. היא הורתה לסוכנויות הפדרליות בארה״ב לטפל ברשומות KEV בתוך שישה חודשים עבור מזהי CVE שהוקצו לפני 2021, ובתוך שבועיים עבור כל שאר החולשות. השדה dueDate עדיין משקף את המודל הזה ברשומות ישנות.
BOD 22-01 כבר לא בתוקף. בדף שלה ב-cisa.gov כתוב עכשיו שהיא בוטלה והוחלפה ב-BOD 26-04, ש-CISA מציגה תחת 10 ביוני 2026. BOD 26-04 קובעת לוחות זמנים לטיפול לפי ארבעה קלטים:
Table 1 ב-BOD 26-04 מכילה את לוחות הזמנים עצמם. ההנחיה סופרת ימים קלנדריים, והיא מגדירה רשומות "& forensic triage", שצריך לטפל בהן בתוך שלושה ימים ואז לבדוק אותן לסימני פריצה. את הערכים המדויקים צריך לקרוא בטבלה בדף ההנחיה, בלי להעתיק מספרים מהמאמר הזה או מפוסטים ישנים.
הקטלוג מראה את שתי התקופות. בקובץ שהורדתי, הפער בין dateAdded לבין dueDate הוא 21 ימים ב-1,025 רשומות, 14 ימים ב-286 רשומות, וכשישה חודשים (181 או 182 ימים) ב-249 רשומות. כמעט לכל הרשומות של שישה חודשים יש מזהי CVE מ-2020 או לפני כן, וזה תואם את הכלל של BOD 22-01. הפערים של 21 ו-14 ימים הם תאריכים ש-CISA קבעה לכל רשומה בנפרד, ולכן הם לא משקפים כלל קבוע אחד. 152 רשומות מזכירות את BOD 26-04 בשדה requiredAction או בשדה notes.
FIRST, ה-Forum of Incident Response and Security Teams, מתחזק את EPSS. לפי FIRST, זה מודל machine learning שמעריך את ההסתברות ש-CVE שפורסם ינוצל בפועל ב-30 הימים הקרובים. FIRST מפרסם את הציון כל יום לכל CVE. הנתונים חינמיים ולא דורשים רישום.
כל CVE מקבל שני מספרים:
רוב הציונים קרובים לאפס, כי רוב החולשות אף פעם לא מנוצלות. לכן הרבה פעמים קל יותר לקרוא את האחוזון מאשר את הציון הגולמי. ציון 0.909 נראה גבוה בפני עצמו, ואחוזון 0.998 מראה איך הוא עומד מול שאר הרשימה באותו יום.
לפי FIRST, המודל נשען על כ-2,850 מאפיינים מחמש קטגוריות (קוד אקספלויט, שיח, מדדי CVSS, גיל והיקף הפניות, בין היתר), והוא לומד מפעילות ניצול שנצפתה ושותפים מספקים. הציונים זזים כשמגיעים אותות חדשים. ה-API יכול להחזיר היסטוריה של 30 ימים ל-CVE אחד, וזה עוזר כשצריך להסביר למה ציון עלה.
ל-EPSS יש מגבלה ברורה. הוא מנבא פעילות ניצול. הוא לא אומר כמה חולשה גרועה, ולא אומר אם המערכות שלך מריצות את הקוד המושפע. ציון גבוה הוא סיבה להסתכל על הנכס, וצריך לבדוק את הנכס לפני שמניחים שהוא בסיכון.
כל מקור עונה על שאלה אחרת:
| מקור | השאלה שהוא עונה עליה | צורת התשובה |
|---|---|---|
| ציון הבסיס של CVSS | כמה זה יהיה גרוע אם מישהו ינצל את זה? | חומרה קבועה, 0 עד 10 |
| KEV | האם CISA אימתה ניצול? | כן או לא, עם תאריכים |
| EPSS | מה הסיכוי לניצול ב-30 הימים הקרובים? | הסתברות ואחוזון, מתעדכנים מדי יום |
| המצאי שלך | האם החולשה נמצאת במערכות שלי, ואפשר להגיע אליה? | כן או לא, מהנתונים שלך |
סדר התיקונים נגזר מהשילוב של הארבעה. זו נקודת התחלה, לא חוק. קודם מה שמאומת ונגיש. אחריו מה שמאומת אבל לא נגיש, ומה שלא מאומת עם EPSS גבוה ונגיש. השאר לפי CVSS ולפי ערך הנכס. BOD 26-04 משלבת את אותם סוגי קלט, כך שהכללים הפדרליים הולכים באותו היגיון.
צריך:
www.cisa.gov, api.first.org וגם services.nvd.nist.gov.השלבים האלה רק קוראים קטלוגים ציבוריים. אף אחד מהם לא סורק מארח. אם בהמשך בודקים את עמודת החשיפה מול שירותים חיים, עושים את זה רק על מערכות בבעלותך או כאלה שיש לך הרשאה בכתב לבדוק.
curl -s https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json -o kev.json
ls -l kev.jsonההורדה שקטה. בהרצת הייחוס הקובץ היה בגודל 1,832,349 בתים. לפני שסומכים על הספירות, צריך לפתוח את תחילת הקובץ ולבדוק את catalogVersion ואת dateReleased.
jq '.vulnerabilities | length' kev.jsonבמכונת הייחוס זה החזיר command not found, כי jq היה חסר. המקבילה ב-Python החזירה:
python -c "import json; d=json.load(open('kev.json')); print(len(d['vulnerabilities']))"1769השדה count ברמה העליונה אמור להציג את אותו מספר.
jq '.vulnerabilities[] | select(.cveID=="CVE-2021-44228") | {cveID, dateAdded, dueDate, requiredAction}' kev.jsonהמקבילה ב-Python הדפיסה את זה, עם requiredAction מקוצר כאן:
{
"cveID": "CVE-2021-44228",
"dateAdded": "2021-12-10",
"dueDate": "2021-12-24",
"requiredAction": "For all affected software assets for which updates exist, the only acceptable remediation actions are: 1) Apply updates; OR 2) remove affected assets from agency networks. ..."
}אותה שאילתה עבור CVE-2023-4863 מחזירה dateAdded 2023-09-13 וגם dueDate 2023-10-04. התאריכים הם הסיבה לשמור את קובץ הקטלוג: הם מתעדים מתי CISA פעלה ולא רק אם פעלה.
curl -s 'https://api.first.org/data/v1/epss?cve=CVE-2021-44228,CVE-2023-4863' | jq '.data'התשובה הגולמית מהרצת הייחוס:
{"status":"OK","status-code":200,"version":"1.0","access":"public","total":2,"offset":0,"limit":100,"data":[{"cve":"CVE-2023-4863","epss":"0.999790000","percentile":"0.999800000","date":"2026-11-07"},{"cve":"CVE-2021-44228","epss":"0.999990000","percentile":"1.000000000","date":"2026-11-07"}]}בקוד חשובים שני פרטים. השורות חוזרות בסדר שונה מהבקשה, ולכן צריך להתאים לפי cve ולעולם לא להסתמך על המיקום. הערכים הם מחרוזות, ולכן צריך להמיר אותם למספרים לפני מיון או השוואה.
לשמור את זה בקובץ priority.py. הוא צריך רק את הספרייה הסטנדרטית של Python.
import json, sys, time, urllib.request
KEV_FILE = sys.argv[1]
CVES = sys.argv[2:]
def get(url):
with urllib.request.urlopen(url, timeout=60) as r:
return json.load(r)
kev = {v["cveID"]: v for v in json.load(open(KEV_FILE))["vulnerabilities"]}
epss = {row["cve"]: row for row in get(
"https://api.first.org/data/v1/epss?cve=" + ",".join(CVES))["data"]}
print("| CVE | CVSS 3.1 base | In KEV | EPSS | Percentile |")
print("|---|---|---|---|---|")
for cve in CVES:
nvd = get(f"https://services.nvd.nist.gov/rest/json/cves/2.0?cveId={cve}")
metrics = nvd["vulnerabilities"][0]["cve"].get("metrics", {})
cvss = metrics.get("cvssMetricV31", [{}])[0].get("cvssData", {}).get("baseScore", "n/a")
e = epss.get(cve, {})
print(f"| {cve} | {cvss} | {'yes' if cve in kev else 'no'} | "
f"{float(e.get('epss', 0)):.5f} | {float(e.get('percentile', 0)):.5f} |")
time.sleep(7) # the NVD API rate-limits requests without a keyלהריץ אותו על שישה CVEs: שניים מדוגמאות הקטלוג וארבעה שנבחרו כדי ליצור ניגוד אליהם.
python priority.py kev.json CVE-2021-44228 CVE-2023-4863 CVE-2024-3400 CVE-2023-44487 CVE-2023-38545 CVE-2024-3094הפלט מהרצת הייחוס:
| CVE | CVSS 3.1 base | In KEV | EPSS | Percentile |
|---|---|---|---|---|
| CVE-2021-44228 | 10.0 | yes | 0.99999 | 1.00000 |
| CVE-2023-4863 | 8.8 | yes | 0.99979 | 0.99980 |
| CVE-2024-3400 | 10.0 | yes | 0.99999 | 1.00000 |
| CVE-2023-44487 | 7.5 | yes | 0.99999 | 0.99998 |
| CVE-2023-38545 | 9.8 | no | 0.78689 | 0.99591 |
| CVE-2024-3094 | 10.0 | no | 0.90900 | 0.99808 |הסקריפט לא ממלא את עמודת החשיפה, כי רק לך יש את המצאי שלך. כך מילאה אותה הרצת הייחוס, ומה כל בדיקה כיסתה:
find אחר log4j-core*.jar תחת פרופיל המשתמש והמאגר לא החזיר כלום. תוצאה: לא.libwebp* תחת /mingw64, /usr ופרופיל המשתמש לא החזיר כלום. תוצאה: לא.curl --version מדווחת על 8.12.1. טווח ה-libcurl המושפע לפי NVD הוא מ-7.69.0 ועד 8.4.0, לא כולל. תוצאה: לא, עבור libcurl של upstream. ההסתייגות מופיעה למטה.xz --version מדווחת על 5.6.4. לפי NVD, הגרסאות 5.6.0 ו-5.6.1 מושפעות. תוצאה: לא.בעמודת החשיפה טועים הכי הרבה. הפצות Linux ויצרנים עושים הרבה פעמים backport לתיקונים, ולכן מספר גרסה לבדו יכול להטעות. לפני שסוגרים שורה כבטוחה, צריך לבדוק את ההודעה של היצרן עבור ה-build שלך.
לסדר את השורות לפי סדר התיקונים, בעזרת הכלל מהסעיף הקודם. אם CVE-2021-44228, CVE-2023-4863 או CVE-2024-3400 היו נגישים ברשת שלך, הם היו התיקונים הראשונים של השבוע, לא משנה מה אומרת שאר הרשימה.
ל-CVE-2023-44487 יש ציון CVSS נמוך מזה של CVE-2023-38545, אבל הוא מאומת וציון ה-EPSS שלו הוא 0.99999. ברשימה שבה שניהם נגישים, הוא הולך ראשון. ה-9.8 ש-CISA לא אימתה יורד למטה.
CVE-2024-3094 הוא המקרה ששובר כלל פשוט. הוא לא מופיע בנתונים של CISA, אבל ציון ה-EPSS שלו הוא 0.909 וציון ה-CVSS שלו הוא 10.0. במכונה הזו הגרסה לא מושפעת, ולכן השורה נסגרת. במארח שמריץ xz 5.6.1 אותה שורה עולה לראש הרשימה, כי הציון אומר שפעילות ניצול סבירה מאוד והחולשה קריטית.
https://www.first.org/epss/how-it-works, שמכסה כיול ומגבלות.https://epss.empiricalsecurity.com/epss_scores-current.csv.gz ולחבר אותו לקובץ KEV לפי cveID. כך בודקים מאות CVEs במעבר אחד.הנתונים במאמר הזה נקראו ב-2026-11-08 מהמקורות שמופיעים במטא־דאטה של המאמר. ספירות KEV וציוני EPSS משתנים עם הזמן, ולכן צריך לבדוק את התאריך בהרצה שלך.
מודיעין חולשות
רשומת CVE נותנת שם לפגם ומפנה לספק, וההודעה של הספק היא שקובעת את הגרסה המתוקנת.
מודיעין חולשות
מה המשמעות של ציון CVSS כמו 9.8, איך בנויות מחרוזות וקטור של v4.0 ו-v3.1, ואיך מפענחים ומחשבים אחת מחדש ביד.