הסוד נמחק מה-issue ונשאר בהיסטוריית העריכות: כך נמחקו יותר ממאה חשבונות אחסון ב-Azure בשבע דקות
עובד בארגון הדביק לתוך issue ציבורי ב-GitHub שלוש מחרוזות: מזהה האפליקציה, הסוד שלה, ומזהה ה-tenant של הארגון ב-Azure. מתישהו אחר כך הוא חזר, ערך את ה-issue והוריד משם את הסוד. הבעיה היא ש-GitHub שומר את היסטוריית העריכות, והיא פתוחה לכל אחד בדיוק כמו הטקסט שהחליף אותה.
ב-25 בספטמבר פרסמה Microsoft Security Research ניתוח של מה שקרה בסביבת Azure של אותו ארגון בתחילת יוני 2026. שתי זהויות אפליקטיביות גנובות מיפו את הסביבה במשך כמעט שש עשרה שעות, ואז מחקו ממנה יותר ממאה חשבונות אחסון בשבע דקות. החוקרים Yossi Weizman ו-Tushar Mudi, יחד עם צוות המחקר של מיקרוסופט, כותבים במפורש שלא הצליחו לאמת שדווקא הסוד מה-issue הוא זה ששימש לתקיפה. מה שכן יש כאן הוא המבט המפורט הראשון על מה שקבוצה בשם JADEPUFFER עושה בענן אחרי שהיא כבר בפנים.
בהמשך נראה למה הזהות שנגנבה כאן נוחה לתוקף יותר מחשבון של עובד, מה בדיוק מראה הלוג, ומה מכל ההגנות בסביבה באמת עצר משהו.
למה תוקף מעדיף זהות של אפליקציה על חשבון של אדם
כשסקריפט או שירות צריכים לגשת למשאבים בענן, לא נותנים להם את הסיסמה של עובד. פותחים להם זהות נפרדת עם מזהה משלה, סוד משלה והרשאות משלה, וכל פעולה שהיא מבצעת נרשמת על שמה. ב-Azure קוראים לזהות כזאת service principal.
מבחינת תוקף זאת עסקה טובה יותר מחשבון אנושי. אין MFA שצריך לעקוף, אין אדם שיקבל התראה על התחברות ממדינה מוזרה, והסוד לא פג בעוד תשעים יום כמו סיסמה של עובד. ההרשאות גם נוטות להיות נדיבות מדי, כי ברגע שמישהו רצה שהאוטומציה פשוט תעבוד, קל יותר לתת לה Contributor על כל ה-subscription מאשר לחשב בדיוק אילו פעולות היא צריכה. בתקיפה הזאת שתי הזהויות השתייכו לאותו tenant, הגיעו מתשתית שמיקרוסופט מקשרת ל-Storm-3168 (השם שבו היא עוקבת אחרי JADEPUFFER), ונשאו את אותה חתימת רשת ואת אותו user agent: python-requests/2.34.2.
חמש עשרה שעות של קריאה, ואז שבע דקות של מחיקה
הזהות הראשונה עשתה דבר אחד בלבד, לאט. במשך כחמש עשרה שעות וחצי היא ספרה מכונות וירטואליות, subscriptions, resource groups ומשאבים, ורשמה יותר מ-300 פעולות קריאה מוצלחות. אף אחת מהן לא שינתה כלום, וזאת בדיוק הנקודה: פעולת קריאה בענן נראית כמו עבודה שגרתית של כלי ניטור, ולא כמו תוקף שמסתובב בבית.
כתשעים דקות אחרי שהראשונה התחילה, נכנסה השנייה. היא סרקה מכונות וירטואליות ו-resource groups בשני subscriptions בתוך חמש שניות, ואז ירדה מהרדאר. שש עשרה שעות מאוחר יותר היא חזרה ועברה על מאגרי התצורה של שירותי App Service בסביבה, כנראה בחיפוש אחר פרטי אימות ששמורים שם. היא ניסתה גם לאתר משאבי Azure OpenSearch, בלי הצלחה.
ואז זה התהפך. שבעים שניות אחרי פעולת המיפוי האחרונה ביקשה אותה זהות את מפתחות הגישה של חשבון אחסון שכלל לא היה קיים. פחות משנייה אחרי שהבקשה נכשלה התחילה המחיקה. בשלושים וחמש הדקות הבאות נרשמו יותר מ-150 פעולות הרס או איסוף פרטי אימות, והליבה ההרסנית שלהן, יותר ממאה ניסיונות למחוק חשבונות אחסון, רצה שבע דקות בלבד. רוב חשבונות האחסון שהותקפו אכן נמחקו.
מה עצר חלק מהמחיקה, ומה עצר אותה בטעות
לא הכול הלך לתוקף. חלק מחשבונות האחסון שרדו כי היו עליהם resource locks והגנת מחיקה שמוגדרת ברמת חשבון האחסון עצמו. מיקרוסופט מדגישה שזה בדיוק הערך של מנגנון שעובד בנפרד מההרשאות: הזהות הגנובה החזיקה סמכות ניהולית רחבה, והמנעול עצר אותה בכל זאת. Key Vault אחד, Function App ותוכנית App Service כן נמחקו, שלושתם באותו resource group ושלושתם כנראה חלק מאותה אפליקציה.
הסיפור של מסדי הנתונים שונה, ופחות מחמיא להגנות. התוקף ניסה למחוק כמה מסדי נתונים של Azure SQL במקביל למחיקת האחסון, וכל הניסיונות נכשלו. לא בגלל מנעול ולא בגלל הרשאה חסרה, אלא כי הקריאות השתמשו בגרסת API שאינה נתמכת עבור סוג המשאב הזה. באג בכלי של התוקף הוא שהציל את מסדי הנתונים.
נרשמו גם ניסיונות כושלים למחוק מנעולים שמגנים על Azure Site Recovery ועל גיבויי Azure Backup. כשלושים דקות אחרי סוף ההרס חזרה הזהות, ביקשה רשימה של חשבונות אחסון, ושלפה בהצלחה מפתחות גישה של יותר משלושים מהם, בהם חשבונות אחסון ששייכים למנגנון ההתאוששות. מיקרוסופט לא ראתה הודעת כופר ולא אישרה הוצאת מידע בפועל, אבל לפי הדוח השילוב של הרס, ניסיון לפגוע ביכולת השחזור ואיסוף מפתחות שפותחים גישה למידע מתיישב עם מה שנעשה לקראת סחיטה.
אז מי הפעיל את זה, אדם או סקריפט?
כאן הדוח זהיר, וכדאי לשמור על הזהירות הזאת. מיקרוסופט לא מצהירה שמודל שפה ניהל את התקיפה הספציפית הזאת בזמן אמת. מה שהיא כן אומרת הוא שהתזמון בין הפעולות, חלוקת העבודה בין שתי הזהויות וזרמי ה-token-ים החופפים מאותה זהות "מצביעים בבירור על הרצה אוטומטית או מבוססת סקריפט", כלשון החוקרים.
הפירוט מאחורי המשפט הזה משכנע. לזהות שביצעה את ההרס הונפקו חמישה token-ים נפרדים: ארבעה שימשו למחיקות, והחמישי לרשימת האחסון ולשליפת המפתחות. שניים מארבעת ה-token-ים של המחיקה היו פעילים באותו חלון של שבעים שניות, כשאחד עסק במחיקת אחסון והשני בתערובת של אחסון ו-SQL. כלומר שני זרמי פעולה רצו במקביל תחת אותה זהות, מה שאדם שעובד מול מסוף לא באמת עושה.
פרט נוסף שווה תשומת לב: כל פעולה שהצליחה נשענה בדיוק על הרשאה שכבר הייתה לזהות. הרשאת Storage Account Contributor שהגיעה דרך חברות בקבוצה אישרה את מחיקות האחסון, הרשאת Contributor ישירה אישרה את מחיקת שלושת משאבי האפליקציה, והרשאת SQL DB Contributor ישירה היא שאפשרה בכלל את ניסיונות ה-SQL. התוקף לא הסלים הרשאות בשום שלב. הוא מיפה מה מותר לו, ועשה את זה.
מ-Langflow לענן: מה ידוע על JADEPUFFER
את הקבוצה תיעדה לראשונה Sysdig ביולי 2026, ותיארה אותה כמקרה המתועד הראשון של מתקפת כופרה שסוכן LLM הריץ מקצה לקצה. נקודת הכניסה שם הייתה CVE-2025-3248, חולשת היעדר אימות ב-endpoint /api/v1/validate/code של Langflow, פריימוורק קוד פתוח לבניית אפליקציות מבוססות LLM. החולשה נמצאת בקטלוג ה-KEV של CISA מאז מאי 2025, ולפי Sysdig היא נשארה וקטור הכניסה של הקבוצה בכל הקמפיינים שתועדו עד כה. בשלב מאוחר יותר, ש-Sysdig תיארה בסוף יולי, הקבוצה חזרה לאותו שרת Langflow עם כופרה ייעודית בשם ENCFORGE שסורקת כ-180 סיומות קבצים, רובן מעולם ה-AI: משקלי מודלים, מסדי נתונים וקטוריים, מערכי אימון ואינדקסים של embeddings.
וכאן החלק בדוח של מיקרוסופט שמעניין דווקא במה שהוא לא מוכיח. מיקרוסופט אכן ראתה, מתחילת השנה, סריקות מתשתית שמקושרת ל-Storm-3168 נגד שירותי App Service של לקוחות שונים, ובכלל זה נגד אותו endpoint של Langflow ונגד נתיבי ניהול של וורדפרס ושל PHP-CGI. אבל היעדים האלה לא חפפו ל-subscriptions שנפגעו, ובארגון שנפגע לא נמצא מסלול שמוביל מ-App Service אל פרטי האימות של ARM. שני הקצוות של הקבוצה מתועדים היטב. החוליה שביניהם, במקרה הזה, לא.
מה זה אומר בפועל
הלקח הכי ישיר כאן לא נוגע ל-AI בכלל. סוד שנחשף פעם אחת במקום ציבורי הוא סוד שרוף, ועריכה של ההודעה לא מבטלת אותו: היסטוריית העריכות, המטמונים והעותקים נשארים. אם פרטי אימות של service principal הופיעו אי פעם ב-repository, ב-issue או בקובץ תצורה שמישהו העלה, החליפו אותם ובדקו לאחור מתי ומאיפה נעשה בהם שימוש.
שני דברים נוספים שווים שעה עבודה השבוע. עברו על ההרשאות של כל service principal בסביבה וצמצמו אותן למה שהאפליקציה באמת צריכה, כי כל מחיקה שהצליחה כאן הצליחה בזכות הרשאה שניתנה מראש. והדליקו resource locks והגנת מחיקה על חשבונות האחסון ועל תשתית הגיבוי, כי אלה הדברים היחידים בסיפור הזה שעצרו תוקף שכבר החזיק את המפתחות.
תגובות