344
0

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

344
זמן קריאה: 11 דקות

אנחנו שומעים בחדשות על ‘מתקפות סייבר’ כל שני וחמישי (חוץ מאלו שלא רואים חדשות, תמשיכו ככה ;)…אבל מה בעצם קורה ‘תוך כדי’, מה בעצם קורה ברקע, מאחורי הקלעים, מה קורה מהרגע שהאירוע ‘החל’ ועד הרגע שכבר מבינים שמשהו פה לא בסדר? או יותר גרוע – שלא מבינים שמשהו פה לא בסדר וממשיכים על אוטומט…

תוכן עניינים

למי הכתבה יכולה להועיל?

הכתבה הזו הולכת להיות קצת ‘טכנית’, מה הכוונה?
היא תכלול בעיקר ניתוח של קטעי קוד Assembly המציגים כיצד Malware (או בשמם העברי – “נוזקות”, כן אני יודע 🤢) פועלים ברקע כדי להשיג את המטרות שלהם בעמדות הקצה שהודבקו, ביניהם:

  • השגת אחיזה/שרידות בעמדת הקצה – בעגה המקצועית: Persistence
  • השגת הרשאות חזקות לצורך ביצוע מניפולציות שונות בעמדת הקצה – בעגה המקצועית: Privilege Escalation
  • השגת חשאיות בעמדת קצה, על מנת להמשיך לפעול ברקע, ללא ידיעת המשתמש – בעגה המקצועית: Stealth

הכתבה הזו יכולה לתת התרשמות ראשונית מעולה, לאלו השוקלים קריירה בתור Malware Analyst או Reverse Engineering בתחומים השונים.
מה בעצם עושים בתפקידים אלו, איזה רקע זה מצריך והאם זה באמת מעניין אתכם פרט לתיאורים הנוצצים של ‘שכר הייטק’ ו- ‘לתפוס האקרים’.
הקבוצה השנייה הם מתכנתים במקצועם.
מתכנתים רבים, בעיקר אלו בתחילת דרכם או כאלו שפחות מתעסקים בפיתוח בהקשרים של Security Oriented או Driver-ים למיניהם, לא לגמרי יודעים איך סוגי Malware שונים פועלים, מה המטרות (השונות) שלהם בעמדות הקצה, ואני מאמין שעצם ההכרה של מה קורה מאחורי הקלעים, יכולה לעשות אתכם ל – ‘מפתחים שלמים’ יותר, עם ראיה מקיפה יותר.

רגע לפני שמתחילים…

בגדול, תהליך ה – Malware Analysis מורכב מ-4 השלבים הבאים:

  • Basic Static Analysis – בשלב זה, ננסה לדלות כמה שיותר מידע על ה – Malware, מבלי להריץ אותו. נבדוק איזה מחרוזות (string-ים) מוטמעים בו (אם בכלל), באיזה פונקציות וספריות DLL הוא משתמש לצורך הריצה שלו, האם הוא Packed או לא, וכל מידע אחר שיוכל לתת לנו רמזים ראשוניים מה ה – Malware בעצם עושה.
  • Basic Dynamic Analysis – בשלב זה, נריץ את ה – Malware במטרה לראות ב”לייב” איך הוא רץ וננסה לדלות כמה שיותר מידע באמצעות הכלים קיימים לרשותנו (ניעזר בעיקר ב – Sysinternals, Wireshark ונוספים לפי הצורך).
  • Advanced Static Analysis – בשלב זה, שוב נעבור לניתוח סטטי של הפוגען, אך כעת נצלול יותר לקרביים שלו. ניעזר בכלים המבצעים תהליך של Disassembly (הנפוצים: IDA Pro או Ghidra) לקובץ הזדוני – המרה מקובץ מקובץ exe מקומפל לקובץ המכיל קוד Assembly שאותו כבר נוכל לנתח.
  • Advanced Dynamic Analysis – אחרי השלב הקודם, כבר אמורה להיות לנו תמונה יחסית ברורה אודות מה ה – Malware עושה ואיך הוא עושה את זה. בשלב זה, נוכל להשלים את החלקים החסרים בפאזל.
    נריץ את ה-Malware תוך שימוש ב – Debugger-ים (הנפוצים: OllyDbg,WinDbg) על מנת לזהות חלקים חסרים שלא הצלחנו לזהות קודם, או לזהות את הערך של פרמטרים/פונקציות שונות שנקראים באופן דינאמי, רק בעת ריצת התוכנית.

אז בואו נתחיל לרברס…🧐

הכתבה הנוכחית, כפי שצוין בתחילת הפוסט, תעסוק בעיקר בשלב ה – Advanced Static Analysis, לכן נציין את הפרטים שנאספו בשלבים הקודמים על מנת לקבל תמונה רחבה בנוגע לקו המחשבה שלנו, למה בחרנו כך, למה הגענו להשערה כזו וכזו וכ’ו…

בשלב ה – Basic Static Analysis ראינו כי ה – Malware מכיל מספר string-ים, לאחר סינון הלא המעניינים מבניהם קיבלנו את:

OpenThread, AppInit_DLLs, send, wsock32.dll, spoolvxx32.dll, OUTLOOK.EXE, MSIMN.EXE, THEBAT.EXE, RCPT TO:,RCPT TO:< ו- SOFTWARE\Microsoft\\Windows nT\CurrentVersion\\Windows

אנחנו רואים כי הקובץ כנראה קשור איך שהוא לשירותי שליחת מיילים בעקבות השימוש ב- string-ים: OUTLOOK.EXE, MSIMN.EXE ו- THEBAT.EXE המציינים process-ים הקשורים לשירותי Email-Exchange.
בנוסף, יש לנו ערך של Registry Key שיכול להכיל מידע מעניין – נבדוק אותו אחרי ריצת הקובץ.
הדובדבן שבקצפת, אנחנו רואים שימוש ב – AppInit_DLLs – זהו mechanism של Windows המאפשר לרשימה של קבצי DLLs להיטען באופן דינאמי ל – process-ים שונים (ב- user space) – מיושם בעיקר לצורך השגת Persistence בעמדת הקצה.

**בגרסאות יותר עדכניות של Windows ובארכיטקטורות 64-bit מודרניות כבר נדרש שלב certification נוסף לצורך היישום של mechanism זה, אך לעת עתה, נדבר על הגרסה הפשוטה יותר של מימושו.

ייתכן כי שם הקובץ שמצאנו – spoolvxx32.dll קשור בצורה כזו או אחרת להשגת ה – Persistence בעזרת AppInit_DLLs, אך נצטרך להעמיק בחקירה כדי לדעת בוודאות.

לאחר ביצוע שלב ה – Basic Dynamic Analysis, ראינו כי הפוגען:

  • פותח קובץ הנקרא Lab11-02.ini (קובץ זה נמצא באותה תיקייה בה נמצא הפוגען, לצורך ריצה תקינה של ה – Malware)
  • פותח את הקובץ spoolvxx32.dll שנמצא בנתיב: C:\Windows\System32\spoolvxx32.dll ומבצע עליו פעולת OverWrite.
  • בנוסף, ראינו כי אכן מתבצעת קריאה ל – Windows API Function הנקראת RegSetValue לצורך שינוי ערך ב- Registry בנתיב הבא: HKLM\SOFTWARE\Microsoft\Window NT\CurrentVersion\Windows\AppInit_DLLs – מה שאכן מאמת את השערתנו הראשונית בנוגע ל-איך מושג Persistence בעמדה.

IDA Pro,IDA Pro, IDA Pro…🤩

אך שאומרים, last but not the least, נעבור לביצוע Advanced Static Analysis:

אנו מתחילים לנתח את הקובץ לאחר שעבר תהליך של Disassembly ומוצג לנו כקוד – Assembly.
כמה שורות לאחר פונקציית ה – main, אנו רואים קריאה לפונקציות הבאות:

  • GetModuleFileName
  • sub_1000105B
  • CreateFile

רק מניתוח הקריאות (וקצת העמקה בפרמטרים שהן מקבלות) נוכל להבין כי:

  1. מוחזר ה – Handle ל- Module (קובץ dll או exe) שנטען ע”י ה – Process הנוכחי. (Handle הוא בעצם reference לאובייקט/משאב מסוים. פונקציות רבות מחזירות Handle-ים על מנת שפונקציות אחרות יוכלו לקבל Handle זה כפרמטר ולהמשיך לגשת/לבצע מניפולציות על אובייקט/משאב זה.)
  2. מתבצעת קריאה לפונקציה sub_1000105B – כיוון שלא מדובר בפונקציית Windows API אלא פונקציה שכתב התוקף (בשפה עילית בה נכתב הפוגען) היא לא מתויגת בעזרת string המרמז לנו על הפונקציונליות שלה.
    לצורך הנוחות, אגלה כי מדובר בפונקציה שמחזירה את הנתיב של ה – system directory של עמדת הקצה.
  3. לאחר כן, מתבצעת קריאה לפונקציה strncat המקבלת מחרוזות Source ו- Destination ומבצעת עליהם פעולת concatinate.
  4. כעת, מתבצעת קריאה לפונקציה CreateFile, בהסתמך על הפרמטרים אותם היא מקבלת (ועם קצת Googling על:
    “MSDN CreateFile” אנו מזהים שמתבצעת פתיחה של הקובץ ולא יצירה שלו).

5. בהמשך, גם מתבצעת קריאה ל – ReadFile לצורך קריאת תוכן הקובץ (לכאורה נראה כמו אוסף רנדומלי של אותיות ומספרים).
בנוסף מתבצעת קריאה לפונקציה נוספת sub_100010B3 המכילה המון פעולות אריתמטיות כגון: XOR,AND,OR וכ’ו… -> מרמז לנו כי כנראה פונקציה זו מבצעת פעולת decode לתוכן הג’יבריש שראינו קודם בקובץ -> נחזור אליה בהמשך.
6. ניתוח נוסף, מגלה לנו את קטע הקוד הבא:

קטע קוד זה אכן מאמת את ההשערה שלנו אודות ה – Persistence Mechanism.
כיוון שה – Malware מתקין את עצמו כ – AppInit_DLL עבור השגת Persistence המשמעות היא כי הוא יטען לכל user-mode process (הכוונה לכל process שמכיל User Interface מסוג כזה או אחר ומשתמש ב – User32.dll) בעמדת הקצה -> פונקציונליות זו מקשה על הסרת הפוגען (שכן “כל” User Space Process מריץ את ה- Malware המדובר).
בקטע הקוד בתחילת הסעיף, אנו בעצם רואים כי ה- Malware מעתיק את עצמו למערכת בתור spoolvxx32.dll (כאן נכנס לתמונה ההיבט של Stealth – משנה את שמו לשם יותר גנרי, על מנת להקשות על הזיהוי ע”י המשתמש).
וקורא לפונקציה RegSetValue על מנת להתקין את עצמו ב – Registry Key המדובר AppInit_DLLs.

7. בהמשך, אנו רואים את קטעי הקוד הבאים:

  • קטע קוד אחד, הבודק האם ה- process הנוכחי שרץ הוא אחד מה- process-ים שראינו קודם: OUTLOOL.EXE, MSIMN.EXE,THEBAT.EXE (נוכל לזהות זאת ע”י ה- string lable-ים ש – IDA Pro מוסיף לנו, בנוסף לביצוע backtracking לערכים שמועברים לרגיסטרים ומועברים לקריאות ה- memcmp).

  • קטע קוד שני, הנראה כמו user-space rootkit.

(על רגל אחת, user-space הינו מרחב כתובות בזיכרון בו רצים process-ים עם הרשאות גישה מוגבלות, בעוד kernel-space הינו מרחב כתובות בזיכרון בו רצים process-ים עם הרשאות גבוהות האחראים על ניהול מערכת ההפעלה עצמה, החומרה של המחשב ובין היתר על ניהול ה- user-space.
Rootkit – קובץ זדוני, הנועד להסתיר (שוב, מימוש יותר רציני של היבט ה – Stealth מאשר רק שינוי השם כפי שצוין קודם) את קיומו של Malware בעמדת הקצה, כיוון שמדובר רק במימוש היבט ה- Stealth, לרוב יגיע עם קובץ זדוני נוסף/כחלק מ- Malware יותר רחב שמממש את שאר הפונקציונליות).

8. בניתוח הפונקציה המתויגת כ – sub_10012A3 (לצורך הפשטות, צילום קטע הקוד לא מצורף) שנקראת ישירות לאחר העברת המחרוזות הבאות : wsock32.dll ו- send כפרמטרים אנו מגלים כי היא:

  • מקבלת Handle ל – wsock32.dll (לצורך תקשורת בעזרת socket-ים).
  • קוראת ל – GetProcAddress לביצוע Dynamic Linking (פיענוח וקריאה בזמן ריצה (“דינאמית”) לפונקציה בספריית ה – DLL שנטענה).
  • לבסוף מתבצעת קריאה נוספת לפונקציה: sub_10001203 (פונקציה זו בעצם מממשת את ה- Rootkit המדובר).

9. כמסקנה מהשלב הקודם, בעצם מתבצע תהליך של Hooking על פונקציית ה – send בקובץ ה- DLL הבא: ws2_32.dll.

חידוד קטן בנוגע לפסקה הקודמת😁

  • הקובץ wsock32.dll משמש כ – Wrapper עבור ws2_32.dll. ב – Wrapper הכוונה, “תוכנית מעטפת”, המוסיפה שכבה נוספת של Data לתוכנית הפנימית יותר, לצורך ריצה תקינה שלה. במקרים אחרים של Malware, שימוש ב- Wraper-ים מרמז כי ייתכן והפוגען הוא Packed וראשית יש לבצע לו Unpacking על מנת לנתחו -> תהליך הנועד להקשות על החוקרים בניתוח הפוגען.
  • ביצוע Hooking – בעצם שינוי של תהליך הקריאה לפונקציה המקורית הלגיטימית (במקרה שלנו פונקציית ה- send ב – ws2_32.dll) שכבר קיימת ב-Windows או שינוי חלק מהקוד שלה לצורך קריאה ל – Malware הזדוני של התוקף.

Rootkit סוף סוף הגענו:

10. “אני רק הערה”: בחלק של ניתוח ה – user space Rootkit, אעשה זאת בקצרה שכן התעמקות מעמיקה מצריכה גישה לכל הקובץ, לצורך ביצוע backtracking ו – reference לקטעי קוד Assembly קודמים.

  • במרחב הכתובות שנמצא בין 0x10001209 – 0x10001212 (מסומן בצהוב), אנו רואים כי מתבצע חישוב של כתובת כלשהי שמועברת לרגיסטר eax -> בעצם מדובר בחישוב כתובת ה – Jump אליה נקפוץ לאחר הקריאה לפונקציית ה – send.
  • במרחב הכתובות שנמצא בין 0x10001218 – 0x10001221 (מסומן בירוק), בעצם מתבצעת קריאה לפונקציה VirtualProtect, בהסתמך על הפרמטרים (וחיפוש ב – MSDN) אנו מבינים כי מתבצע שינוי של הגדרות הגישה ל – memory של process זה, על מנת לשנות את תוכן הקוד בזיכרון של הפונקציה send.
  • במרחב הכתובות שנמצא בין 0x10001253 – 0x1000126E (מסומן בכתום), אנחנו תחילה מבצעים שמירה של הקוד שמופיע בתחילתה של פונקציית ה- send ולאחר מכן דריסה של תחילתה עם הערך 0xE9.
  • לבסוף, במרחב הכתובות 0x10001274 – 0x1000127D (מסומן בכחול) מתבצעת הכתיבה של כתובת ה – Jump (ששמורה במשתנה – var_4) במקום קוד הקטע המקורי שמופיע בתחילתה של פונקציית ה- send.

11. לצורך הפשטות, אגלה כי לאחר ביצוע ה – Jump לכתובת השמורה ב – var_4, בעצם מתבצעת כתיבה לזיכרון על מנת להוסיף את הערך “RCPT TO” בנוסף לערך נוסף הנשלף מתוך קובץ ה – Lab11-02.ini שראינו כי לכאורה מכיל ג’יבריש.

12. אם נבצע את שלב ה – Advanced Dynamic Analysis, נריץ את ה – Malware תוך כדי מעקב אחר אופן הפעולה שלו בעזרת ה – Debugger הידוע OllyDbg נוכל לגלות מהו ערכו של הג’יבריש שראינו.
נשים breakpoint בדיוק בכתובת בה פונקציית ה – Decode מסיימת לרוץ (אחרי כל פעולות ה – XOR,AND,OR…ורגע לפני ביצוע ה – Return והתקדמות ל – Instruction הבא) ונוכל לגלות כי מדובר בכתובת מייל.
יחד עם העובדה כי הקריאה לפונקציה זו התבצעה אחרי ביצוע Hooking לפונקציית ה – send וכתיבה לזיכרון עם הערכים “RCPT TO:” נוכל להסיק כי ה – Malware יוסיף את הכתובת שזה עתה פוענחה לכל מייל במידה ומדובר באחד מה – process-ים שזוהו קודם (OUTLOOK.EXE, MSIMN.EXE,THEBAT.EXE – שאחראים לשירותי Email Exchange).

אז תכל’ס מה ראינו?

  • ה – Malware משתמש ב – AppInit_DLL mechanism לצורך השגת Persistence: במטרה לגרום ל – Malware להיטען לכל user-space process (שטוען את User32.dll).
  • ה – Malware משתמש ב user -space Rootkit (המינוח היותר מקצועי לתהליך שראינו נקרא In-line Hooking) לצורך השגת Stealth בעמדת הקצה.
  • במידה והתהליך אליו ה – Malware נטען הוא אחד משירותי ה – Email Exchange שצוינו – הוא יבצע את תהליך ה – Hooking לפונקציית ה – send. הוא יפענח את כתובת האימייל ויוסיף אותה בתור נמען לכל מייל שנשלח כך שיועבר גם לתוקף -> כך התוקף יקבל גישה לכל המיילים שנשלחים מעמדת הקצה.

תובנות, תהיות ושאר ירקות…

  1. הניתוח שהוצג כאן, אינו ניתוח מלא לצורך הפשטה ותימצות של תהליך החקירה, על כן יש מקומות בהם יש קצת קפיצה בסדר הכרונולוגי של ביצוע החקירה.
  2. ראינו כי בהרבה מקרים, יכולנו לשער מה התכלית של קטע קוד מסוים ובמקרים רבים גם קיבלנו הוכחות חותכות המאמתות את נכונות ההשערה שלנו. עם זאת חשוב לציין, כי חייב למצוא את ההוכחות החותכות הללו.
    במקרה שלנו מדובר ב – Malware שהוא Lab Sample הנועד לתרגול HandsOn ולמידה של הנושא.
    היו קטעים בקוד שהצריכו יותר העמקה וממש לחקור פקודה-פקודה והיו קטעי קוד בהם יכולנו להבין מה בגדול קורה בעיקר על סמך הקריאות לפונקציות.
    ב – Malware-ים במציאות, נראה דברים הרבה יותר מורכבים.
    לרוב ה – Malware יכיל חלק כלשהו של Anti-ReverseEngineering, יכיל מספר רב של פונקציות במטרה להשיג פונקציונליות מלאה של ההיבטים שצוינו (Stealth, Persistence וכ’ו…) ויהיה הרבה יותר מורכב לניתוח.
    על כן, לעיתים נראה כי ההשערות המקוריות שלנו דיי רחוקות ממה שקורה בפועל ולכן תמיד חייב לחפש קטע קוד המאמת את ההשערה שלנו (או מפריך אותה לטובת השערה אחרת😎).
  3. בנוסף, החקירה כפי שהוצגה כאן לכאורה הייתה רצף כרונולוגי בו שלב אחד מתגלגל מאחד לשני בצורה קוסמית מופלאה.
    גם ב -Sample הזה וגם ב – Malware אמתיים (Out there in the wild) אין כך הדבר, נדרשת היכולת לבצע Pivoting סביב נקודת מידע שמצאנו, ביצוע cross-reference על פיסות מידע (IDA Pro מאפשר ממשק מדהים לכך), הגדרת Struct-ים שייתכן ו – IDA Pro לא לגמרי זיהה ועוד שלל יכולות הנצברות עם הניסיון.
  4. לסיכום, הייתי אומר כי חבר’ה הרוצים לעסוק ב – Malware Analysis צריכים להיות אנשים סקרנים וכאלה האוהבים להבין איך דברים עובדים מאחורי הקלעים -> רק כך ניתן באמת להבין את הפונקציונליות המלאה של Malware-ים שונים.
    להיות מסוגלים לנבור בקוד Assembly במשך שעות (וכשאני אומר שעות, אני מתכוון ימים), להבין איך מערכות הפעלה עובדות, מנגנוני יצירת תקשורת לרשת, מנגנוני קריאה לפונקציה, גישה ל – kernel ועוד.
    ולדעתי הכי חשוב, צריך להיות מסוגלים תמיד להטיל ספק בהשערות שלכם עד אשר מצאתם הוכחה חותכת שהם נכונים -> רק כך ניתן באמת להגיע לרמת מקצועיות גבוהה בתחום🧐.
  5. אסיים ואומר, שאל דאגה, הרבה מהדברים האלו מגיעים עם ניסיון שנצבר לאחר ביסוס רקע תיאורטי יציב.
    ואני בטוח שכל אחד שבאמת מרגיש Passion לתחום יצליח ללמוד את זה 🙂
    אפרסם בקרוב פוסט נוסף, אודות איך כדאי להיכנס לתחום הזה, אילו יכולות צריך להתחיל לרכוש באופן עצמאי ואיך אפשר לעשות זאת 😉

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

דן דורפמן
WRITEN BY

דן דורפמן

סטודנט למדעי המחשב באוניברסיטה הפתוחה.
SecOps Engineer & Automation Developer.
בעל תשוקה לתחום ה- Malware Analysis & Reverse Engineering.
בזמני הפנוי אני: לומד דברים חדשים, משחק כדורסל, שומע מוזיקה, ומדבר על החיים עם החבר'ה ;)

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *