כל עשר שניות הנוזקה בודקת אם הגיע מייל עם פקודה: Antino מנהלת את ערוץ השליטה שלה דרך Outlook ו-OneDrive
על מכונה שנדבקה בקמפיין הזה, יומן התעבורה היוצאת נראה משעמם להפליא. שתי כתובות חוזרות שוב ושוב, login.microsoftonline.com ו-graph.microsoft.com, בדיוק אותן כתובות שכל Outlook וכל OneDrive בארגון מדברים איתן כל היום. אין domain מוזר שנרשם לפני שבועיים, אין IP שאף אחד לא מכיר, אין port לא סטנדרטי. הנוזקה אכן מתחברת ל-Microsoft 365, רק לא לשלכם: ל-tenant שהתוקף רשם לעצמו, שממנו היא מושכת מייל שבגוף שלו כתובה פקודה, מריצה אותה, ושולחת את הפלט בחזרה לאותה תיבה.
חוקרי Cisco Talos פרסמו ב-30 בספטמבר ניתוח של הדלת האחורית הזאת, שהם קוראים לה Antino על שם מחרוזות שהמפתחים השאירו בקוד, ושל אשכול התקיפה שמפעיל אותה, UAT-11587. לפי הדוח, שכתבה החוקרת Ashley Shen, הפעילות נצפתה לראשונה בספטמבר 2025 ונמשכה עד יולי 2026, עם כ-350 endpoint-ים נגועים בשמונה מדינות באסיה ולפחות 16 סביבות מוסדיות שנפגעו או היו יעד: עשר מאומתות, חמש משוערות ואחת שנותרה יעד מתוכנן. הגל הגדול ביותר התרחש ב-8 וב-9 ביוני, עם כ-57 endpoint-ים חדשים שקושרו להודו. בהמשך נעבור על איך המייל הראשון נראה לנמען, איך מגיעים ממנו לקוד שרץ על המכונה, ולמה ערוץ השליטה הוא החלק שהכי קשה לתפוס.
המייל שמראה לכם קובץ מצורף שלא קיים
ההתאמה של הפיתיונות ליעד מרשימה: אחד המסמכים שחולצו משכתב הנחיה אמיתית של משרד האוצר הטייוואני על מיסוי הוצאות של חברי פרלמנט. הטריק החזק יותר יושב בגוף ההודעה. התוקפים לא צירפו קובץ בכלל. הם בנו בתוך ה-HTML של המייל חיקוי של כרטיס הקובץ המצורף ש-Gmail מצייר, מארבע תמונות PNG שהוטמעו בקידוד Base64, ועטפו את כל הכרטיס בקישור לכתובת שבשליטתם. Gmail מצייר את ה-HTML כפי שהוא, ומה שהנמען רואה נראה בדיוק כמו קובץ מצורף. הקישור מוביל ל-Cloudflare Pages, ובפרמטר ?m= יושב מזהה ייחודי לכל נמען, כך שהמפעיל יודע מי לחץ. Talos מצביעה על פרט קטן שמסגיר תכנון: הכתובת נכתבה בצורה שמתחילה ב-// בלי http או https לפניה, צורה חוקית שכלי אבטחה שמחלצים רק כתובות מלאות פשוט לא סופרים.
וכדי שההודעה תגיע בכלל, הקבוצה ניצלה את הפער בין שתי הכתובות שיש לכל מייל. ההודעות נשלחו דרך שירות הדיוור Migadu עם הדומיין osc-cdn[.]com ככתובת השולח ברמת הפרוטוקול, זו שנבדקת ב-SPF, בעוד שבשדה From שהנמען רואה הופיע שמו של הארגון שאליו התחזו. SPF עבר, כי Migadu באמת מורשית לשלוח בשם osc-cdn[.]com. DMARC, שנועד לתפוס בדיוק את זה, זיהה את הפער והחזיר כישלון. זה לא עזר: המדיניות של הדומיין שהוצג לנמען הייתה p=none, כלומר דווחו לי ואל תעשו כלום, וההודעה עברה לתיבה.
חמישה שלבים עד שמשהו נכתב לדיסק
הלחיצה על הכרטיס המזויף מורידה קובץ HTA, פורמט ישן של Windows שמריץ HTML ו-script דרך mshta.exe. הוא מסתיר את החלון של עצמו, שולח בקשה לכתובת מעקב קבועה ב-Cloudflare Pages עם שם הפיתיון בנתיב, כך שהמפעיל יודע איזה פיתיון עבד, ומושך את השלב הבא מ-Cloudflare R2 או מ-CloudFront.
מכאן זה נעשה מעניין. השלב השני הוא JScript שמוריד שלושה קבצים מוצפנים, מפענח אותם בעזרת Base64 מותאם ו-RC4 עם מפתח מוטמע, ואז עושה משהו שנשמע עקום ועובד מצוין: הוא מבקש מ-.NET לשחזר אובייקטים מתוך נתונים שהתוקף הכין מראש. הרכיב שמשחזר אותם, BinaryFormatter, לא בודק מה בדיוק הוא בונה, וכשהנתונים מורכבים נכון עצם השחזור גורם להרצת הקוד. לרצף האובייקטים שבונה את ההרצה הזאת קוראים gadget chain. התוקפים שולחים שני רצפים זה אחר זה: הראשון מנסה לכבות בדיקת אבטחה ש-Microsoft הוסיפה כדי לחסום בדיוק את הטכניקה הזאת, והשני טוען קובץ .NET בשם TestAssembly.dll ישירות לזיכרון של mshta.exe. הקריאה הראשונה עטופה ב-try/catch, מה שלפי החוקרים מרמז שהמפתחים ציפו להבדלי גרסאות של .NET בין היעדים.
TestAssembly.dll הוא רק שליח. הוא מוריד מסמך פיתיון שנפתח מול המשתמש, ולצידו שלושה קבצים עם סיומות אקראיות, .luy, .pzs ו-.syk. בתוכם קובץ הרצה חתום של Microsoft בשם GatherOsState.exe, רכיב לגיטימי מערכת ה-ADK של Windows, הנוזקה עצמה בשם slc.dll, וקובץ דמה. כשמריצים את הקובץ החתום הוא מחפש ספרייה בשם slc.dll בתיקייה שלו, מוצא את זו שהתוקף שתל, וטוען אותה. לטכניקה הזאת קוראים DLL sideloading, והיא הסיבה שמה שרץ בפועל על המכונה הוא תהליך עם חתימה דיגיטלית תקינה.
אז איפה שרת השליטה? אין כזה
עד כאן השרשרת דומה לעשרות קמפיינים אחרים. מה שמבדיל את Antino מתחיל בדיוק כאן.
רוב הנוזקות צריכות מקום לדבר איתו, ושם גם נקודת התורפה שלהן: שרת אפשר לחסום, ואת הכתובת שלו אפשר לזהות בלוגים. Antino פתרה את זה אחרת. היא נכנסת לחשבון Microsoft 365 שהתוקפים רשמו לעצמם ומשתמשת ב-Microsoft Graph, ה-API הסטנדרטי שדרכו אפליקציות ניגשות לדואר ולקבצים. האימות נעשה בזרימת OAuth 2.0 מסוג client credentials, כלומר אפליקציה רשומה ב-Entra ID עם הרשאות משל עצמה, בלי שאף אדם צריך להתחבר. לדפוס שבו שני הצדדים לא מדברים ישירות אלא משאירים זה לזה הודעות במקום שלישי קוראים dead drop, על שם שיטת העבודה של מרגלים.
בפועל יש כאן שני ערוצים. הראשון הוא תיבת הדואר. Antino מושכת ממנה הודעות כל עשר שניות, מזהה את הרלוונטיות לפי קידומת בשורת הנושא, command_req_ ואחריה מזהה ה-session שלה, ומפרסרת מגוף ההודעה אובייקט JSON עם שלושה שדות: איזו פקודה להריץ, הפרמטרים שלה, ומזהה שקושר בין בקשה לתשובה. את הפלט היא שולחת בחזרה כהודעה עם הקידומת command_res_.
הערוץ השני הוא OneDrive, ושמות התיקיות בו נכתבו מנקודת המבט של המפעיל ולא של הקורבן. לתיקייה /antino/heartbeats/ מעלה הנוזקה כל דקה קובץ JSON עם מזהה ה-session, שם המחשב, שם המשתמש, הפלטפורמה וקוד קמפיין. ב-/antino_uploads/ מניח התוקף כלים שהוא רוצה להעביר למחשב הנגוע, ול-/antino_downloads/ מעלה הנוזקה קבצים שחילצה ממנו. כלומר הקבצים שנגנבים מכם יושבים ב-OneDrive של מישהו אחר, והדרך שלהם לשם נראית ברשת כמו סנכרון רגיל.
עשר פקודות, ושתי דרכים להסתיר אותן
Antino כתובה ב-Rust ונמצאה בגרסאות 32 ו-64 ביט, כקובץ הרצה עצמאי וגם כ-DLL. ברשימת המטפלים שחולצה מהגרסאות שנבדקו עשר פקודות, והזמינות משתנה בין בניות: הרצת שורת פקודה ב-cmd וב-PowerShell, איסוף פרטי מערכת, הרצת תוכנית שהמפעיל סיפק, רשימת קבצים בתיקייה, העלאה והורדה של קבצים, טעינת shellcode לזיכרון, הוספת ערך תחת מפתח Run ב-registry, ויציאה.
שתי יכולות בולטות מעבר לרשימה. הראשונה נוגעת למה שקורה כש-shellcode שנטען לזיכרון נכנס להמתנה. Antino מחליפה את ההתנהגות של Sleep ו-VirtualAlloc ורושמת מטפל חריגות משלה (VEH). כשהקוד הנטען קורא ל-Sleep, הנוזקה מסמנת את אזור הזיכרון שלו כלא ניתן להרצה, מצפינה את התוכן במקום, ורק אז נרדמת באמת. הניסיון הבא להריץ משם קוד יוצר חריגה, ומטפל החריגות מפענח בחזרה ומחזיר את הרשאות ההרצה. בחלון הזמן שבו סורק זיכרון סביר להסתכל, המטען לא נראה כקוד. Talos מדגישה שזה לא מסתיר את Antino עצמה ולא מבטיח התחמקות.
השנייה היא איך הנוזקה משיגה שרידות (persistence, היכולת לחזור לפעולה אחרי אתחול) בלי להריץ PowerShell בעצמה. ל-Windows יש מנגנון אבחון תקלות, אותם פותרי בעיות מובנים, שמריץ scripts של PowerShell דרך תהליך בשם sdiagnhost.exe. Antino יוצרת דרך COM מופע של מנוע האבחון, מאתחלת אותו עם חבילת אבחון לגיטימית, מקבלת ממנו תיקיית עבודה זמנית, כותבת לתוכה script משלה, ומבקשת מהמנוע להמשיך. ה-script שמוסיף את הערך ב-registry רץ אז תחת תהליך חתום של Microsoft ולא תחת הנוזקה.
למה Talos אומרת סין, ומה היא לא מוכנה לקבוע
ההערכה נשענת על צבר סימנים ולא על אחד בודד. מסמך פיתיון שכוון לטייוואן נושא תגית שפה zh-CN, סינית מפושטת, ערך מחבר 未定义 (לא מוגדר) וחותמת יצירה באזור זמן +08:00, ושתי הודעות הפישינג שנמצאו נושאות גם הן +08:00. החוקרים מציינים בעצמם שאזור הזמן לבדו לא אומר הרבה, כי הוא משותף לסין, לטייוואן, להונג קונג ולסינגפור, אבל בשילוב עם סינית מפושטת הוא מתאים יותר ליבשת מאשר לטייוואן ולהונג קונג, שבהן נהוגה סינית מסורתית. בעשרה קבצי Antino שונים נמצאו נתיבי Cargo שמפנים ל-rsproxy.cn, מראה חבילות Rust שמאיץ הורדות בתוך סין.
מעניין לא פחות מה שהחוקרים נמנעים מלקבוע. נמצא downloader שמפנה לאותה הפצת CloudFront שדווחה בעבר על ידי Arctic Wolf בפעילות של הקבוצה UNC6384, אבל מכיוון שתשתית ענן עוברת בין קבוצות ושתיהן משתמשות בנוזקות ובארכיטקטורות שליטה שונות, Talos מדרגת את הקשר ברמת ודאות נמוכה. במקביל פרסמה Symantec מחקר על Jewelbug, קבוצה סינית שמריצה ריגול והונאת קריפטו זו לצד זו, ו-Talos מצאה חפיפה בינה לבין פעילות Antino. Symantec כתבה שלהערכתה "עסק ה-SEO סיפק גישה, תשתית והפצה למבצע הריגול, ולא שאדם אחד ביצע את שני התפקידים". Talos לא אימתה באופן עצמאי קשר בין קמפיין הריגול לפעילות הכלכלית, ולכן היא עוקבת אחרי UAT-11587 כאשכול נפרד.
מה זה אומר בפועל
היעדים כאן הם גופי ממשל באסיה, לא ארגונים ישראליים, אבל ערוץ השליטה הוא מה ששווה לקחת מהדוח. Microsoft 365 נמצא כמעט בכל ארגון בישראל, ושתי הכתובות האלה מותרות בכל firewall שראיתם אי פעם, כך שחסימה לפי יעד לא תעשה כאן כלום. מה שכן אפשר לבדוק זה מי מדבר ולאן: תהליך שהוא לא דפדפן ולא רכיב Office ומחזיק token מול Graph, ובמיוחד כזה שמתאמת מול tenant שאינו שלכם, הוא חריגה שאפשר לנסח עליה כלל זיהוי. באותה הזדמנות, GatherOsState.exe שרץ מחוץ לתיקיית ההתקנה של ADK הוא דגל אדום בפני עצמו.
ולמי שאחראי אצלכם על הדואר, שווה לפתוח את רשומת ה-DMARC שלכם. ההודעות בקמפיין הזה הגיעו ליעד לא כי משהו נשבר, אלא כי המדיניות הייתה p=none והכישלון רק דווח. p=quarantine הוא ההבדל בין דוח שאף אחד לא קורא לבין הודעה שלא נוחתת בתיבה.
תגובות