המטען המוצפן נדחף לסוף קובץ גופן: הספק המזויף של Terraform מפיץ נוזקה גם ללינוקס ולווינדוס
בשרת לינוקס עם מעבד aarch64, הסקריפט מבקש קובץ בשם NotoSansCJK-Regular.woff. על מק עם Apple Silicon הוא מבקש HiraginoSans-Regular.woff, ועל ווינדוס 64 ביט את MalgunGothic-Bold.woff. שלושת הקבצים נראים כמו גופני ווב רגילים, ותחילת הקובץ אפילו מכילה נתוני גופן אמיתיים. אחרי מחרוזת סימון אחת באמצע מתחיל משהו אחר לגמרי: קובץ הרצה מוצפן, מותאם בדיוק למערכת ההפעלה ולארכיטקטורה של המכונה שביקשה אותו.
את שרשרת ההדבקה הזאת פירסם ב-8 באוקטובר 2026 סונגסו פארק, חוקר איומים ב-Zscaler ThreatLabz, שנתקלה בקמפיין ביולי. נקודת ההתחלה היא ספק מזויף של Terraform, וההמשך הוא מה שעושה את הדוח הזה מעניין: בספטמבר, כשהקמפיין הזה דווח לראשונה, הוא נראה כמו מתקפה ממוקדת על מקים. ברשימת סימני ההיכר של ThreatLabz מופיעים שמונה קבצי מטען מוצפנים, לשלוש מערכות הפעלה ולארבע ארכיטקטורות מעבד. בהמשך נראה מה בדיוק עושה הספק המזויף ברגע ש-Terraform טוענת אותו, למה המטענים מתחזים לגופנים, ואיך הדלת האחורית מוצאת את שרת השליטה שלה בלי שאף כתובת תהיה כתובה בתוכה.
מה כבר היה ידוע, ומה חדש כאן
הצד של הכניסה לארגון תועד לפני שלושה שבועות. ב-18 בספטמבר פירסמה SentinelLabs ניתוח של קמפיין שבו מועמדים למשרות DevOps קיבלו "משימת בית" ממגייס מזויף, ובתוך פרויקט ה-Terraform שבמשימה היה קובץ נעילה ערוך שהצביע על רישום ספקים בשליטת התוקפים. כתבנו על הניתוח הזה בזמנו. שם מדובר היה בשתי דלתות אחוריות ל-macOS בלבד, FLATROOF ו-ROOFDECK, אותן שתיים שהופיעו באפריל בתקיפה של LayerZero שממנה נגנבו 292 מיליון דולר מפרוטוקול KelpDAO.
הדוח של ThreatLabz לא ממשיך משם אלא מסתכל על אותה חיה מצד אחר. הוא מנתח את הבינארי של הספק עצמו ואת מה שהוא מוריד, ולגבי הדגימה שלו הוא אומר במפורש שלא ברור איך הספק הגיע למכונה. השילוב בין שני הדוחות הוא מה שמשלים את התמונה: SentinelLabs הסבירה את הפיתיון, ThreatLabz מראה שהמטען שמחכה בסופו כבר לא מוגבל למחשב אחד של מפתח אחד.
ספק הוא קוד שרץ אצלכם
Terraform לא מדברת ישירות עם AWS או עם Azure. לכל פלטפורמה יש תוסף נפרד שהוא קובץ הרצה לכל דבר, ו-Terraform מפעילה אותו כתהליך ומתקשרת איתו דרך ממשק מוגדר. לתוספים האלה קוראים ספקים, וההשלכה היא פשוטה: terraform init לא מוריד קבצי תצורה, הוא מוריד תוכנות.
הבינארי שניתחה ThreatLabz כתוב ב-Go ונקרא terraform-provider-awsbeta_v1.0.0, ומתחזה לספק של AWS. בתוך הסמלים שלו יש שלד תקין לגמרי של ספק, כולל מימושים לדוגמה של resource ושל data source. לצד השלד הזה הוסיף התוקף חבילה אחת בשם awsbeta וקרא לפונקציה המיוצאת שלה ישר מ-main. התוצאה היא שהקוד הזדוני רץ ברגע ש-Terraform מפעילה את הספק, לפני שמישהו ביקש ממנה ליצור משהו.
מה שהקוד הזה עושה קצר. הוא בודק אם קיים קובץ בשם session.lock בתיקיית הקבצים הזמניים, לפי משתנה הסביבה TMPDIR ובברירת מחדל בתיקיית tmp, וכשהקובץ לא שם הוא מוריד ב-HTTPS סקריפט Bash מדומיין שנקרא hashicorp-terraform[.]io, בנתיב שנראה כמו endpoint לדיווח מטריקות של תוסף Terraform. הסקריפט נשמר בשם safari_updater, מקבל הרשאת הרצה, מורץ דרך sh -c כתהליך בן מנותק, ואז נוצר קובץ הנעילה כדי שזה לא יקרה שוב. ובמקביל הספק ממשיך לענות כמו ספק. ה-plan וה-apply עובדים, ואין בפלט שום סימן שמשהו נוסף נכנס למכונה.
למה המטען מתחזה לגופן
הסקריפט שירד הוא החלק שהופך את הקמפיין לחוצה פלטפורמות, והוא עושה את זה בדרך קטנה ומסודרת: הוא ממפה כל מערכת הפעלה לשם משפחת גופנים וכל ארכיטקטורת מעבד לשם סגנון, ומהשניים מרכיב שם קובץ. לינוקס מקבל NotoSansCJK, macOS מקבל HiraginoSans וווינדוס מקבל MalgunGothic. x86_64 ו-amd64 הם Bold, aarch64 ו-arm64 הם Regular, ARMv6 ו-ARMv7 הם ExtraBold, ו-x86 של 32 ביט הוא Italic. השם שיוצא, למשל HiraginoSans-Regular.woff, נראה כמו קובץ גופן שכל אתר שני מוריד.
גם מאיפה הוא יורד נבחר בקפידה. הסקריפט מנסה שלושה מקורות בזה אחר זה: מאחסן בשירות DNS דינמי, מאגר GitHub, ואתר שמתארח ב-Vercel. בתוך כל קובץ .woff יושבים נתוני גופן מדומים, אחריהם מחרוזת סימון בשם @@ENDFONT@@, ואחריה קובץ ההרצה עצמו, מקודד ב-Base64 ומוצפן ב-AES-256-CBC. הסקריפט חותך את מה שאחרי הסימון, מפענח את הקידוד ומפענח את ההצפנה, וכדי לא לסחוב ספריית הצפנה משלו הוא בודק מה כבר מותקן על המכונה ומשתמש ב-Python, ב-Node.js, ב-Perl או ב-OpenSSL, לפי מה שיש. על מק הוא מסיר קודם את מאפיין ההסגר בעזרת xattr ומחתים את הקובץ בחתימה מקומית, כך ש-Gatekeeper לא עוצר אותו.
הקובץ המפוענח נכתב לנתיב שנראה כמו רכיב של אפליקציה קיימת. בלינוקס זה .config/git/update בתיקיית הבית, ב-macOS זה קובץ בשם SystemUpdate בתוך תיקייה שמתחזה לרכיב iTunesCloud של אפל, ובווינדוס זה service.exe בתיקיית ההתקנה המקומית של Edge. התעבורה שהכול מייצר נראית כמו הורדת גופן מ-GitHub.
שלושה ערוצי שליטה, ולא כולם חייבים לעבוד
הדלת האחורית שמגיעה בסוף התהליך היא FLATROOF, וגרסאות הלינוקס, ה-macOS והווינדוס שלה חולקות אותו מבנה מודולים ב-Rust ואותן יכולות. את התצורה שלה היא נושאת מוצפנת, עם גזירת מפתח ב-PBKDF2-HMAC-SHA256 והצפנה ב-AES-256-GCM, ובתוכה JSON שמגדיר לכל מערכת הפעלה בנפרד לאן להתקין, איך לשמור אחיזה, בכל כמה זמן לפנות לשרת ולאן. שימור האחיזה בדגימה שפורסמה הוא service בלינוקס בשם snap-imagent, מנגנון ה-zlogout של מק, וערך Run ברישום של ווינדוס בשם powershell-config-service. היא גם מחפשת נתיבים ותהליכים של Cortex XDR ושל Traps, כלומר בודקת אם יש על המכונה הגנה שתזהה אותה.
לערוץ השליטה יש שלוש אפשרויות: ממשק הבוטים של Telegram, תשאול של ה-API של GitHub מול מאגר ו-token מוגדרים, ו-webhook בשליטת התוקף לרישום ולקבלת משימות. לא כל ערוץ מוגדר בכל דגימה, אבל הקוד תומך בשלושתם. היתרון כפול: גם גיבוי אם אחד נחסם, וגם תעבורה שנראית כמו פנייה רגילה לשירות פופולרי.
איסוף המידע עצמו נעשה בסקריפטי פייתון נפרדים לכל מערכת הפעלה, שאורזים הכול לארכיון אחד. שלושתם לוקחים את מסדי הנתונים של דפדפני Chromium ושל Firefox, היסטוריות פקודות מהטרמינל, רשימת אפליקציות מותקנות, תצלום של התהליכים הרצים ושם המשתמש. בלינוקס נוסף חילוץ של סוד ה-Safe Storage של Chrome דרך שירות הסודות של המערכת וקבצי keyring, במק עותק של login.keychain-db ונתוני Safari, ובווינדוס רשומות של Credential Manager, היסטוריית PowerShell ושורת הפקודה, ונתוני התוספים של ארנקי MetaMask, Phantom, Trust Wallet ו-Rabby. בגרסת ווינדוס מוטמעים גם שני קבצי הרצה: אחד שמוזרק לתהליך Chromium שמושהה כדי לחלץ את מפתחות ההצפנה הראשיים של הדפדפן, ושני שמעתיק קובצי cookie כשההעתקה הרגילה נכשלת.
על הסקריפטים האלה ThreatLabz מוסיפה הערכה, לא קביעה: ההערות המפורטות, האמוג'ים, הטיפול החוזר בשגיאות ושמות המשתנים הלא עקביים מעלים לדעתם את האפשרות שחלקים מהקוד נכתבו או שופרו בעזרת מודל שפה גדול.
הכתובת לא נמצאת בקוד
ROOFDECK יורדת בשלב הבא, ומה שמייחד אותה הוא לא רשימת היכולות שלה אלא איך היא מגלה לאן לפנות. קודם היא קוראת קובץ תצורה מקומי שמתחזה לקובץ של אפליקציה לגיטימית. אם זה לא עובד, היא מורידה קובץ מ-Pastebin שבתוכו כתובת שרת מוצפנת וחתימת RSA, מופרדות בשני קווים אנכיים, ומאמתת את החתימה לפני שהיא מפענחת ומקבלת את הכתובת. הסידור הזה לא נועד להסתיר את הכתובת מהמגננה אלא למנוע ממישהו אחר שימצא את אותו קובץ Pastebin להפנות את המכונות הנגועות לשרת שלו, בלי מפתח החתימה של המפעיל.
ואם גם ה-Pastebin לא נגיש, ROOFDECK פונה לרשת החברתית המבוזרת Nostr, מחפשת פרופילים של המפעיל וקוראת מהם את שדה האתר. בזמן הניתוח, פרופיל פעיל בשם tulip הצביע על אותה כתובת Pastebin שהייתה מוטמעת בגרסת הווינדוס. את מנגנון ה-Nostr הזה תיארנו בהרחבה בכתבה הקודמת; החדש כאן הוא השכבה החתומה שמתחתיו. מהרגע שהכתובת בידיה, ROOFDECK מדברת עם השרת ב-HTTP וב-WebSocket, ומציעה למפעיל shell הפוך, פעולות על קבצים, קריאה וכתיבה ללוח הגזירים, שינוי של כתובת השרת ושל קצב הפניות, עדכון עצמי והשמדה עצמית.
עד כמה בטוח שזו TraderTraitor
כאן כדאי לקרוא את מה שהחוקרים כתבו ולא את הכותרת. הקמפיין מיוחס ל-TraderTraitor, תת-קבוצה של Lazarus שמיוחסת לממשל בצפון קוריאה ומוכרת גם בשמות Jade Sleet, UNC4899, Pressure Chollima ו-Slow Pisces, והחפיפה לאירוע KelpDAO קיימת בשמות הנוזקות ובאופי היעדים. ThreatLabz עצמה בולמת שם: "ThreatLabz זיהתה חפיפה מהותית בטקטיקות ובמיקוד עם TraderTraitor. עם זאת, ThreatLabz לא זיהתה דמיון קוד ייחודי, תשתית משותפת או קשרים קריפטוגרפיים שמספיקים כדי לייחס את הקמפיין הזה ל-TraderTraitor באופן עצמאי וברמת ודאות גבוהה", כתבו בפרק הייחוס. SentinelLabs, שהגיעה לקורבן שלה דרך אותן דלתות אחוריות שהופיעו בתקיפת LayerZero, כן מייחסת את הפעילות לקבוצה בלי סייג. השוני בין שתי הקביעות הוא הבדל במה שכל חברה ראתה, לא מחלוקת על העובדות.
מה זה אומר בפועל
מי שצריך לעשות משהו עם הדוח הזה הוא מי שמריץ Terraform, ולא רק על מק. השורה המעשית הראשונה היא שתחנת פיתוח ומערכת CI/CD מריצות ספקים כקבצי הרצה, ולכן פרויקט תשתית שהגיע מבחוץ שווה בדיקה של קובץ הנעילה ושל הרישום שהוא מצביע עליו לפני שמריצים terraform init, וגם אימות של הסכימות שלו. ThreatLabz ממליצה להגביל שימוש בספקים שאינם מאומתים, לאמת checksum, ולנטר פעילות תהליכים חריגה בתחנות פיתוח.
הנקודה השנייה נוגעת למי שסימן את הקמפיין הזה בספטמבר כבעיה של מפתחים עם מק. שמונה המטענים שבדוח מכסים גם ELF של 32 ביט וגם ARM, כלומר גם מכונות בנייה ו-runner-ים בלינוקס. אם כתבתם חוקי זיהוי לפי הנתיבים של גרסת ה-macOS, הם לא יתפסו את הגרסה שכותבת קובץ בשם update לתוך תיקיית התצורה של git.
תגובות