Chrome נפתח, ובין התוספים יושב תוסף בשם Smart Bookmarks. אין באנר צהוב שמזהיר על מצב מפתחים, אין חלונית שמבקשת אישור, ואין רישום בחנות התוספים הרשמית. מבחינת הדפדפן התוסף הזה תקין לחלוטין, מפני שמי שהתקין אותו טרח לחתום מחדש על הקובץ שבו Chrome שומר אילו תוספים אושרו לפרופיל.

חוקרי יחידת המחקר STRU של SOCRadar פרסמו ב-4 בספטמבר ניתוח של הערכה הזאת, שאותה הם מכנים PEEP, וThe Hacker News הרימו אותה בסוף השבוע. זאת לא נוזקה שמגיעה במייל ולא קמפיין פישינג. PEEP הוא כלי post-exploitation, שנכנס לתמונה רק אחרי שלתוקף כבר יש הרצת קוד על המחשב. מה שהוא מוסיף מעבר לגישה שכבר יש הוא העניין: הוא הופך את Chrome או Edge לדלת אחורית קבועה שיודעת להריץ פקודות על מערכת ההפעלה עצמה.

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

התוסף שנכנס בלי לעבור בחנות

PEEP הוא לא קובץ בודד אלא ערכה מודולרית עם שלושה חלקים. הראשון הוא הסוכן עצמו, תוסף Manifest V3 בשם Smart Bookmarks בגרסה 1.3.0, שמבקש הרשאות לכל הכתובות (all_urls), ללשוניות, לעוגיות, להיסטוריה, להורדות, להגדרות ה-proxy ולתקשורת עם תוכנה מקומית. השני הוא nm_host.exe, קובץ הרצה ל-Windows במשקל 37.7 מגה-בייט שאורז בתוכו Node.js בגרסה 18.5.0. השלישי יושב בצד השרת: לוח בקרה בנוי Flask מעל SQLite, על Python 3.12.

הבסיס לא מקורי, והחוקרים אומרים את זה במפורש. PEEP נשען על RedExt, פרויקט קוד פתוח לצוותי red team שמימש את הרעיון של שרת שליטה ובקרה שעובד דרך תוסף דפדפן, ושומר את מסלולי ה-API שלו כמעט כלשונם. מה שהמפעיל הוסיף הוא בדיוק מה שמפריד בין הוכחת היתכנות לכלי עבודה: מנגנון התקנה שקטה, גשר אל מערכת ההפעלה, ערוץ עדכונים לתוסף, וסט פקודות מורחב. זאת נגזרת תפעולית של RedExt, לא RedExt עצמו.

אז איך התוסף שורד את הפעלת הדפדפן?

Chromium שומר בקובץ בשם Secure Preferences את הרשימה של מה מותר לרוץ בפרופיל, ולצד כל רשומה ערך קצר שמחושב מתוך תוכנה, ומעליהם ערך אחד שמכסה את הקובץ כולו. בכל הפעלה הדפדפן מחשב את הערכים מחדש ומשווה, ואם מישהו הוסיף תוסף ידנית מאחורי גבו של הדפדפן, החישוב לא יתאים והתוסף יבוטל. בקוד של Chromium קוראים להם protection.macs ו-super_mac.

הבעיה היא שהמפתח שממנו מחושבים הערכים האלה הוא ערך קבוע וידוע בקוד הפתוח של Chromium. אז PEEP פשוט מחשב אותם בעצמו וכותב אותם. הסקריפט install_silent.ps1, 279 שורות PowerShell, עושה בדיוק את זה: מחשב את ה-HMAC-SHA256 לרשומה של התוסף, מסמן developer_mode כאמת, ומעדכן את ה-super_mac העליון. סקריפט שני, patch_secure_prefs.ps1 באורך 1,019 שורות, עושה את אותו הדבר ביסודיות רבה יותר, כולל שחזור של הסדר שבו Chromium מסדר את שדות ה-JSON לפני החישוב. גרסת פייתון מיישמת את אותה טכניקה מול פרופילי Chrome ו-Chromium ב-Linux. ב-MITRE ATT&CK זאת T1553, עקיפה של מנגנוני אמון.

לא תמיד זה מספיק. סקריפט שלישי בערכה, force_enable.ps1, מוותר לגמרי על Secure Preferences ונשען במקום זאת על מפתח הרישום HKCU Extensions, ושורת הלוג האחרונה שלו מסגירה כמה זה מתיש מהצד של התוקף: אם התוסף עדיין מושבת, כותב הסקריפט, ייתכן ש-Chrome 150 ידרוש מדיניות ForceInstall ארגונית.

והשכבה הרביעית היא הכי מעניינת טכנית. כש-Chrome מהדר את ה-service worker של תוסף, הוא שומר את התוצאה המהודרת במטמון ומאנדקס אותה לפי הכתובת של הקובץ ולא לפי התוכן שלו. המפעיל דורס את background.js ואת content.js בגרסאות ריקות ותמימות, משאיר את מזהה התוסף, את הגרסה ואת הנתיב כמו שהם, ובהפעלה הבאה הדפדפן טוען מהמטמון את ה-worker הזדוני שכבר הודר קודם. מי שיפתח את תיקיית התוסף יראה קוד נקי. הקוד שרץ בפועל אינו הקוד שבתיקייה. בערכה קוראים לזה Ghost Anchor Persistence, והיא עותק מותאם של הוכחת היתכנות ציבורית.

ארבע השכבות, אם כן: רשומת Secure Preferences חתומה מחדש, מדיניות התקנה ארגונית כפויה, רישום המארח לתקשורת מקומית, ומטמון ה-worker. אף פעולת ניקוי בודדת לא מסירה את כולן.

הגשר שמוציא את התוסף אל מערכת ההפעלה

תוסף דפדפן רץ בארגז חול. הוא יכול לקרוא דפים, לגעת בעוגיות ולפתוח לשוניות, אבל הוא לא אמור להיות מסוגל להריץ תוכנה על המחשב. ל-Chrome יש מנגנון רשמי שכן מאפשר את זה: תוכנה שמותקנת על המכונה נרשמת במפתח רישום ייעודי, והתוסף מחליף איתה הודעות דרך הקלט והפלט הסטנדרטיים שלה. מנהלי סיסמאות וכרטיסים חכמים לחתימה דיגיטלית משתמשים בזה כל יום. קוראים לו native messaging, ו-PEEP רושם דרכו מארח בשם com.peep.lab.

מהצד השני של הגשר יושב nm_host.exe, קובץ הרצה 64 סיביות לא חתום. הפקודות שהוא חושף קצרות ולעניין: list_dir, read_file, write_file, delete_path, search_files, process_list, list_services ו-shell. האחרונה היא העיקר, והיא מריצה פקודה דרך cmd, PowerShell, bash או sh.

כאן יש פרט ששווה לעצור עליו. קובץ ה-README של הערכה טוען שיכולת ה-shell דורשת הפעלה מפורשת דרך משתנה סביבה בשם PEEP_NM_SHELL, אבל בבדיקת הקוד עצמו SOCRadar מצאו שבשני פרופילי ההרצה base ו-full, כש-base הוא ברירת המחדל, הרצת הפקודות פתוחה בלי סינון. פעולות על קבצים דווקא כן מוגבלות לנתיבים מסוימים. הפקודות לא.

מה שהגשר הזה לא נותן הוא הסלמת הרשאות. הכול רץ בהקשר של המשתמש שהדפדפן פתוח אצלו. מצד שני, מכיוון שהלוגיקה יושבת בתוך תהליך הדפדפן החתום, כלי EDR שמחפשים קובץ הרצה חדש או לא חתום לא רואים כאן שום דבר חריג. וזה בדיוק מה שהופך את ה-endpoint הזה לנוח כל כך.

מה נאסף, וכל כמה זמן

הסוכן פונה לשרת השליטה והבקרה (C2, השרת שממנו התוקף מושך פקודות ואליו הוא שולח את השלל) כל 30 שניות, ב-HTTP רגיל בלי הצפנה, מול כתובת IP קשיחה בקוד: 206.237.30.232, ב-AS55933 של Cloudie Limited בהונג קונג. הזהות של הסוכן נשלחת בשתי כותרות HTTP ייעודיות, X-PEEP-Agent-Key ו-X-PEEP-Agent-Id. המסלולים עצמם ספורים: api/register להרשמה, api/commands למשיכת משימות, api/exfil להוצאת מידע, ועוד שניים לדיווח חיים ולהחזרת תוצאות.

קובץ ההגדרות agent_config.json מונה 37 פקודות. חלקן רצות בתוך הדפדפן: צילום מסך, העתקת מבנה הדף, חילוץ של localStorage ו-sessionStorage, הזרקת JavaScript לדף פתוח, ושינוי הגדרות ה-proxy של Chrome. אחרות עוברות דרך הגשר אל המחשב. ובכל מחזור פעימה נאספות אוטומטית, בלי שאף אחד מבקש, העוגיות, ההיסטוריה והלשוניות הפתוחות.

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

וגם קצב הפעימה הוא שאיפה ולא הבטחה. Manifest V3 משעה service workers ברקע כשהם לא בשימוש, ולכן 30 השניות שהקוד מבקש הן יעד שהדפדפן לא בהכרח מכבד.

מי עומד מאחורי זה, ומה אי אפשר להגיד

חלק ניכר ממה שידוע על PEEP ידוע רק מפני שהמפעיל השאיר ספרייה פתוחה לרשת. על פורט 5002, לצד שרת ה-C2 שיושב על 5001, נמצאה תיקייה חשופה לגמרי עם 38 ארכיוני ZIP של הערכה, מגרסה v9 ועד v29, קוד מקור, לוגים של בדיקות, וגם מפתח החתימה הפרטי של התוסף. כל 38 החבילות כללו את extension.pem, כלומר כל מי שהגיע לספרייה הזאת יכול לחתום עדכונים בשם אותה זהות תוסף. והמספרים נשמעים גדולים ממה שהם: 38 העותקים של nm_host.exe זהים זה לזה. זאת בנייה איטרטיבית של אותו כלי, לא 38 קמפיינים.

הרמזים לזהות המפעיל חלקיים. קובץ בדיקות בשם CHROME150-LIVE-RESULT.md, שמתעד ריצה על Windows עם Chrome בגרסה 150.0.7871.187, כתוב בסינית מסורתית. גם ממשק ההתחברות ללוח הבקרה כתוב בסינית מסורתית, תחת כותרת שמשחקת הומופונית על המילה hacker. נתיבי הקומפילציה של nm_host.exe מפנים לתיקיית משתמש בשם runneradmin, שם המשתמש של מכונות Windows ב-runner-ים של GitHub, כלומר הכלי נבנה בצנרת אוטומטית ולא על תחנת עבודה. SOCRadar לא מייחסים את הכלי לקבוצה מוכרת, למדינה או לארגון פשיעה, ומציינים שלא נמצאו כינויי מפתחים, כתובות דואר, תעודות חתימה או ארנקי קריפטו.

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

אותה זהירות חלה על היקף ההדבקה, ושווה לשים לב אליה. ה-endpoint שנקרא health, שהיה פתוח בלי אימות, הראה בצילום מצב אחד 34 רשומות סוכן, 10 הפעלות פעילות ו-507 רשומות מידע. SOCRadar מדגישים שאי אפשר להפריד במספרים האלה בין מכונות נגועות אמיתיות לבין רשומות בדיקה של המפתח עצמו. אז לא, אלה לא 34 קורבנות מאומתים.

מה זה אומר בפועל

ההגנה כאן היא לא ברמת המייל או הקישור אלא ברמת מדיניות הדפדפן. אם אתם מנהלים צי תחנות ארגוני, רשימת היתר לתוספים דרך Group Policy היא היחידה שעומדת מול טכניקת ההתקנה הזאת, מפני שהיא לא נשענת על החתימות שהתוקף יודע לחשב לבד. שני מקומות נוספים ראויים לניטור ולרוב לא מנוטרים: כתיבות לקובץ Secure Preferences בפרופילי Chrome ו-Edge, ומפתחות הרישום של NativeMessagingHosts. תוכנה שנרשמת שם מבקשת רשות לדבר עם הדפדפן, וזה אירוע נדיר מספיק כדי להצדיק התראה. SOCRadar פרסמו רשימת מזהים לחסימה.

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