מדוע הפרצה באפליקצית רמיני היא כל כך מזעזעת

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

רמיני

רמיני

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

כשל ראשון – קוד בצד הלקוח שלא עבר uglification.

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

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

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

// "https://www.remini.me/XXXXLiadTestWP.php",
// "https://www.remini.me/XXXXLiadTestWP.php",
// : "https://www.remini.me/XXXXLiadTest.php",
// "https://www.remini.me/XXXXLiadTest.php",
// "https://www.remini.me/XXXXZviTest.php",
// "https://www.remini.me/XXXXZviTest.php",

כשל שני – שרת שלא השתמש באותנטיקציה כלל

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

כשל שלישי – API שחשוף ל-SQL injection

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

כשל רביעי – מסד נתונים שלא השתמש בסיסמה ושם המשתמש שלו היה root

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

כל מה שנותר לתוקף לעשות הוא להוריד את כל הטבלאות. – הנה רשימה חלקית שלהן:

+-------------------------------------+
| AdoptedPost                         |
| Adult                               |
| AdultDevices                        |
| AdultLoginDevices                   |
| AdultToAffiliateCampaign            |
| AdultToChild                        |
| AdultWithFrame                      |
| Affiliate                           |
| AffiliateCampaign                   |
| AllWeeksNumPosts                    |
| Attendance                          |
| AttendanceStatuses                  |
| BadEmailsInvitations                |
| Child                               |
| ChildAttendance                     |
| ContactUs                           |
| Conversations                       |
| DailySheetActivitiesTypes           |
| DailySheetDetails                   |
| DailySheetDetailsTypes              |
| DailySheetMealTypes                 |
| DigitalContent                      |
| DigitalContentPost                  |
| Email                               |
| EmailElementsText                   |
| Entity                              |
| EventFrames                         |
| EventReminder                       |
| Events                              |
| FamilyUsers                         |
| Followers                           |
| FollowersOfTheAdultChildren         |
| Frame                               |
| FramePeriod                         |
| FramePeriodChildren                 |
| FramePeriodChildren_neta081117      |
| FramePeriodTeacher                  |
| GroupDataFiles                      |
| Invitation                          |
| InvitationChildren                  |
| KindergartenTeacherPerformance      |
| LastTwoWeeksNumPosts                |
| LogCampaign                         |
| LogFunctionTime                     |
| LogPushNotifToViewedProfile         |
| LogTaggingEntities                  |
| LogTries                            |
| LogUser                             |
| LogUserFunction                     |
| LogUserPressSignUpButton            |
| MeasureKindergarten                 |
| Messages                            |
| MessagesViews                       |
| Notification                        |
| Settings                            |
| Tag                                 |
| TagMilestones                       |
| TagName                             |
| TagToEntity                         |
| UrlDirectory                        |
| 1weekAdultPost                      |
| 1weekFramePosts                     |
| Language                            |
| assessmentDetails                   |
| assessmentFrames                    |
| assessmentHeaders                   |
| assessmentLevels                    |
| assessmentObservations              |
| tmp_UsersFromKindergartenInvitation |
| tmp_UsersWhoInvitedFamily           |
| tmp_UsersWhoWhereInvited            |
| tmp_invitedKindergarten             |
| usersUsage                          |
| usersUsageHelp                      |
| usersUsageHelpWithFrame             |
| usersUsageWithFrame                 |
| wizoFrameChildren                   |
| wizoPosts                           |
+-------------------------------------+

לסיכום

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

זה פשוט מרגיז מאוד לראות איך הפרטיות שלנו מופקרת שוב ושוב בידי אנשים שאפילו את הבסיס המינורי לא עושים. אפילו התגובה שלהם, שנמסרה לדה-מרקר:

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

מרגיזה. ״מאמצים כבירים״?!? לא מדובר בפירצה מחוכמת. מדובר ב׳פירצה׳ שלא אמורה להתקיים גם באתרים פשוטים. אם יש מומחה אבטחה אחד שאישר את הבדיחה הזו – צריך לקבל את השם שלו כי אסור לו לעבוד במקצוע הזה. כי אני לא ראיתי איש אבטחת מידע אחד שהיה מאשר API שפגיע ל -SQL Injection שהוא הפרצה הכי מוכרת שיש ברשת בערך.

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

אהבתם? לא אהבתם? דרגו!

לא אהבתי בכלללא אהבתיבסדראהבתיאהבתי מאוד (36 הצבעות, ממוצע: 4.31 מתוך 5)

תגיות: , פורסם בקטגוריה: חדשות אינטרנט

יאללה, שתפו :)

אל תשארו מאחור! יש עוד מה ללמוד!

30 comments on “מדוע הפרצה באפליקצית רמיני היא כל כך מזעזעת
  1. ינאי הגיב:

    להשאיר ROOT כשם משתמש וסיסמא – ממש טיפשי!!!

  2. אביב הגיב:

    בשורה “בצד מתכנתי השרת – שם לא טרחו לעשות וידאו לפרמטרים.” מניח שזה אמור להיות “וידוא” ולא “וידאו” 🙂

  3. שמוצי הגיב:

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

  4. גופי הגיב:

    נשמע כמו מתחרה שרוצה להכפיש את המערכת הזאת

  5. למהלא הגיב:

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

    • רן בר-זיק הגיב:

      יש לי שאלה – אתה חושב שכאן זה מערכת טוקבקים רגילה ואני לא רואה שה-IP של התגובה הזו ושתי התגובות הקודמות הוא אותו IP?!? חחחחחח

      • חחחחחחח...... הגיב:

        ברור שאתה רואה.
        עדיין הכל נכון

        • חגי הגיב:

          תגובה ממש לא עניינית.
          API שחשוף לפגיעות SQL INJECTION הוא פשוט לא מקצועי
          אי מחיקת קומנטים שמגלים סודות זה לא מקצועי
          בסיס נתונים עם שם משתמש דפולטיבי זה לא מקצועי.

          והכי לא מקצועי זה לא להודות בטעות.

        • רן בר-זיק הגיב:

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

      • איזה אהבלים הגיב:

        חחחח

      • יוסף הגיב:

        חחחחל הרגת אותי. עשיתי lol בחיים האמיתיים

      • עודד הגיב:

        רן אתה מפתח על! יודע את הip של המשתמשים שלך.
        פשוט אין דברים כאלה. עף על עצמך

    • רן הגיב:

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

      לעיתים קשה להגן על מערכות, אבל וואו, זה בסיסי כל כך…

  6. מאור הגיב:

    חחחחחחחחחחחחחחחחחחחחחחחחחחחחח אני מת

  7. עומרי הגיב:

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

  8. מתכנת הגיב:

    “uglification” או obfuscation אלא כלים של security by obscurity .

    והם מיותרים, וחסרי ערך אמיתי.

    • רן בר-זיק הגיב:

      אלא אם כן אתה שם הערות בקוד עם קישורים ל-API של הדיבאג (ולא טורח לסגור אותו בכלל)….

      • מתכנת הגיב:

        זה אולי היה מקשה על הפריצה המדוברת. אבל זה כיסוי קוסמטי…

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

  9. קקק הגיב:

    יש לי הרגשה שאני יודע טוב מי זה הליעד הזה…

  10. רן בר-זיק אני כל כך חולה עלייך שאני רוצה שיגידו לי: מזל טוב, וזה יהיה הילד שלך

  11. שושנה הגיב:

    וואו. די מדהים שיש אפליקציה שנכתבה ב-15 השנים האחרונות שפגיעה ל-sql injection. זה כל כך בסיסי.

  12. זיקו הגיב:

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

  13. programmer2018 הגיב:

    איש אבטחה שלא יכול לרשום בקו”ח איפה הוא עבד בשנים האחרונות…
    לך תדע, אולי הם היו לחוצים לשחרר גירסא….
    למי יש זמן לבדוק חורי אבטחה בחברות מדיה שמתות רק להעיף לחנות אפליקציות את האפליקציה שפיתח מתכנת שבידיוק סיים קורס מזורז ב JAVA For dummies או מתכנת BACK END שקרא מדריך על PHP …
    למי יש תקציב ל MYSQL DBA ? כשכל מה שאתה רוצה לעשות זה לחסוך בעלויות להתעשר בקלות.
    show databases;<
    brain
    drop brain;<

  14. משתמש אנונימי (לא מזוהה) הגיב:

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

    • משה הגיב:

      אני חושב שזה הבדל סמנטי כי תהליך minificatio גם “מכער” את הקוד (כמובן ש”כיעור” הוא סובייקטיבי) ועדיין יעלה מעט את רמת הקושי לעשות שימוש רע בקוד. תהליך טוב לא רק מוריד רווחים ומשנה שמות משתנים וכו’ אלא ממש משנה את הקוד (מכניס if else לתצורה של single line condition וכדו’) שמקשה עוד יותר על קריאת ודיבוג הקוד. כמובן שלמתכנת front טוב, לא יפריעו כל הדברים האלו, אבל זה יעלה את סף ה”כניסה”.

  15. ניר הגיב:

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

כתיבת תגובה

האימייל לא יוצג באתר.

רישום