השבתת CrowdStrike נבעה מאי-התאמה של 21 שדות מול 20. Kestrel בודקת עדכונים בקוד לפני אתחול נקודות קצה.
CrowdStrikeאבטחת נקודות קצהחוסן IT

קריסת CrowdStrike התמצתה בספירת שדות: 21 שדות במקום 20 שהליבה ציפתה להם. אף שכבה עצמאית לא בדקה.

Ashutosh SinghalAshutosh Singhal20 ביולי 202611 min

ב-19 ביולי 2024, עדכון יחיד מספק תוכנה הפיל מיליוני מחשבי Windows בפחות מ-90 דקות, והסיבה לכך הייתה מספר בודד. קובץ ערוץ "Rapid Response Content" של CrowdStrike הצהיר על 21 שדות במקום שבו מפרש הליבה (kernel interpreter) שנפרס ציפה ל-20 שדות בלבד. השדה הנוסף יצר קריאה מחוץ לגבולות (out-of-bounds read), מסך כחול מיידי, ומכיוון שהקריסה התרחשה בשלב כה מוקדם של תהליך האתחול, הסוכן שקרס לא יכול היה לעלות שוב כדי לקבל פקודת שחזור (rollback). ההתאוששות חייבה לגשת פיזית לכל מכונה ולתקן אותה ידנית במצב בטוח (Safe Mode).

קראתי את ניתוח סיבת השורש שפרסמה CrowdStrike עצמה באותו חודש אוגוסט יותר מפעם אחת לפני שהתחדד בי הדבר שהטריד אותי באמת. זו לא הייתה פריצה. זה לא היה מודל בינה מלאכותית לקוי. זו הייתה עובדה אריתמטית ניתנת להכרעה, 21 מול 20, שישבה במטען נתונים (payload) שאף שכבה עצמאית מעולם לא בדקה לפני שהגיע לסביבת הייצור. המאמת של הספק אישר אותו. הארגונים שהושבתו לא החזיקו באותו מאמת. הם נשאו בתוצאות לבדם.

הקדשתי את התקופה האחרונה לבניית הדגמה סביב הפער הזה: קונסולה שכיניתי בשם Kestrel, הניצבת בין ספק התוכנה לבין צי הייצור ומכריעה, בקוד, מה הספק מורשה להפיץ. תוכלו לראות כיצד היא פועלת בכתובת veriprajna.com/demos/software-update-integrity. מה שהפתיע אותי במהלך הבנייה היה המקום שבו התברר שהפתרון נמצא. ניגשתי לפרויקט מתוך ביטחון שאזדקק למודל חכם יותר, אך כמה שורות פייתון פשוטות לכדו את הקריסה ראשונות.

שחזרתי את הקריסה ואז נתתי לקוד להכריע

שחזרתי את חתימת הכשל של 19 ביולי כמקרה מבחן (fixture) וכיוונתי את המערכת שלי אליה, כמעט מתוך ציפייה להתאכזב מהשחזור של עצמי. החבילה היא C-00000291, קובץ ערוץ Rapid Response Content מספק בדיוני שכיניתי SentinelEdge, שנדחף לצי סינתטי של 8,500 נקודות קצה בשם Acme Financial. אף אחת מאלו אינה חברה אמיתית. אך חתימת הכשל אמיתית לחלוטין: סכמה מוצהרת של 20 שדות שתפחה ל-21, ונדחפה ל-100% מכלל הצי בגל יחיד, ללא תוכנית פריסה מדורגת (canary).

השער מופעל על ארבע בדיקות בו-זמנית, וכל אחת מהן היא אריתמטיקה טהורה או בדיקה פשוטה בטבלה, לעולם לא שיקול דעת סובייקטיבי. השוואת הסכמה מזהה 21 שדות במקום שבו המפרש מצפה ל-20 ומסמנת את הקריאה מחוץ לגבולות. סביבת ארגז חול (sandbox) מדומה, שהיא מודל תוצאות דטרמיניסטי לכל פרופיל ולא חוות מכונות וירטואליות אמיתיות של Windows, מכניסה 5 מתוך 6 פרופילי הצי ללולאת אתחול לאורך מחזורי אתחול מחדש. היא מסיקה זאת מאות תאימות מנהלי התקנים שאינו תלוי בבדיקת הסכמה, כך ששני הממצאים מאששים זה את זה ולא רק מהדהדים כפילות. גלאי הסוכן המת מסמן את לולאת השחזור כ-true, מכיוון שהסוכן הקורס הוא בעצמו הישות שאמורה לקבל את פקודת השחזור, והוא מושבת עוד לפני סיום תהליך האתחול. רדיוס הפגיעה עומד על 100% מול מדיניות קנרית של 5%. פסק דין: BLOCK. על המסך נכתב: נחסם לפני שנקודת קצה כלשהי בייצור אותחלה מחדש.

קונסולת Kestrel המציגה את לוח Block Rollout עבור C-00000291 מהספק SentinelEdge, עם ארבע ההוכחות הדטרמיניסטיות, צי של 8,500 נקודות קצה וזמן השבתה מוערך שנמנע בשווי 5,000,000 $.
C-00000291, שחזור חתימת הכשל מ-19 ביולי. השער מפעיל את כל ארבע הבדיקות: אי-התאמה במספר שדות הסכמה (20 צפויים, 21 סופקו), לולאת אתחול בארגז חול ב-5/6 פרופילים, לולאת שחזור סוכן מת, ורדיוס פגיעה של 100% מול מדיניות קנרית של 5%. פסק דין BLOCK, זמן השבתה מוערך שנמנע: 5,000,000 $.

זמן ההשבתה המוערך שנמנע באותו עדכון בודד מצביע על 5,000,000 $, ואני מבקש לדייק לגבי מהותו של נתון זה. זהו המודל הפנימי של ההדגמה: החלק המושפע מוכפל בנתון עלות של 5 מיליון דולר לשעה מוכפל ברף התאוששות מינימלי של שעה אחת, כאשר הנוסחה מוצגת בבירור על גבי המסך. אין מדובר בכסף שלקוח חסך בפועל. ההתאוששות האמיתית ב-19 ביולי נמשכה ימים ולא שעה בודדת, ולכן רף המינימום נקבע במכוון באופן שמרני.

המקרה הירוק הפחיד אותי יותר מהמקרה האדום

הייתי מתוח יותר לגבי המקרה הירוק מאשר לגבי האדום, מכיוון ששכבת ממשל החוסמת את העדכון המסוכן אך בו-זמנית חונקת את העדכון הבטוח אינה אלא השבתה שקבעתם לעצמכם ביומן. אותו ספק בדיוני דוחף את RRC-7741, עדכון שפיר של חתימות זיהוי, עם סכמה מוצהרת של 20 מול 20, ותוכנית קנרית מדורגת של 1.2%. צוות הסוכנים פועל, הסכמה תואמת, 5 מתוך 6 פרופילים עוברים בהצלחה את מחזורי האתחול מחדש, לולאת הסוכן המת היא false, ורדיוס הפגיעה נשאר בתוך גבולות המדיניות. פסק דין: APPROVE ROLLOUT, שוחרר לטבעת קנרית של 102 נקודות קצה. ירוק, מהיר, ונטול דרמות.

קונסולת Kestrel המציגה את לוח Approve Rollout הירוק עבור RRC-7741 ששוחרר לטבעת קנרית של 1.2%, בליווי עקבות הערכה 7/7 ורשומת ראיות.
העדכון השפיר מאותו הספק, RRC-7741. הסכמה תואמת, 5/6 פרופילים עוברים מחזורי אתחול, לולאת סוכן מת false, רדיוס פגיעה של 1.2% בתוך המדיניות. פסק דין APPROVE ROLLOUT, שוחרר לקנרית של 102 נקודות קצה, רשומת ראיות sha256:798431b4c96612a9.

לאורך ששת העדכונים השפירים בערכה, השער לא ייצר אף חסימת שווא (zero false blocks). אני אומר זאת תוך ציון המכנה במפורש, כי שש זה שש, ולא אתיר לעגל זאת כלפי מעלה לכדי הבטחה גורפת לצי שלכם. הערך של מקרה ה-ALLOW צר יותר וחשוב בהרבה מסתם אחוזים. שער זוכה לאמינות רק אם הוא בלתי נראה בתעבורה רגילה ובלתי מתפשר באירוע היחיד שעלול למוטט את התשתית שלכם.

מדוע שללתי את סמכות ההכרעה מהמודל

התחלתי את הבנייה מתוך הנחה שהחלק המורכב טמון בהסקה, ושמודל חד יותר או מבקר מתוחכם יותר יהיה זה שילכוד את העדכון הפגום. טעיתי באופן שלקח לי זמן להודות בו. ישנו צוות LLM בתוך Kestrel: מאחד (normalizer), מפרש ארגז חול, ושני מבקרים יריבים — האחד טוען שהעדכון בטוח להפצה והשני טוען שהוא יקרוס. הצמד היריב מרוויח את מקומו בצדק, כיוון שהוא מעביר את פסק הדין בדיקת חדירות ובחינה מחמירה משני הכיוונים בטרם הוחלט דבר. אך אף לא אחד מסוכנים אלה קובע את פסק הדין הסופי.

פסק הדין נקבע על ידי שני קובצי פייתון פשוטים, verifier.py ו-gate.py, שפועלים לחלוטין מחוץ למסגרת הסוכנים. הצוות פועל על גבי Pydantic AI עם מודל ברירת מחדל של claude-opus-4-8, והמערכת כולה פועלת גם במצב לא מקוון ללא מפתח API באמצעות מנגנון ייעוץ חלופי דטרמיניסטי. בכל אחד ממצבים אלה השער זהה לחלוטין ומחזיר את אותה ההחלטה, כיוון שההחלטה היא אריתמטיקה טהורה, ולא היסק הסתברותי. סוכנים מייעצים, הקוד מכריע. סוכן מייעץ הנוטה ל"אשר" אינו יכול למחוק ממצא דטרמיניסטי קריטי, ואין מדובר בעניין של טעם אישי.

שכבה שנבנתה כדי לבקר את הספק אינה יכולה לקבל את הבטחות הספק בנוגע לבטיחות. היא אינה יכולה לקבל גם את הבטחות המודל שלה עצמה.

משפט זה הוא הסיבה המדויקת לכך שהארכיטקטורה בנויה כפי שהיא בנויה. אמון במוצר שתפקידו הבלעדי הוא לנהל את מה שספק מפיץ לעולם אינו יכול לעבור דרך רכיב שניתן לשכנעו לומר כן.

מה שהייתי מגיש למבקר

השארתי את חוק החוסן הקיברנטי האירופי (CRA) פתוח על צג שני בזמן שבניתי את רשומת הראיות, כי אותה רשומה היא התוצר הפיזי שאצטרך להגן עליו בפועל. כל החלטה מייצאת קובץ HTML בלתי ניתן לשינוי וקובץ JSON חתום הנושא גיבוב תוכן מסוג SHA-256, את פסק הדין, ההוכחות הדטרמיניסטיות, תוצאות ארגז החול לכל פרופיל, פסקי הדין של הסוכנים המייעצים עם מזהה המודל שלהם, כללי המדיניות שהופעלו, ועקבות הערכה שלב-אחר-שלב שבהם כל שלב נושא את זמן ההשהיה שלו.

תצוגת ההחלטה של Kestrel עבור C-00000291 שנחסם, המציגה את רשומת הראיות עם sha256:0f4f71b2bd7d1753 וכפתורים לפתיחת רשומת ה-HTML וה-JSON החתום.
רשומת הראיות המיוצאת עבור העדכון שנחסם. גיבוב תוכן SHA-256, רשומת HTML פתוחה וקובץ JSON חתום, המופקים ישירות עם מתן ההחלטה עצמה.

עקבות המעקב הם החלק שהערכתי בחסר עד שלחצתי על שלב בודד. אירוע אחד מציג: "נרמול מנשר ספק חתום, הושלם תוך 184 מילי-שניות", והוא נשמר יחד עם פלט ההחלטה לצורכי סקירת ביקורת. כל שלב ניתן לשחזור ולחישוב מחדש. רגולטור אינו נדרש להאמין ללוח הבקרה שלי בעיניים עצומות. הוא יכול להריץ מחדש את האריתמטיקה ולקבל את אותה התוצאה בדיוק.

חלון מודאלי של שלב בעקבות ההערכה של Kestrel המציג 'נרמול מנשר ספק חתום, הושלם תוך 184 מילי-שניות', עם הערה המציינת כי האירוע נשמר לסקירת ביקורת.
שלב פתוח מתוך עקבות ההערכה: נרמול מנשר ספק חתום, הושלם תוך 184 מילי-שניות, נשמר לצד פלט ההחלטה לצורכי סקירת ביקורת.

אני מקפיד מאוד על מה שהחתימה מהווה ומה שאינה מהווה. מדובר בגיבוב SHA-256 מקומי, לא ב-PKI ארגוני כולל. ערוץ עדכוני הספק וכרטיסי ה-ITSM מאחוריו הם רכיבי בדיקה מדומים (stubs), ולא מחברים חיים. הרשומה תוכננה להתיישר עם דרישות דיווח: דיווח התקריות בטווח הזמן הקצר של ה-CRA, חובת הדיווח של ה-SEC תוך ארבעה ימי עסקים על אירוע סייבר מהותי, ושאלות אחריות הספק שהועלו בתביעת Delta נגד CrowdStrike במחוז פולטון בשנת 2025. "תוכננה להתיישר עם". היא אינה מעניקה הסמכה לאיש, אינה מהווה ייעוץ משפטי, וכל מי שמוכר לכם יומן ביקורת בטענה שהוא הופך אתכם לתואמי רגולציה בסך הכל מנסה למכור לכם משהו.

ישנה החלטה נוספת שאני גאה בה, והיא דווקא סירוב. מקרה מבחן XX-0000 הוא מקטע נתונים מוצפן של תוכן קנייני שהשער אינו מסוגל לנתח, ולכן אינו מנחש. הוא מחזיר ABSTAIN (הימנעות) ומפנה זאת לבודק אנושי, כיוון ששער שנותן אור ירוק למה שאינו מסוגל לקרוא גרוע בהרבה מהיעדר שער לחלוטין. שרתי מורשת ישנים שארגז החול אינו מסוגל למדל מסומנים ומוחרגים, לעולם לא מוגדרים כבטוחים כברירת מחדל. אוצר המילים כולל ארבע מילים בלבד: ALLOW, HOLD, BLOCK, ABSTAIN, והאחרונה היא זו שעליה אגן בנחרצות הרבה ביותר.

מה ש-12 מתוך 12 רשאי לסמל

כאן עליי להאט, מכיוון שבדיוק בנקודה זו מייסד מתחיל לעגל מספרים כלפי מעלה. ומאחר שקראתי לחברה Veriprajna, קרי חוכמת אמת, עיגול מספרים כלל אינו בא בחשבון. לאורך ערכה קבועה ומתויגת של שנים-עשר עדכונים, השער מפיק את ההחלטה המדויקת בכל השנים-עשר. שישה מהם שפירים והוא אינו חוסם אף אחד מהם. אחד מהם הוא ה-ABSTAIN הישר. לוח התוצאות מציג: 12/12 החלטות מאומתות, 0/6 חסימות שווא, וזמן השבתה מוערך שנמנע בשווי 13.3M $ לאורך הערכה כולה, שמתוכו 5 מיליון דולר מיוחסים לחסימה הבודדת ברמת CrowdStrike.

לוח ביצועי Kestrel המציג 12/12 החלטות מאומתות, 0/6 חסימות שווא, ו-13.3M $ בחשיפה למ סיכונים שנמנעה לאורך ערכת העדכונים המתויגת.
לוח הערך לאורך ערכת המבחנים המתויגת: 12/12 החלטות מאומתות, 0/6 חסימות שווא בעדכונים שפירים, 13.3M $ זמן השבתה מוערך שנמנע במערך כולו. מכנים קטנים, שצוינו במתכוון.

וכעת לחלק שאני מסרב לקצר. אלו תוצאות על שנים-עשר פריטים מתויגים בלבד, ולא הבטחה לגבי העדכון הבא שיגיע לצי שלכם. שישה פריטים שפירים הם בסך הכל שישה. אין פירוש הדבר "חוסם 100% מהעדכונים הרעים", זה לעולם לא יהיה כך, ואם תתפסו אותי כותב משפט כזה בעתיד, עליכם לחדול מלקרוא את דבריי. המספר שאני עומד מאחוריו הוא מסוג שונה: אותו קלט, אותה החלטה, בכל הרצה, כיוון שלפסק הדין אין כל טמפרטורת מודל. הריצו את ערכת המבחנים שוב מחר והיא תחזיר תוצאות זהות ברמת הבייט, וזה בדיוק מה שמאפשר לבקר שכבה דטרמיניסטית באופן שלעולם לא יתאפשר בשכבה הסתברותית.

השאלה שנותרה עמי

מה שמלווה אותי מפרויקט הבנייה הזה הוא עד כמה הכשל היה רגיל ובנאלי. עשרים ואחד שדות במקום שבו ציפו לעשרים. מספר שכל מאמת עצמאי יכול היה ללכוד באמצעות אריתמטיקה פשוטה עוד לפני שמכונה בודדת אותחלה מחדש, אילו רק ניצב מאמת עצמאי בין הספק לבין הצי. לא היה שם איש. ועד היום, במרבית המקרים, עדיין אין שם איש.

כל ארגון מפעיל שמונה עד שנים-עשר סוכנים בעלי הרשאות ברמת הליבה מספקים שאינם בשליטתו, וכל אחד מהם יכול לדחוף קובץ ישירות לתוך ring 0. כלי SBOM מנטרים תלויות קוד פתוח. ניהול זהויות מנטר גישה. אך איש אינו קורא את העדכון הקנייני של הספק בכניסה ומוכיח את בטיחותו. Kestrel אינה מערכת EDR ולעולם אינה נוגעת בליבה. היא יושבת מעל אותם סוכנים ומנהלת את מה שהם מורשים להפיץ. זוהי בדיוק השכבה שניסיתי לבנות, והפירוט המלא זמין בכתובת veriprajna.com/demos/software-update-integrity.

ואם אתם מעדיפים לצפות במערכת בפעולה מאשר לקרוא אותי מתאר אותה, הנה המערכת כולה פועלת מקצה לקצה.

אז הנה מה שאני שואל כעת לגבי כל צי מחשבים שאני פוגש: כאשר עדכון הספק הבא יגיע, מה יעמוד בין אותו קובץ לבין סביבת הייצור, והאם הוא מסוגל להוכיח את עבודתו? אם התשובה היא ועדת ייעוץ לשינויים (CAB) שסומכת בעיניים עצומות על הספק, הרי שאותה שגיאה אריתמטית שהפילה מיליוני מחשבים ממשיכה לפעול ללא כל הפרעה. היא לא תודיע על בואה. היא תיראה בדיוק כמו כל עדכון שקדם לה, ממש עד לרגע האתחול מחדש.

מחקר קשור

פורסם גם ב

בנו את ה-AI שלכם בביטחון.

שותפו עם צוות בעל ניסיון עמוק בבניית הדור הבא של AI ארגוני. אנו נסייע לכם לתכנן, לבנות ולהטמיע אסטרטגיית AI שתוכלו לסמוך עליה.

Veriprajna ייעוץ דיפ-טק מתמחה בבניית מערכות AI קריטיות לבטיחות עבור תחומי הבריאות, הפיננסים והרגולציה. הארכיטקטורות שלנו מאומתות מול פרוטוקולים מבוססים ומלוות בתיעוד ציות מקיף.