דילוג לתוכן
  • דף הבית
  • קטגוריות
  • פוסטים אחרונים
  • משתמשים
  • חיפוש
  • חוקי הפורום
כיווץ
תחומים

תחומים - פורום חרדי מקצועי

💡 רוצה לזכור קריאת שמע בזמן? לחץ כאן!
  1. דף הבית
  2. תכנות
  3. ניתוח חולשת PwnKit

ניתוח חולשת PwnKit

מתוזמן נעוץ נעול הועבר תכנות
3 פוסטים 1 כותבים 508 צפיות
  • מהישן לחדש
  • מהחדש לישן
  • הכי הרבה הצבעות
התחברו כדי לפרסם תגובה
נושא זה נמחק. רק משתמשים עם הרשאות מתאימות יוכלו לצפות בו.
  • yossizY מנותק
    yossizY מנותק
    yossiz
    כתב ב נערך לאחרונה על ידי yossiz
    #1

    ניתוח חולשת PwnKit

    הקדמה

    ביום שלישי השבוע פירסמו חברת Qualys על חולשה ברכיב נפוץ בהרבה הפצות לינוקס שמאפשר לכל משתמש במערכת לקבל הרשאות רוט. החולשה קיבלה את השם PwnKit - הרכבה של שם הרכיב הפגיע (Polkit) והמילה Pwn שהוא סלנג לפריצה.

    מה שמעניין, לדעתי, בחולשה זו יותר מחולשות אחרות שמתפרסמות יום יום, זה העובדה שלמרות שמדובר בחולשה מסוג memory corruption כאשר בד"כ חולשות מסוג זה הם קשים יותר להבנה למי שלא עמוק בתחום, כאן אפשר עם קצת מאמץ להבין את החולשה והמימוש של האקפלויט מא' עד ת'. תעיד על זה העובדה שאפשר למצוא נכון להיום כ-80 פרוייקטים בגיטהאב שעוסקים בחולשה זו.

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

    רקע

    setuid bit

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

    אחת מהמשתנים המרכזיים שמשפיעים על ההחלטה אם לאפשר או לסרב, זה "מה רמת ההרשאות של התהליך שמבקשת גישה?"

    במערכות *NIX (שם כללי לסוגי היוניקס למיניהם, כולל לינוקס), לכל תהליך מוצמד מזהה של היוזר שמריץ את התהליך, וזה קובע את רמת ההרשאות של התהליך.

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

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

    ואיך עובד הקסם הזה של sudo שפתאום אתה מצליח להסלים הרשאות? לשם כך המציאו את ה-setuid bit. זה סה"כ פיסת מידע קטן שמוצמד לקובץ הבינארי של פקודת sudo שאומר למערכת ההפעלה שכאשר מישהו מריץ פקודה זו, תן לפקודה הראשות רוט. (כמובן, רק מי שהוא כבר רוט, יכול להוסיף פיסת מידע זו לקובץ, אחרת כל אחד יוכל להסלים הראשות)

    מנגנון זה הוא חרב פיפיות, מצד אחד זה מאפשר למשתמש רגיל לנהל את המחשב, מצד שני אנחנו לא רוצים לתת אפשרות לתהליך לא רצוי להסלים הרשאות. לשם כך, יש הרבה בדיקות וגדרים בתוך הקוד של sudo שמוודא שרק מי שמורשה יכול להשתמש בו. מכיון שכן, הקוד של כל בינארי שיש לו את ה-setuid bit חייב להיות מאוד מאובטח, ובלי באגים.

    משתני סביבה "מסוכנים"

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

    כאשר אנחנו מריצים תוכנה עם ה-setuid bit אנחנו רוצים שליטה מלאה על הקוד שרץ, ולא רוצים להריץ קוד אקראי בצורה לא מבוקרת. לשם כך, לפני הרצת התוכנה, מערכת ההפעלה "מנקה" את משתני הסביבה של התהליך, ומאפשרת רק משתני סביבה "מאובטחים" ולא "מסוכנים".

    Polkit ופקודת pkexec

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

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

    מכיון שהפקודה צריכה להסלים הראשות, יש לפקודה את ה-setuid bit.

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

    נמשיך כעת לחולשה עצמה!

    (מכאן והלאה דרוש קצת הבנה בתכנות)

    החולשה

    argc & argv

    כידוע, פקודות שמורצים במערכת הפעלה יכולים לקבל פרמטרים ששולטים על פעולת הפקודה. זה עובד בצורה כזו שמי שמריץ את הפקודה (בד"כ ה-shell, אבל זה יכול להיות כל תהליך) מבקש ממערכת ההפעלה להריץ תהליך חדש (פונקציית execve). פוקנציה זו מקבלת שלוש ארגומנטים, הראשון הוא נתיב לקובץ ה-exe של הפקודה. השני זה מערך של מחרוזות כאשר האבר האחרון במערך זה הוא NULL pointer, כל אבר במערך זה מצביע על מחרוזת של פרמטר שאתה רוצה להעביר לפקודה. זה נקרא argv (כלומר arg vector כאשר vector זה שם נרדף למערך). השלישי זה מערך נוסף של מחרוזות שנקרא envp שמכילה את משתני הסביבה שאתה רוצה להגדיר עבור התהליך.

    המילים "מערך של מחרוזות" טעונים ביאור, כי מי שמשתמש בשפות "נורמליות" יבין את הדברים בצורה לא נכונה. ביוניקס, וכל API/ABI מבוססת שפות C/C++ הכוונה במילים אלו הוא כזה:

    קודם כל נקדים כמה מושגים בסיסיים:

    מצביע (pointer) = unsigned int (= מספר חיובי) בגודל של מספר הסיביות של המעבד, שמצביע על כתובת במרחב הזכרון של התהליך

    NULL pointer = מצביע עם הערך של 0, זה מסמן "משהו שלא קיים".

    מערך = זה פשוט "מצביע" (כנ"ל) שמצביע על איזור זיכרון שמאכסנת אובייקט אחד או יותר ברצף (כל האובייקטים הם מאותו סוג ובגודל זהה, האורך של המערך לא ידוע, כלומר זה לא מקודד איפשהו ב"מערך" דהיינו ה"מצביע", במקרה שלנו ה-NULL pointer בסוף הוא זה שמסמן את סוף המערך)

    מחרוזת = "מצביע" (כנ"ל) על איזור בזכרון שמאחסנת רצף של 0 או יותר תווים, ואחריהם NULL (בייט עם הערך 0) שזה מסמן את סוף המחרוזת

    ובכן מה זה "מערך של מחרוזות"?

    מתרגמים את זה ככה: תעביר מצביע שמצביע על רצף של מצביעים כאשר המצביע האחרון הוא NULL, וכל אחד ממצביעים אלו מצביעים על רצף של תווים שאחריהם מגיע תו 0.

    מערך הפרמטרים מקובל לקרוא לו argv (vector זה שם נרדף למערך) וזו הצורה להעביר ארגומנטים לתהליכים.

    מערכת ההפעלה לוקחת המערכים אלו ומעתיקה אותם למרחב הזכרון של התהליך החדש.

    פונקציית main

    בתהליך החדש, הפונקציה הראשית (שנקרא בד"כ main) מקבלת כארגומנטים שני פיסות מידע, א) argc - זה int שערכו הוא מספר הפרמטרים שבתוך argv ב) argv שזה כנ"ל מצביע על מערך של מצביעים למחרוזות.

    argv[0]

    מקובל שהמחרוזת הראשונה במערך argv זה תמיד שם הקובץ של ה-exe. וכן הוא באמת כאשר מריצים תהליך דרך ה-shell או בדרכים מקובלות אחרות. אבל חשוב להבין שזו רק מוסכמה. אפשר בהחלט להריץ תהליך כאשר המחרוזת הראשונה זה "foobar" או NULL. (במקרה של NULL, ה-argc יהיה 0, ו-argv יצביע על מערך עם אבר אחד שערכו הוא 0)

    הקוד הפגיע

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

    435 main (int argc, char *argv[])
    436 {
    ...
    534   for (n = 1; n < (guint) argc; n++)
    535     {
    ...
    568     }
    ...
    610   path = g_strdup (argv[n]);
    ...
    629   if (path[0] != '/')
    630     {
    ...
    632       s = g_find_program_in_path (path);
    ...
    639       argv[n] = path = s;
    640     }
    

    מה אנחנו רואים פה?

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

    בשורה 435 יש הצהרה על פונקצית ה-main שמקבלת שני ארגומנטים (כנ"ל). מדלגים על כמה שורות לא קשורות, ובשורה 534 המתכנת רוצה לטפל בדגלים שמגיעים לפני הפקודה עצמה. אז הוא עובר בלולאה על הפרמטרים, בגוף הלולאה (לא מופיע פה) יש תנאי עצירה על הפרמטר הראשון שלא מתאים לשום דגל. מה שחשוב להבין הוא שכאשר יוצאים מהלולאה, הערך של n שווה לפרמטר הראשון שלא מתאים לשום דגל, כאשר זה יכול להיות גם ה-NULL שמסמן את סוף הפרמטרים. (כך חשב לעצמו המתכנת. האומנם זה נכון? נראה בהמשך...).

    שוב נדלג על כמה שורות לא מעניינות, ונגיע לשורה 610, ובו המתכנת מעתיק את המחרוזת שעליה מצביע argv[n] והוא מקבל חזרה מצביע שיצביע על המיקום של המחרוזת המועתקת. שוב מדלגים עד שורה 629 ובה אנחנו בודקים אם התו הראשון המחרוזת לא / (כלומר זה לא נתיב אבסוטלוטי, אלא נתיב יחסי או שם של פקודה בלי נתיב) ואז נצטרך לחפש ב-PATH אם קיימת פקודה עם שם זה. בשורה 632, המשתנה s מצביעה על מחרוזת חדשה שמכילה את הנתיב לפקודה ש-g_find_program_in_path מצאה. בשורה 639 (כנראה אחרי כמה בדיקות) המצביע s נכנסת ל-argv[n] במקום במצביע הקודם.

    בשורות הבאות כנראה התוכנה תבדוק אם להריץ או לא את הפקודה שמאוכסנת במחרוזת זו.

    הבאג

    איפה הבאג פה?

    תחשבו לעצמכם מה יקרה אם הערך של argc הוא אפס. הרי אפשר להריץ תוכנה עם מערך מחרוזות ריקה כנ"ל. מה יהיה הערך של n במקרה כזה? הוא יהיה 1. כי בתחילת הלולאה איתחלנו אותו ל-1, וגוף הלולאה לא הרצנו כי התנאי n < argc לא התקיים, אז n נשאר 1.

    על מה יצביע argv[n]? הוא יצביע על הערך שאחרי סוף המערך. כי הרי argv[0] יצביע על הערך היחיד שנמצא במערך שזה ה-NULL pointer ו-argv[1] יגלוש מחוץ למערך לערך הבא.

    ומה באמת נמצא שם? בד"כ מערכת ההפעלה שמה שם את המערך envp שנתקלנו בו למעלה בתיאור של פונקציית execve.

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

    אם עקבת עד כאן, אז א) כל הכבוד! וב) הבנת איך קיבלנו את היכולת לשלוט על אחד ממשתני הסביבה של התהליך באמצעות באג זה.

    בפוסט הבא (בעז"ה אם יהיה כח) ננסה להסביר איך אפשר לנצל עובדה זו להריץ תוכנה אקראית כרוט.

    📧 יוסי@מייל.קום | 🌎 בלוג | ☕ קפה

    תגובה 1 תגובה אחרונה
    30
    • yossizY yossiz התייחס לנושא זה ב
    • yossizY מנותק
      yossizY מנותק
      yossiz
      כתב ב נערך לאחרונה על ידי yossiz
      #2

      פרק ב - מבאג לאקספלויט

      (אקספלויט = תוכנה שמנצלת חולשה)

      תקציר

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

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

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

      אז איך ננצל את החולשה כדי להריץ קוד אקראי שלנו?

      (אגב, יש מישהו שטוען שהוא עלה על הבאג כבר בשנת 2013, אבל לא מצא את הדרך איך לנצל אותו. עיין כאן העתק של מייל שהוא כתב לפרוייקט polkit בנושא, לא ידוע למה התעלמו ממנו)

      משתני סביבה מסוכנים

      התשובה: רמזנו כבר למעלה, יש משתני סביבה "מסוכנים" שמערכת ההפעלה מנקה לפני הרצת תוכנה עם setuid. אם נוכל להזריק שוב לתוך הסביבה משתנה מסוכנת, נוכל לנצל אותה כדי להריץ קוד אקראי.

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

      GCONV_PATH

      הרכיב שאחראי על טעינת תוכנות לזכרון והכנתם להרצה בלינוקס הוא ld.so, בתיעוד של הרכיב (man ld.so או כאן) ניתן למצוא רשימה של משתני סביבה מסוכנים שהרכיב מנקה לפני הרצת תוכנות עם setuid. בתוכם נמצא את המשתנה GCONV_PATH.

      המשתנה GCONV_PATH מוכרת על ידי ספריית iconv. ספרייה זו נמצאת ברוב ככל מערכות לינוקס (זה חלק מתקן POSIX שמגדיר מה אפשר לצפות ממערכת UNIX-ית) והיא אחראית על המרת טקסט בין קידודים שונים. כאשר תוכנה כלשהי קוראת לפונקציה מתוך ספריית iconv לבקש המרת טקסט לקידוד כלשהו, הספרייה בודקת את משתנה הסביבה GCONV_PATH כדי למצוא את הנתיב לקובץ תצורה. בתוך קובץ זה ניתן להגדיר נתיבים לספרייות קוד שנטענות בצורה דינאמית כדי לבצע את ההמרה. (ע"ע man iconv או כאן)

      g_printerr ומשתנה הסביבה CHARSET

      בקטע הקצר של הקוד מהבאג ועד לניקיון חוזר של משתני הסביבה יש קריאה לפונקציה g_printerr. פונקציה זו היא חלק מספריית glib (ספריית היסוד של GTK ש-polkit הוא חלק ממנה). פונקציה זו (כשמה) מדפיסה שגיאות לקונסול, והיא מכבדת את משתנה הסביבה CHARSET כדי לבחור קידוד להדפסה זו. שינוי הקידוד מהמחרוזת המקורית לקידוד הרצוי מתבצעת על ידי... iconv.

      והנה קטע הקוד (הנוגע לענינינו) שמדפיס את הודעת השגיאה:

       383 validate_environment_variable (const gchar *key,
       384                                const gchar *value)
       385 {
       ...
       406           log_message (LOG_CRIT, TRUE,
       407                        "The value for the SHELL variable was not found the /etc/shells file");
       408           g_printerr ("\n"
       409                       "This incident has been reported.\n");
      

      מה שחשוב להבין היא שהעובדה שמשתנה הסביבה SHELL מצביעה על shell לא חוקי תגרום להדפסת השגיאה, ולקריאת פונקציית iconv.

      עכשיו הדרך לאקספלויט מלא פתוחה לפנינו... 😎

      עוד לא הבנת? זה בסדר, זה מצריך קצת יצירתיות. תעקוב אחרי:

      האקספלויט

      בתור הכנה, נעשה את השלבים הבאים (אח"כ אנסה להסביר):

      • נבחר תיקייה כלשהו כ"תיקיית הבית" של האקספלויט.
      • ניצור תיקייה (בתוך "תקיית הבית" שלנו) בשם GCONV_PATH=.‎ (כן, ה-= וה-. הם חלק מהשם)
      • בתוך תיקייה זו נשים קובץ EXE כלשהו (כלומר, קובץ שיש לו הרשאות ריצה). לא משנה איזה. נקרא לקובץ שם כלשהו, לצורך הענין נבחר בשם "xxx" ונוסיף את התווים ‎:.‎‎ בסוף השם. השם המלא יוצא: xxx:.‎ (ההסבר יבוא)
      • ניצור קובץ קינפוג ל-iconv ב"תיקיית הבית" שלנו. בתוך הקובץ יש שורה אחת שאומרת ל-iconv שכדי להמיר קידוד UTF-8 לקידוד (שהמצאנו לצורך הענין) "PWNKIT" צריך לטעון את הקוד של ספרייה בשם "pwnkit.so". (השורה נראית משהו כזה: module UTF-8// PWNKIT// pwnkit. לעוד פרטים עיין בתיעוד). נקרא לקובץ בשם iconv_modules
      • ניצור קובץ בינארי (ספרייה - מה שנקרא DLL בעולם הווידוס) בתוך "תקיית הבית" שלנו, ונקרא אותו בשם pwnkit.so. הספרייה הזו מתחזה כמודול של iconv (ז.א. הוא מממש את הפונקציות gconv_init ו-gconv) בתוך הקוד של פונקציית gconv_init נוכל להריץ קוד אקראי עם הראשות רוט... ☠
      • ניצור עוד תוכנה שמריצה את pkexec עם פרמטרים מיוחדים:
        • argv של אבר אחד שהוא null pointer.
        • envp שכולל מספר ערכים:
          • הראשון: xxx:.‎ (כן, זה לא נראה כמשתנה סביבה. נראה בהמשך מה יקרה עם זה)
          • PATH=GCONV_PATH=.‎
          • SHELL=/i/do/not/exist
          • CHARSET=PWNKIT

      טוב, סיימנו את ההכנות, נצא לדרך!

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

      1. נריץ את התוכנה שיצרנו בשלב האחרון של ההכנות
      2. זה מריץ את הקוד של pkexec
      3. כפי בתיארנו בפוסט הראשון, pkexec יטעה, ויחשוב שמשתנה הסביבה הראשונה היא היא שם הפקודה שהעברנו אליה
      4. היא מעבירה את זה לפוקנציה שמחפשת פקודה זו ב-PATH ומחזירה את הנתיב לפקודה (שורה 632 בקטע הקוד בפוסט הראשון)
      5. מכיון שה-PATH שלנו מכילה ערך אחד: GCONV_PATH=.‎, הפוקנציה תחפש תיקייה בשם GCONV_PATH=.‎ ובתוכה קובץ בשם: xxx:.‎
      6. הפונקציה תמצא את הקובץ שהכנו, והיא תחזיר לתוכנה את הנתיב אליה: GCONV_PATH=./xxx:.‎
      7. pkexec תיקח תוצאה זו ותכניס אותה חזרה ל... משתנה הסביבה הראשונה. יוצא שהצלחנו להזריק משתנה הסביבה לא בטוחה לתוך התהליך. משתנה הסביבה נראית כך עכשיו: GCONV_PATH=./xxx:.‎
      8. התוכנה תמשיך לרוץ ומכיון שהגדרנו משתנה SHELL לא חוקית, נגיע להודעת השגיאה...
      9. פונקציית ההדפסה מכבדת את משתנה הסביבה CHARSET שערכו אצלנו "PWNKIT", לכן היא מנסה להמיר את טקסט ה-UTF-8 שבקוד המקור, לקידוד "PWNKIT"
      10. כדי לבצע את ההמרה היא מחפשת את הגדרות iconv לפי משתנה הסביבה GCONV_PATH. משתנה זו אמורה להכיל רשימה של נתיבים מופרדים באמצעות תו :. אצלנו יש שני ערכים ברשימה: ‎./xxx ו-..
      11. הפונקציה מחפשת בשני הנתיבים לקובץ בשם iconv_modules. הנתיב הראשון לא קיים כמובן, אבל השני קיים. ה-. מסמל את התיקייה הנוכחית. בינגו! יש שם קובץ תצורה. בוא נראה מה כתוב:
      12. הופ! כתוב שלהמיר קידוד UTF-8 לקידוד PWNKIT אני צריך לטעון את הספרייה בשם pwnkit, אז בוא נחפש ספרייה בשם זה בתקייה הנוחכית...

      אתם יכולים לנחש את הסוף העצוב של הסיפור...

      ☠

      (קרדיט: נעזרתי בשני מקורות אלו להכנת המאמר:

      • https://www.qualys.com/2022/01/25/cve-2021-4034/pwnkit.txt
      • https://github.com/berdav/CVE-2021-4034)

      📧 יוסי@מייל.קום | 🌎 בלוג | ☕ קפה

      תגובה 1 תגובה אחרונה
      22
      • yossizY מנותק
        yossizY מנותק
        yossiz
        כתב ב נערך לאחרונה על ידי yossiz
        #3

        פרק ג - סיכום ולקחים

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

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

        למתכנתנים

        הלקח למתכנתים ברור:

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

        למתעניינים בסייבר

        נהנית מהמאמר? אולי אתה אוהב את תחום הסייבר?
        תוכל להפיק מכאן כמה לקחים:

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

        אם יש לך מה להוסיף או להעיר, אשמח מאוד לשמוע בתגובות. תודה רבה!

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

        📧 יוסי@מייל.קום | 🌎 בלוג | ☕ קפה

        תגובה 1 תגובה אחרונה
        24
        • dovidD dovid העביר נושא זה מ-תכנות ב-

        בא תתחבר לדף היומי!
        • התחברות

        • אין לך חשבון עדיין? הרשמה

        • התחברו או הירשמו כדי לחפש.
        • פוסט ראשון
          פוסט אחרון
        0
        • דף הבית
        • קטגוריות
        • פוסטים אחרונים
        • משתמשים
        • חיפוש
        • חוקי הפורום