בתאריך ה-14.10.2019 התפרסמה פגיעות בקוד של אחת הפקודות הנפוצות הקיימות במערכות ההפעלה המבוססות unix. החולשה שקיבלה את שם הקוד : CVE-2019-14287, הינה חולשה בקוד של פקודת ה sudo , המשמשת להענקת גישות למשתמש.
החולשה בקוד נמצאה ונותחה ע"י Joe Vennix מ Apple
מהי פקודת ה sudo ?
פקודת ה sudo הינה פקודה במערכות הפעלה המבוססות unix המאפשרת הרצת פקודות בעזרת הרשאות של משתמש אחר, בדרך כלל כמשתמש על – root
בעת שימוש יום יומי במערכת , נהוג לעבוד כמשתמש "נמוך" (משתמש ללא הרשאות מיוחדות) , ולהחליף משתמש רק כשיש צורך להריץ פקודות המחייבות הרשאות גבוהות . בעבר הדבר בוצע ע"י הפקודה su שהיא קיצור ל switch user ומאפשרת להחליף משתמש. עם הזמן , הגיעו למסקנה כי החלפת משתמש היא לא מנהג טוב, משתמשים פשוט היו מבצעים החלפת משתמש למשתמש גבוה (root) ופשוט ממשיכים לעבוד כמשתמש זה,בלי לחזור חזרה למשתמש הנמוך.
פקודת sudo באה להתגבר על תופעה זו , ע"י כך שהיא משמשת להרצה של פקודות ספציפיות , ולא מבצעת החלפת משתמש מלאה.
פגיעות או חולשות בקוד של פקודה זו , הינה דבר חמור שיכול לגרום לתופעה של privilege escalation – תופעה הגורמת למשתמש פשוט להריץ פקודות כמשתמש גבוה בלי שניתנה לו ההרשאה המתאימה .
אז מה בעצם החולשה ?
בואו נראה דוגמא . ברשותי מערכת ubuntu , עם קרנל גירסה 4.15.0-64 :
יצרתי משתמש חדש בשם testuser ללא הרשאות מיוחדות . כמובן שבשביל ליצור משתמש חדש, יש צורך בהרשאות גבוהות ולכן הרצתי את הפקודה sudo על מנת להריץ את הפקודה adduser כמשתמש root :
שימו לב , שהשלב הראשון אחרי הרצת הפקודה , אני צריך להכניס את הסיסמה של היוזר שלי . פקודת ה sudo מחייבת מהמשתמש להכניס את הסיסמה שלו לצורך הזדהות.
כעת , בוא נשתמש בפקודה su על מנת להחליף את המשתמש ולהתחיל לעבוד כמשתמש החדש שיצרנו:
כעת , ננסה שוב ליצור משתמש חדש , הפעם בעזרת היוזר החדש שיצרנו :
שימו לב , שהפעם קיבלנו הודעת שגיאה . ההודעה אומרת שהיוזר שלנו (testuser) לא קיים בקובץ ה sudoers . מה ?!?!
מה זה קובץ ה sudoers ?
קובץ זה נמצא בתוך התיקייה etc והוא מכיל את כל הקונפיגורציה של פקודת ה sudo . שם אפשר להגדיר איזה משתמש יכול לקבל גישה לאיזו פקודה ואפילו כאיזה משתמש (חשוב מאוד , פקודת ה sudo יכולה לתת הרשאות של כל משתמש , לא רק משתמש root)
ניתן לראות את קובץ ה sudoers ע"י הפקודה cat /etc/sudoers – שימו לב , כי דרושה הפקודה sudo על מנת להעלות את ההרשאות מאחר וקובץ זה ניתן לפתיחה רק ע"י משתמש גבוהה:
ניקח לדוגמא את הפקודה whoami . פקודה זו נועדה (כשמה) להראות מי היוזר. הנה דוגמא להרצה:
בפעם הראשונה אני מריץ את הפקודה כמשתמש guym , והפקודה מחזירה לי את שם המשתמש שהריץ אותה – guym
בפעם השניה אני מריץ את הפקודה בעזרת הפקודה sudo , ולאחר אימות , אנחנו רואים שהפקודה whoami , החזירה לי את שם המשתמש root . זה בגלל שהפקודה sudo העלתה את ההרשאות שלנו ל root לפני שהריצה את הפקודה whoami .
אותו דבר, ניתן לעשות בעזרת sudo ולשנות את המשתמש שלנו למשתמש אחר . לדוגמא:
בדוגמא הזאת , השתמשנו ב sudo על מנת לתת למשתמש שלנו guym את ההרשאות של היוזר testuser , ולכן הפקודה whoami הציגה לנו את שם המשתמש שהריץ אותה , שהוא testuser
אז איפה הבעיה ?
כזכור , כשניסינו להריץ את sudo בעזרת המשתמש שיצרנו testuser קיבלנו את הודאת השגיאה כי היוזר testuser לא נמצא בקובץ ה sudoers .
בואו נוסיף אותו :
הוספנו את המשתמש testuser , ונתנו לו את ההרשאות להריץ את הפקודה whoami ככל יוזר.
בוא נבצע בדיקה חוזרת :
בשורה הראשונה , אנחנו משתמשים ב su על מנת להחליף את המשתמש למשתמש testuser
בשורה השניה , אנחנו רואים שכשאנחנו מריצים sudo whoami כמשתמש testuser , אנחנו בעצם מקבלים את root (כי הפקודה whoami רצה עם ההרשאות של root)
בשורה השלישית אנחנו רואים כי המשתמש testuser יכול להריץ את הפקודה whoami גם כמשתמש אחר – לדוגמא guym
אבל אם root לא בא לי ?
יש אפשרות בקובץ ה sudoers להגביל את מתן ההרשאות למשתמשים מסוימים . לדוגמא, נשנה את השורה שהוספנו ונגביל את האפשרות למשתמש testuser לשנות את ההרשאות למשתמש root :
ביצענו את השינוי בקובץ ה sudoers והוספנו את האפשרות root!– שאומרת שאת הפקודה whoami המשתמש testuser לא יוכל להריץ כמשתמש root
בואו נבדוק:
בשורה הראשונה , אנחנו משנים את המשתמש שלנו למשתמש testuser
בשורה השניה , אנחנו מריצים whoami בצורה רגילה , ובאמת התשובה היא testuser
בשורה השלישית , אנחנו מריצים את whoami כמשתמש guym , ובאמת התוצאה היא guym
בשורה הרביעית , אנחנו מנסים להריץ את whoami כמשתמש על – root – ומקבלים הודאת שגיאה.
בשורה החמישית , עושים עוד ניסיון להריץ את הפקודה כ root , ושוב , הודאת שגיאה.
הכל עובד כמו שצריך , אז מה בעצם הבעיה ?
על מנת לראות את החולשה בפעולה , ננסה שוב להפעיל את הפקודה whoami , אבל כמשתמש …
רגע לפני שממשיכים , שימו לב שלפקודה sudo ניתן להוסיף את הפרמטר -u ואת המשתמש שרוצים לקבל את ההרשאות שלו . ניתן להוסיף את שם המשתמש , או את ה uid שלו .
מה זה uid ? זה מספר המייצג את המשתמש . ניתן לקבל אותו ע"י שימוש בפקודה id , או לראות אותו בתוך קובץ ה passwd :
כמו שאתם רואים , ה id של המשתמש guym הוא 1000 , ואילו ה id של המשתמש root הוא 0
אתם רואים שאם אני מעביר את ה id 1001 לפקודה sudo , אני בעצם מקבל את ההרשאות של המשתמש testuser (כי זה ה uid שלו)
מה יקרה , אם אני אעביר לפקודה sudo את ה uid מינוס 1 ? ה uid צריך להיות מספר חיובי , איך הפקודה sudo תתייחס לכזה נתון ?
בואו נבדוק :
זהו , הצלחנו לנצל את החולשה בפקודה sudo על מנת להריץ את הפקודה whoami עם ההרשאות של root, למרות שבקובץ ה sudoers מוגדר במפורש לא לתת למשתמש testuser להריץ את הפקודה whoami כ root (אפשר לראות שבפעם הראשונה בפקודה באמת נכשלת)
ניתן גם להשתמש במספר 4294967295 על מנת לקבל את אותה תוצאה .
אז למה בעצם זה קורה ?
בשביל להבין למה זה קורה בדיוק , צריך להבין איך רצה הפונקציה sudo.
אם נסתכל על ההגדרה של קובץ ה sudoers , נראה שמסתתרת לנו s קטנה כחלק מהרשאות הקובץ:
ה s הזאת בעצם נקראת – SetUID bit – ואומרת שהתוכנה הזאת רצה עם ID המשתמש שלה (כמו שאנחנו רואים הצילום מסך הקובץ sudo שייך למשתמש root) ולא עם ה ID של המשתמש שהריץ אותה . לכן , כל משתמש שיריץ sudo , יריץ אותו כ root.
בשלב השני , תסתכל הפונקציה sudo בקובץ ה soduers , ותבדוק האם ניתן או לא ניתן להריץ את הפקודה שניתנה. במקרה שלנו , המשתמש testuser מנסה להריץ את הפקודה whoami כיוזר -1 . האם מותר ?
כן , לפי קובץ ה soduers מותר למשתמש testuser להריץ את whoami ככל משתמש אחר למעט root . המשתמש -1 הוא לא root (ה id של המשתמש root זה 0 ) , ולכן מותר (בעיה מספר 1 )
בשלב שלישי , הפונקציה sudo קוראת לפונקציות setresuid ו setreuid על מנת לשנות את ה id של המשתמש , ל id שנבחר (במקרה שלנו ה id הוא 1-) . כאן יש בעיה שהפונקציות הלו , בהינתן ה id 1- , לא מבצעות כלום , ולא משנות את ה id . (בעיה נוספת ? )
בשלב הרביעי , sudo יריץ את הפקודה שניתנה לו (במקרה שלנו whoami) , ובגלל שבשלב 3 לא שונה ה id , התוכנה whoami תרוץ עם ה id של sudo , שכמו שאמרנו בשלב 1 , sudo תמיד רץ כ root
וזהו , המשתמש testuser הצליח להריץ את whoami כמשתמש root , למרות שקובץ ה soduers בפירוש לא מרשה את זה.
האם הגיע הזמן להיכנס לפאניקה ?
ובכן , כנראה שלא.
מדובר על חולשה שמנצלת קינפוג מאוד ספציפי שמרשה למשתמש מסוים להריץ פקודה מסוימת ככל משתמש אחר למעט root . האם זה משהו שמקונפג בדרך כלל , נראה לי שלא ומדובר פה על מקרים מאוד ספציפים.
מה עושים עכשיו ?
עכשיו הזמן לשדרג . תבדקו מה גירסת ה sudo שלכם , ובמידה והיא קטנה מ 1.8.28 , אז צריך לשדרג:
למידע נוסף :