לקוח מזויף שלח לי למייל השבוע מאגר (repository) זדוני ב-GitHub, ופשוט על ידי הרצת סקריפט ההתחלה, הוא מחק יומיים של עבודה וחשף כל סיסמה ששמרתי בדפדפן שלי.
ה"לקוח" פרסם משרה של מהנדס בכיר בשכר גבוה, יצר קשר במהירות ושלח repo שנראה מקצועי מאוד. הבקשה הייתה פשוטה: לעשות clone, להריץ npm run dev, ולשלוח צילום מסך כדי להוכיח שהדמו עובד — ללא חוזה וללא בדיקת רקע. ברגע ששרת הפיתוח עלה, קוד נסתר בקובץ הגדרות יצר קשר עם שרת command-and-control (C2), הוריד payload בשלב שני והחל לשאוב פרטי גישה (credentials) מהמכונה המקומית.
איך המתקפה התרחשה
ה-payload הזדוני התחבא ב-postcss.config.js, קובץ שרוב המפתחים רק מעיטים בו מבט כי הוא בדרך כלל מכיל כמה חוקי עיבוד CSS פשוטים. במקרה הזה, התוקף הוסיף שורה של JavaScript מוסתר (obfuscated) רחוק מאוד מצד ימין של הצהרה לגיטימית, כשהיא מרווחת ברווחים כדי להשתלב בטבעיות. כשפקודת ה-npm run dev הריצה את צינור העיבוד (pipeline) של PostCSS, השורה הנסתרת רצה מבלי שיבחינו בה.
הנוזקה ביצעה שלושה שלבים ברצף מהיר:
- יצירת קשר עם C2 – היא פתחה חיבור רשת לשרת שנשלט על ידי התוקף ודיווחה על המארח (host) שנפרץ.
- הורדת שלב שני – היא משכה קוד נוסף שהכיל את הלוגיקה האמיתית של גניבת הנתונים (data-exfiltration).
- גניבת פרטי גישה מהדפדפן – ב-macOS, היא שאלה את מפתח ה-Chrome Safe Storage השמור ב-keychain של המערכת. אם המשתמש אישר את הודעת ה-keychain, התוקף גבה כל סיסמה שנשמרה ב-Chrome.
מעבר לגניבה המיידית, ה-payload כתב את עצמו לתוך מספר כלי פיתוח נפוצים — VS Code, npm, Discord — כך שכל הפעלה עתידית של האפליקציות הללו הפעילה מחדש את הקוד הזדוני. הפעלה מחדש (reboot) פשוטה לא ניקתה את הזיהום; ה-npm install הבא או פתיחת העורך הקימו מחדש את ה-backdoor.
נורות אדומות שלרוב עוברות מתחת לרדאר
- בקשות להריץ קוד לפני שנחתם חוזה כלשהו. תהליכי גיוס לגיטימיים כוללים בדרך כלל הסכם רשמי לפני שמשתפים עבודה קניינית כלשהי.
- קבצים דחוסים המתחזים ל"תקציר פרויקט" (project briefs). ארכיבי Zip או RAR יכולים להסתיר סקריפטים ניתנים להרצה או קבצים בינאריים זדוניים.
- בקשות לכתובות אימייל אישיות כדי "לעקוף מסננים של הפלטפורמה". התחבבות אלו נועדו להעביר את השיחה מחוץ לפלטפורמה המוגנת, שבה ניתן לדווח על הפרות.
- תיאורי משרה שמבקשים מהמועמד לממן ארנק קריפטו או לרכוש טוקנים לבדיקה. דרישות כאלה אינן אופייניות לעבודת פיתוח אמיתית.
צעדים מעשיים כדי להישאר מוגנים
- לעולם אל תריצו קוד של אדם זר ללא בדיקה. פתחו את ה-repository בתצוגת קריאה בלבד (למשל, דרך תצוגת ה-raw ב-GitHub) וסרקו כל סקריפט, במיוחד קבצי הגדרות וערכי
scriptsב-package.json. - התייחסו לכל הקבצים המצורפים כטקסט פשוט. אם נשלח קובץ zip, חלצו אותו בסביבת sandbox ובדקו את התוכן לפני שפותחים משהו.
- השתמשו במנהל סיסמאות ייעודי במקום באחסון של הדפדפן. גם אם ה-keychain של הדפדפן נפרץ, הכספת של מנהל הסיסמאות נשארת מבודדת.
- הריצו קוד לא מהימן במכונה וירטואלית מבודדת או ב-container ללא גישה לרשת. זה חוסם את יכולתו של התוקף להגיע לשרת C2.
- הפעילו אימות דו-שלבי (2FA) בכל החשבונות. אם סיסמה נגנבת, הגורם השני ימנע כניסות לא מורשות.
- שמרו על כלי הפיתוח מעודכנים והפעילו בדיקות תקינות (integrity checks) אוטומטיות במידת האפשר. עורכים מסוימים מתריעים כיום כאשר קבצי ליבה משתנים באופן בלתי צפוי.
אם אתם חושדים שהרצתם קוד זדוני, הניחו שהמערכת נפרצה. גבו נתונים חיוניים, מחקו את הכונן והתקינו מחדש את מערכת ההפעלה. הפעלה מחדש פשוטה לא תחסל מנגנון התמדה (persistence mechanism) שכותב מחדש קבצים באפליקציות נפוצות.
בשורה התחתונה: שורה אחת של JavaScript נסתר יכולה להפוך דמו שגרתי למבצע גניבת פרטי גישה מלא. התייחסו לכל repository כאל לא מהימן עד שתאשרו אותו, והפכו בידוד לחלק מובנה מתהליך העבודה שלכם. המחיר של רגע של חוסר זהירות גדול בהרבה מהמאמץ המושקע בבדיקה כפולה של קובץ.
