הפלאגין בדק את סוג הקובץ שהועלה, ולא את הנתיב שאליו כתב אותו: החולשה ב-Bricksforge מותקפת מ-63 כתובות
ב-7 באוקטובר, בשעה 21:47 לפי שעון UTC, נרשמה בטלמטריה של Patchstack הבקשה הראשונה. היא לא ניסתה לנחש סיסמה ולא חיפשה עמוד התחברות. היא ביקשה מספר חד-פעמי מ-endpoint של פלאגין וורדפרס שמחלק אותו לכל מי שפונה אליו, בלי לבדוק מי זה. אחריה הגיעו עוד, ועד פרסום הניתוח ספרה החברה 63 כתובות IP שונות שתקפו את אותה חולשה.
החולשה מסומנת CVE-2026-85097 והיא נמצאת ב-Bricksforge, הרחבה מסחרית לבונה האתרים Bricks שמוסיפה לו רכיבי טפסים ואוטומציות. היא מאפשרת למי שאין לו שום חשבון באתר להעלות קובץ PHP ולהריץ אותו על השרת, וזה בפועל כל מה שצריך כדי לקבל שליטה מלאה. על חומרת הציון יש מחלוקת: Patchstack נותנת 10.0, והרשומה הרשמית ב-NVD, שהוקצתה על ידי Wordfence בתפקידה כגוף שמנפיק את ה-CVE, נותנת 9.8 בווקטור AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H. בהמשך נראה מה הפלאגין בדק, מה הוא לא בדק, מי תוקף אותו עכשיו, ולמה דווקא בשאלה הפשוטה איזו גרסה מתקנת את זה אין כרגע תשובה אחת.
מה Bricksforge עושה, ולמה הטפסים הם המקום הרגיש
Bricks הוא בונה אתרים פופולרי לוורדפרס, ו-Bricksforge היא הרחבה שנמכרת אליו ומוסיפה לו יכולות שאין לו מהקופסה. הרכיב הרלוונטי כאן נקרא Pro Forms, והוא מה שמאפשר לבנות באתר טופס שאפשר לצרף אליו קבצים: טופס יצירת קשר שמקבל צילום מסך, טופס גיוס שמקבל קובץ קורות חיים, טופס תמיכה שמקבל חשבונית. כל מקום שבו גולש אנונימי יכול לדחוף בייטים לדיסק של השרת הוא מקום שדורש בדיקה הדוקה, ולכן רכיבי העלאת קבצים הם מהאזורים שחוזרים שוב ושוב ברשומות החולשות של וורדפרס.
פרט אחד מיומן הגרסאות של Bricksforge ראוי לתשומת לב מיוחדת, כי הוא מרחיב את מספר האתרים שצריכים לדאוג: לפי היצרן, הבעיה נוגעת לכל אתר שבו Pro Forms פעיל, גם אם אין בו בכלל שדה להעלאת קבצים. במילים אחרות, מי שחשב שהוא מחוץ לתמונה כי לא בנה טופס עם צירוף קובץ, לא בהכרח מחוץ לתמונה.
הבדיקה נעשתה פעם אחת, במקום הלא נכון
כשגולש מעלה קובץ לטופס, הפלאגין עושה בדיוק את מה שצריך: הוא בודק את סוג התוכן של הקובץ, מוודא שמדובר בתמונה, ושומר אותו בתיקיית ביניים. הבדיקה הזאת עובדת, ו-NVD טורחת לציין אותה במפורש. הבעיה מתחילה בשלב הבא. כשהטופס נשלח בפועל, הפלאגין לוקח מהדפדפן לא רק את הנתיב של הקובץ שנשמר אלא גם שדה בשם url, שאומר לאן התוכן אמור להיכתב, והשדה הזה מגיע מצד הגולש ולא נבדק בכלל.
מכאן השרשרת קצרה. התוקף מעלה קובץ שהוא בו-זמנית תמונת GIF תקינה וגם קוד PHP, מה שקוראים לו polyglot: הבייטים הראשונים שלו הם כותרת GIF חוקית, ולכן בדיקת סוג התוכן מאשרת אותו בתור תמונה, והקוד יושב אחריה בתוך אותו קובץ. הקובץ נכנס לתיקיית הביניים כתמונה לכל דבר. ואז נשלח הטופס, כשהוא מצביע על אותה תמונה מאושרת בתור המקור, ובשדה היעד רשום שם קובץ שמסתיים ב-php. הפלאגין מעתיק את התוכן ליעד שהתבקש, השרת מפרסר את מה שנמצא שם כ-PHP ברגע שמישהו פונה לכתובת, והקוד של התוקף רץ.
נשאר רק חלק אחד, וזה החלק שהופך את החולשה לכזו שלא דורשת שום חשבון. וורדפרס מגן על שליחת טפסים בעזרת nonce, ערך חד-פעמי שנועד לוודא שהבקשה יצאה מהעמוד האמיתי ולא מאתר זר. Bricksforge מחזיק endpoint בשם bricksforge_regenerate_nonce שמייצר nonce תקין ומחזיר אותו למי שביקש, בלי לאמת אותו. אז התוקף פונה לשם, מקבל את ה-token, וממשיך. ההגנות היו במקום. הן פשוט שמרו על הדבר הלא נכון.
רוב הבקשות שנרשמו הלכו ל-POST /wp-json/bricksforge/v1/form_submit, ואחת הגיעה דרך admin-ajax.php עם הפעולה bricksforge_form_submit.
אז מה בעצם נראה בטלמטריה?
Patchstack מחלקת את מה שראתה לשני אשכולות שנראים שונה לגמרי זה מזה. הראשון הוא עבודה של סקריפט: 44 כתובות IP שלחו 56 בקשות עם מטען זהה, בהפרש של שניות זו מזו. השני מעניין יותר. שלוש כתובות התמקדו באותו קובץ ביניים בודד וניסו עליו 25 וריאציות של סיומות וקידודים, בין היתר סיומות PHP חלופיות כמו php5, phtml ו-phps, שינויי רישיות, וסיומות מקודדות וכפולות-קידוד. לצד זה שונו או הושמטו השדות path, name, originalFilename ו-url עצמם. מישהו שם בדק איזו סיומת השרת יריץ ואיזו חוקי ההגנה יחסמו, וזו התנהגות של ידיים על המקלדת, לא של כלי מהמדף.
המטענים עצמם עקביים למדי: ב-95 אחוזים מהבקשות שנתפסו הנתיב בצד השרת הסתיים ב-gif או ב-png, ורובם הצביעו על התיקייה /wp-content/uploads/bricksforge/tmp/. חלק מהניסיונות ניסו להשתיל קבצים בשם login_admin ובסיומת php דווקא בתיקיית ההעלאות הרגילה של החודש, /wp-content/uploads/2026/10/, כלומר במקום שבו קובץ נוסף לא בולט.
התשתית מעורבת: מרכזי נתונים, ענן, שירותי פרוקסי ו-VPN, וגם ספק אינטרנט ביתי. שש הכתובות הפעילות ביותר אחראיות לכ-46 אחוזים מהבקשות. אחת מהן, כתובת ב-Azure, נושאת יותר מ-1,270 דיווחי שימוש לרעה ב-AbuseIPDB. החריגה היא כתובת על ספק קווי ברזיל שכמעט אין לה היסטוריה של דיווחים, מה שמתאים או למכונה שנפרצה או למי ששכח להתחבר לפרוקסי. את הייחוס עצמו Patchstack לא עושה: לדבריה התבניות מצביעות על הרצה אוטומטית מעל פרוקסי מתחלפים או תשתית מבוזרת, אבל הן "אינן מספיקות בפני עצמן כדי לייחס את הפעילות לגורם תקיפה אחד". החברה הוסיפה שהיא ממשיכה לעקוב אחרי הקמפיין בחיפוש אחר וריאציות מטען וניסיונות עקיפה חדשים.
ואיזו גרסה מתקנת את זה?
כאן מתחילה אי-בהירות שכדאי להכיר לפני שאתם מריצים עדכון. Patchstack כותבת שהחולשה נסגרה בגרסה 3.1.8.10, ומצביעה על כל הגרסאות עד 3.1.8.9 ועד בכלל כפגועות. אבל ביומן הגרסאות הפומבי של היצרן אין בכלל רשומה לגרסה 3.1.8.10. הגרסה האחרונה שמופיעה שם היא 4.0.1, שיצאה ב-8 באוקטובר, יום אחרי תחילת ההתקפות, והשורה שמתלווה אליה אומרת שתוקנה בעיית אבטחה בהעלאת הקבצים של Pro Forms, שהיא נוגעת לכל אתר שבו הרכיב פעיל, ושפרטים מלאים יפורסמו אחרי הגילוי המתואם. לפניה, 4.0.0 יצאה ב-17 בספטמבר ו-3.1.8.9 ב-28 באוגוסט.
ההסבר הסביר הוא ש-3.1.8.10 היא תיקון שהוחזר לקו 3.x ולא תועד בעמוד הפומבי, והסיקור ב-The Hacker News אכן מפנה את הקוראים לשתי הגרסאות בלי להסביר את הפער. מה שכן, אין בזה שום הכרעה מאומתת, ולכן ההוראה המעשית היא לעדכן לגרסה הזמינה הגבוהה ביותר בחשבון הרישיון שלכם ולא לחפש מספר ספציפי שאולי לא קיים שם בכלל.
מה קורה אחרי שהקוד רץ, ולמה עדכון לא מנקה אתר
חולשה שמאפשרת הרצת PHP שרירותי היא בסך הכול הדלת. מה שעובר בה היום מתועד היטב בחקירה נפרדת של Patchstack מאותו שבוע, שעוסקת בקמפיין אחר לגמרי בוורדפרס ומראה כמה רחוק הולכת ההשתרשות. שם שתי חולשות XSS מאוחסן בלתי מקושרות, CVE-2026-93836 ב-WPC Product Bundles for WooCommerce ו-CVE-2026-94504 ב-Ninja Forms, שימשו להגשת אותו קובץ JavaScript בדיוק, והוא נצפה לראשונה ב-4 וב-5 באוקטובר בהתאמה.
הקוד הזה לא גונב את ה-cookie של המנהל. הוא רץ בדפדפן של מנהל מחובר, בהקשר האבטחה של האתר עצמו, ולכן כל בקשה שהוא שולח לאזור הניהול נושאת את ההרשאות שלו ממילא. הוא טוען עמודי ניהול, מחלץ מהם את ה-token-ים שוורדפרס דורש לפעולות אמיתיות, ומשתמש בהם כדי להתקין פלאגין משלו. סימון cookie כ-HttpOnly לא עוזר כאן בכלל, כי שום דבר לא קורא את ה-cookie.
מה שהפלאגין הזדוני משאיר אחריו הוא השיעור האמיתי. לפי Patchstack הוא יוצר מנהל גלוי, ולידו מנהל נוסף שמוסתר מהמנהל האמיתי של האתר: שם המשתמש נשלף מרשימה של כחמישים מילים תפעוליות שגרתיות כמו support, updater, maintenance ו-backup, ו-mu-plugin שנכתב לתיקייה שנטענת בכל בקשה דואג שהחשבון לא יופיע ברשימת המשתמשים ואף לא ייספר בסכימות שמעליה. ומעבר לשני החשבונות נוצרת כתובת התחברות עם token, שקשור דווקא למנהל הוותיק ביותר באתר ולא לחשבון המוסתר, כך שמי שמחזיק בכתובת נכנס בזהות הבעלים המקורי. הקבצים שנשתלו מקבלים חתימת זמן של הקובץ הישן ביותר ששרת האתר מצא, כדי שלא יבלטו בחיפוש אחר שינויים אחרונים.
המשמעות המעשית חדה: לפי החקירה נשארות לתוקף ארבע דרכי חזרה, ורק אחת מהן נראית בלוח הבקרה של וורדפרס. הסרת הפלאגין הפגיע, ואפילו הסרת הפלאגין הזדוני, לא סוגרת את שלוש האחרות.
מה זה אומר בפועל
אם אתם מריצים אתר על Bricks עם Bricksforge, העדכון הוא דחוף ולא נדחה למחר, כי הניצול התחיל ב-7 באוקטובר והוא אוטומטי ורחב ולא ממוקד בכם במיוחד. אחרי העדכון צריך לבדוק אם הייתם חשופים לפני שהוא הותקן: חפשו בלוגים בקשות ל-/wp-json/bricksforge/v1/form_submit שמכילות את הפרמטר temporaryFileUploads, במיוחד כאלה שמצביעות על קובץ תמונה ומבקשות יעד בסיומת PHP, וחפשו קריאות ל-bricksforge_regenerate_nonce שאחריהן העלאה ושליחת טופס. בצד הקבצים, קובץ PHP שלא אמור להיות שם בתוך /wp-content/uploads/bricksforge/tmp/ או בתיקיית ההעלאות של החודש, ובמיוחד כזה בשם login_admin, הוא ממצא ולא הפתעה.
ואם מצאתם משהו, אל תעצרו ברמת הפלאגין. בדקו את תיקיית ה-mu-plugins, שלא מוצגת בכלל במסך הפלאגינים ולא ניתן לכבות אותה משם, והשוו את רשימת המנהלים שמופיעה בממשק מול שאילתה ישירה למסד הנתונים. בדיוק הפער בין שתי הרשימות האלה הוא מה שהתוקפים בונים עליו.
תגובות