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

את הרצף הזה תיעדו חוקרי Blackpoint Cyber סם דקר, אנדי אורסרי ונבן ביל, בדוח שפרסמו ב-18 בספטמבר על נוזקת שליטה מרחוק שלא היה לה שם עד עכשיו והם קראו לה ChainScript. הנוזקה כתובה ב-JavaScript ורצה על Node.js שהיא מביאה איתה, היא מגיעה דרך קמפיין ClickFix, והחלק המעניין בה הוא לא מה שהיא עושה על המכשיר אלא איך היא יודעת לאן להתחבר. בהמשך נראה איך היא נכנסת, איפה שמורה כתובת השרת שלה, ולמה דווקא ההחלטה הזאת מקשה על חסימה.

מ-ClickFix ל-MSI שמתחזה ל-Spotify

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

הפקודה הפעילה את msiexec.exe מול api-configuard[.]com, שם פנייה ל-endpoint בשם capher.php עם פרמטר token החזירה את קובץ ההתקנה. הקובץ שנותח, ComponentTask33-4d14e6ac.msi, הציג את עצמו כתוכנה של Spotify AB. שתי הגדרות בתוכו, ALLUSERS=2 ו-MSIINSTALLPERUSER=1, דאגו שההתקנה תרוץ בהקשר המשתמש בלבד. המשמעות המעשית פשוטה: כל השרשרת ממשיכה בלי הרשאות מנהל ובלי חלון אישור שמישהו יכול לעצור בו.

מיד אחרי ההתקנה רץ סקריפט PowerShell מוסתר בשם ._scatter.ps1, שמפזר את הרכיבים לארבע תיקיות שנראות כאילו מיקרוסופט יצרה אותן. סביבת ההרצה של Node.js נחתה תחת %LOCALAPPDATA%\Microsoft\Windows\Libraries\QuickSystemSearch, קוד הסוכן עצמו תחת %APPDATA%\Microsoft\Windows\Themes\SettingsHostStandard58, ההגדרות ומצב הריצה תחת %LOCALAPPDATA%\Microsoft\Windows\INetCache\FilterManager, וכלי העזר תחת %LOCALAPPDATA%\Microsoft\Windows\Shell\RemoteTempPrimary. אחר כך wscript.exe מריץ קובץ VBScript בשם ._agent.vbs, שמפעיל את node.exe המצורף מול app\src\index.js. בלי חלון, בלי קונסולה.

רק אחרי שהסוכן כבר רץ הוא דואג לעצמו לשרידות. סקריפט בשם StreamServiceSharedBridge.ps1 מנסה ליצור משימה מתוזמנת מוסתרת בשם ComponentTask33Agent שתופעל בכל כניסת משתמש ותריץ את אותו ._agent.vbs, ואם יצירת המשימה נכשלת הוא נופל חזרה למפתח Run של המשתמש ברישום, עם אותו שם בדיוק. שתי הדרכים נשארות בהקשר המשתמש ולא דורשות הסלמת הרשאות.

אז איפה שמורה כתובת השרת?

כשהסוכן עולה הוא לא קורא קובץ הגדרות קריא. הוא טוען קובץ בשם HiddenVirtualSilentLoader.dat, מפענח אותו מ-Base64, מריץ XOR מול ערך seed שמגיע ממטא-דאטה של ההתקנה (בבילד שנותח, c8c384083f), ורק אז מפרסר את ה-JSON שיצא. בתוכו נמצאים ה-token שבו הסוכן מזדהה, מרווח של 12 דקות בין אותות חיים, 15 שניות המתנה לפני ניסיון חיבור חוזר, וכתובת שרת אחת שמורה ישירות.

הכתובת הזאת היא לא זאת שבאמת משמשת. לפני שהוא מתחבר, הסוכן שולח שאילתת קריאה לחוזה חכם שמאוחסן על רשת Polygon ומקבל בחזרה מחרוזת. הוא בודק שהיא מתחילה ב-ws:// או ב-wss://, שומר אותה בזיכרון לחמש דקות, ומשתמש בה במקום בערך שבהגדרות. כלומר כתובת השרת הפעיל לא כתובה בתוך הנוזקה בכלל: היא שמורה בבלוקצ'יין ציבורי, והנוזקה רק שולפת אותה משם כל פעם מחדש. לשיטה הזאת קוראים EtherHiding.

הפרטים היבשים, למי שרוצה לחפש: חוזה 0xf9099d0d747368cce8C10226CC9AF2bFD4DDbCF4 ברשת מספר 137, קריאת eth_call עם מזהה פונקציה 0x4ab7874e. מבין הפאנלים שנצפו, פורט 3847 חזר הכי הרבה, ולצידו נראו גם 3851 ו-3854.

מחקר עצמאי שפרסם Justice-Hammer ב-GitHub, ושאותו מצטטים חוקרי Blackpoint, הוסיף פרט שמסביר הרבה על איך הדברים האלה נבנים. החוזה ששימש את הבילד הזה נפרס ב-24 באוגוסט 2026 בשעה 11:20:09 UTC, וקובץ ה-MSI נבנה 23 שניות אחריו, ב-11:20:32. "הסדר נכון מבחינה סיבתית, כי הבנאי צריך את כתובת החוזה לפני שהוא יכול לכתוב את קובץ ההגדרות של הסוכן, והפער קצר מכדי להיות ידני", נכתב שם. המסקנה שהוא מסיק היא שפריסת החוזה היא שלב אוטומטי בקו הבנייה, וכתובת החוזה היא ככל הנראה פריט נפרד לכל בילד.

התשתית התחלפה בזמן שהחוקרים הסתכלו

כדי לראות את זה עובד, צוות המחקר של Blackpoint חיבר סוכן לתשתית החיה ועקב אחרי מה שעובר בקו. בהתחלה החוזה החזיר את shift-api-control[.]com:3847. החיבור החזיק כ-18 דקות של אותות חיים, ואז הגיעה מהשרת משימה מסוג files שביקשה רשימה של הכוננים הזמינים. כעבור כשתים עשרה דקות נוספות החיבור נותק.

מה שקרה אחר כך הוא כל הסיפור. הסוכן פנה שוב לאותו חוזה בדיוק, וקיבל הפעם את bedotiq[.]net:3854. אותו קובץ, אותה לוגיקת חיבור מחדש, שרת אחר. החוקרים מדגישים שהם לא יודעים מה גרם להחלפה, ולא מייחסים לה סיבה, אבל התוצאה ברורה: המפעיל יכול להזיז את כל המכשירים הנגועים לתשתית חדשה בלי לגעת בנוזקה שכבר יושבת עליהם.

(אגב, זה גם מסביר למה הדוח ממליץ במפורש לא לחסום גורף גישה ל-RPC ציבורי של Polygon. בדרך לחסום את זה חוסמים המון תעבורה לגיטימית.)

מה הסוכן יכול לעשות על המכשיר

אחרי החיבור, הסוכן מזדהה מול הפאנל בכותרת X-Agent-Token, בונה לעצמו זהות יציבה משם המחשב ומה-MachineGuid של Windows, ורושם את עצמו עם שם המשתמש, הארכיטקטורה, זמן הפעילות, הזיכרון, מספר המעבדים, כתובת ה-IPv4 המקומית ושם הדומיין או קבוצת העבודה. מכאן זה RAT קלאסי למדי: הפעלת פקודות דרך cmd.exe, הרצת PowerShell, קריאה וכתיבה ומחיקה של קבצים, צילומי מסך שמוחזרים כ-PNG דרך כלי עזר .NET בשם SearchTrustedRuntimeSvc.exe, הורדה של קבצים לתיקיית %TEMP% והרצתם משם, והפצה של מטענים נוספים בפורמט MSI או סקריפט. יש גם פקודת עדכון עצמי שמחליפה רכיבים מתוך קובץ ZIP, ופקודת ניקוי שמוחקת את ה-persistence ואת הקבצים.

שני דברים מבדילים אותו מהממוצע. הראשון הוא shell אמיתי: במקום פקודות בודדות, הסוכן פותח סשן אינטראקטיבי של CMD או PowerShell דרך node-pty, עם תמיכה ב-ConPTY וב-WinPTY, כולל קלט ושינוי גודל חלון. השני הוא היכולת של השרת להרחיב את הסוכן תוך כדי ריצה: רכיב ייעודי מושך קוד JavaScript מהשרת ומריץ אותו בתוך הקשר vm של Node.js, מה שמאפשר להוסיף מטפלי פקודות חדשים שלא היו בבילד המקורי. כשהחוקרים ניסו את הנתיב הזה מול התשתית החיה, השרת החזיר שגיאת 404, כלומר האפשרות לא הייתה פעילה באותו רגע.

נקודה אחת ראויה לדיוק, כי קל לקרוא אותה לא נכון. הפקודה wallet_scan סורקת ארנקי קריפטו מותקנים ותוספי ארנק בדפדפן, אבל היא רק ממפה שמות ונתיבים. החוקרים מציינים שלא מצאו בבילד שנותח יכולת ייעודית לחילוץ seed phrases, מפתחות פרטיים, סיסמאות דפדפן, עוגיות או מידע מוגן DPAPI. זה לא אומר שהמידע הזה בטוח, כמובן, כי גישת ה-shell והקבצים מאפשרת לאסוף אותו ידנית.

אותו סוכן, שמות אחרים

ChainScript לא מופצת תחת שם אחד. החוקרים זיהו בילדים נוספים שמתחזים לתוכנות אחרות: UpdateDigital, שגם הוא משתמש בפיתיון Spotify, HostShared שמציג את עצמו כ-Zoom Workplace, ו-OrchidViolet66 שמתחזה ל-Microsoft Teams. מתחת לשמות, הרכיבים חוזרים על עצמם. אותו ._agent.vbs, אותו app\src\index.js, אותו שימוש ב-MachineGuid לזיהוי המכשיר, ואותו קובץ connect-delay-state.json שמנהל השהיה אקראית של 10 עד 30 שניות לפני החיבור הראשון (בהרצה אחת בסביבת בדיקה נרשמו 24,540 אלפיות שנייה). ההבדל העיקרי היה בפריסת הקבצים: ComponentTask33 פיזר אותם לתיקיות נפרדות, בעוד UpdateDigital השאיר הכול תחת שורש אחד.

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

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

אם אתם אחראים על ניטור בארגון, הסימן הכי שימושי כאן הוא לא כתובת אלא רצף: msiexec.exe שמוביל ל-wscript.exe ולקובץ VBS מתיקיית המשתמש, ואחריו node.exe שמריץ app\src\index.js מתוך %LOCALAPPDATA% או %APPDATA%. שווה גם לחפש node.exe שמפעיל PowerShell כדי ליצור משימה מתוזמנת, ולצליב גישה ל-RPC של Polygon עם חיבור WebSocket יוצא מאותו תהליך. כל אחד מהשניים לבד רועש; ביחד הם כבר סיפור.

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