
הטקסט המלא של הדקות הראשונות בהרצאה «כתיבת C# wrapper סביב Meterpreter Payload» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.
שלום לכולם, בהרצאה הזו אנחנו רוצים לייצר ראפר, מעטפת ב-C-Sharp סביב הקוד הזדוני שלנו שכתוב בשפת מכונה אנחנו גם קוראים לזה הרבה פעמים שפת אסמבלר אז אנחנו רוצים לעטוף את כל הקוד הזדוני שלנו בתוך מעטפת ב-C-Sharp כדי שנוכל להוסיף עליו יכולות מסביב כדי להתחמק מכל הבדיקות אנחנו נעשה מעטפת ב-C-Sharp
שבודקת האם אנחנו נמצאים בתוך מכונה וירטואלית ואז אנחנו לא עושים שום דבר רע, פשוט יוצאים מהתוכנית. האם אנחנו נמצאים בתוך סנדבוקס?
מה זה סנדבוקס? זה מה שהאנטיווירוסים בודקים בהם את התוכנות. זה כמו מכונה וירטואלית מבודדת שבודקת האם התוכנה עושה משהו זדוני או לא.
אז אנחנו רוצים לקחת את הקוד הזדוני שלנו ולעטוף אותו ב-C-Sharp, בוויז'ואל סטודיו שהתקנו בהרצאה קודמת. קודם כל ככה, בואו נעשה שני דברים, נעשה ליסנר שיאזין לכל הפקודות שלנו, נעשה את הליסנר שלנו ונייצר את הקוד הזדוני, זה שני הדברים שאני רוצה.
אני מייצר אותו ב-C-Sharp, ב-X64 ושם אותו כאן בקובץ. אחרי שאני מייצר את הקובץ שנקרא מטרפריטר C-Sharp, בואו נראה שיש לנו את הקובץ הזה שהוא באמת קיים ומה יש בפנים, שלושת אלפים שלוש מאות שישים בתים נעשה cut ואת השם של הקובץ אנחנו רואים שפת מכונה פקודות בשפת מכונה וזהו שאנחנו צריכים לעשות מעטפת שמריצה אותם וגם על הדרך
מתחמקת אני מפעיל שרת web כדי שאני אוכל לקחת את הקובץ הזה ופותח tab חדש אז הtab הזה זה נקרא rename http server אני אקרא לו בtab הזה אנחנו נריץ listener נקרא לו handler handler מטפל או listener או איך שאתם רוצים תקראו לו סודו מינוס S אני מריץ את הליסנר זה MSF קונסול מינוס Q שלא יציג לי את כל
הכניסה היפה שלו רק אכנס בשקט ומינוס X זה כל הפקודות שהוא יריץ בפנים אחרי שהוא יכנס פנימה במקום שאני אריץ אותם ידנית אני מעביר לו שורה אחת זה כל זה שורה אחת ב-CMD בטרמינל והוא מריץ את כל הפקודות האלו ברצף לבד במקומי בואו ניתן לו לרוץ
נבדוק שבאמת יש ג'וב שמאזין, כן, אני רואה פה ג'ובס שמאזין, וסשנס, כמובן שאין שום סשן שיתחבר, אין אף לקוח שיתחבר. אז זה ההנדלר שלנו, זה המטה ספלויט, אפשר לקרוא לזה מטה ספלויט הנדלר, ותאב אחרון שאני אפתח זה סתם תאב, אם אני ארצה להריץ איזה שהם פקודות.
יופי, חוזרים חזרה, מה אנחנו רוצים? אנחנו רוצים לקחת את הקוד הזדוני הזה ולעטוף אותו, את הסוס הטרויאני הזה ב-C-Sharp. אז אנחנו פותחים פה את ה-Visual Studio ועושים Create New Project לייצר פרויקט חדש.
הוא שואל אותי באיזה שפה אני רוצה, אני אומר לו, תסנן לי מכל הפרויקטים שאתה יודע לייצר, שימו לב כמה פרויקטים הוא יודע לייצר בכל מיני שפות, לדוגמה F-Sharp, C-Sharp, אני אומר לו, תעשה לי רק C-Sharp עבור Windows, רק עבור Windows, הוא יודע גם לעשות כל מיני פרויקטים.
פרויקט זה כמו תוכנה או אתר אינטרנט, אז הוא יודע לעשות לדוגמה גם לאייפון, גם לטלוויזיות, לאנדרואיד, אני אומר לו רק לווינדוס אני רוצה, ואיזה סוג, C-Sharp לווינדוס, האם זה הולך להיות משחק, האם זה הולך להיות תוכנה עם הקליקים, עם חלונות, אני אומר לו לא, קונסול, קונסול זה מסך שחור
רגיל, ואז נשאר לנו פה קונסול ו.NET framework, זה מה שאני רוצה, project create command line, זה אומר תוכנה ב-CMD רגילה.
למה אני עושה דווקא את זה? כדי לא להסתבך עם התכנות, אני רוצה כמה שפחות תכנות. אז אני עושה תוכנה רגילה ב-CommandLine, שימו לב ל-.NET Framework.
אני לא עושה אותה ל-Linux ו-Mac OS, כי אני לא רוצה .NET Core, אני רוצה רק ל-Windows .NET Framework רגיל. לא את ה-Core, אני עושה Next.
שיהיה לי הכי קל, איך נקרא לה? זה למעשה מה שאנחנו נשלח ללקוח שלנו, זה הווירוס שלנו, זה הטרוג'אן שלנו, זה הקובץ אקזה שייצא.
נקרא לו, נניח משהו תמים, כמו youtube.exe. סתם דוגמה, נקרא לו יוטיוב, ואז התוכנה תקרא youtube.exe כדי שבן אדם לא יפחד ללחוץ עליה. אתם יכולים לתת איזה שם שבא לכם, המטרה שבסוף הלקוח יריץ את זה, ואני מייצר בשם יוטיוב.
עכשיו שימו לב, אנחנו הולכים לכתוב כולה איזה ארבע פקודות. אחת שעושה את הבאפר עם הקוד הזדוני זה המטרפריטר שלנו זה הפקודות בשפת מכונה שאנחנו מכניסים לתוך הבאפר מקצים לו זיכרון תא בזיכרון משתנה בשם אדרס יצביע לאיזשהו תא בזיכרון מעתיקים לתוך האדרס הזה עושים קופי מעתיקים לתוכו
את כל הבאפר שלנו זאת אומרת את כל הקוד הזדוני מעתיקים לזיכרון ומריצים אותו יוצרים thread Thread זה תוכנה להרצה ולמעשה אנחנו מפעילים אותו ופה אנחנו נותנים לו לרוץ ומחכים לתשובה ממנו.
יוצרים Thread ופה אנחנו מריצים אותו וזהו, זה כל מה שצריך לעשות. בואו נראה איך זה עובד, יש לנו פה פרויקט, שימו לב בפרויקט יש לנו רק קובץ אחד, סתם דוגמה בוא נעשה איזושהי פקודה פשוטה cwConsul right line תדפיס לי על המסך אות aaa.
סתם תראו מה זה עושה, אני לוקח את הפרויקט הזה עם פקודה אחת ויחידה שיש לי כרגע, קונסול רייטליין, אני פותח אותו באקספלואור רגיל, אני רוצה להראות לכם מה קורה, זאת התיקייה של הפרויקט.
בתיקייה של הפרויקט יש לנו את הקובץ הזה, שעשינו אותו כאן, שימו לב, זה סתם קובץ טקסט, שלא תפחדו מתכנות, אז אני נותן לכם קצת בסיס.
כל מה שאנחנו כותבים זה קובץ טקסט, פשוט במקום לכתוב אותו בנוטפד, אנחנו כותבים בכזה כתבן יותר יפה, ופה מצביע לי אם יש איזושהי בעיה בפקודה ואם אני אכתוב פקודה לא נכון תוך כדי כתיבה הוא יעשה פה x ויכתוב לי שיש לי טעות ויסמן אותה באדום זאת אומרת כתבן חכם שמתקן שגיאות כתיב של מתכנתים כל הקוד שלנו זה למעשה טקסט פשוט שאנחנו כותבים אותו באנגלית רגילה בפקודות
של c-sharp ובסוף זה מתקמפל לשפת מכונה שימו לב אני עושה פה נניח דיבאג ועושה ריבילד הריבילד מה הוא עושה הוא מייצר לי קובץ אקזה הופך את כל הפקודות שיש פה לשפת מכונה יש פה קבצי עזר שאני יכול למחוק אותם ובסוף נוצר לי קובץ אקזה רגיל עכשיו שימו לב אם אני אעשה פה שיפט רייט קליק ואני אפתח CMD בתיקייה הזאת אני יכול להריץ
את הקובץ הזה והוא ידפיס לי על המסך AAA אני גם אדגים לכם שזה עובד ב-CMD זאת אומרת אני ב-CMD רגיל גם כן יכול להריץ את הקובץ הזה יוטיוב והוא ידפיס לי aaa שתבינו כל מה שקורה בתכנות זה לקחת את הפקודות שאני כותב נניח בשפת c-sharp או c++ או לא משנה באיזה שפה ולתרגם אותם לשפת מכונה כדי שאני כמתכנת לא אצטרך להתעסק לבד בשפת מכונה אני
כותב את זה במה שיותר נוח לי לא משנה יש פה כל מיני קבצי עזר שלא מעניינים ואז אני לוקח את הקובץ אקזה הזה ואני מריץ אותו נניח במקרה הזה עשינו תוכנת קונסול אז היא רצה ב-SIMD רגיל שימו לב זה יוטיוב.אקזה אני מריץ אותו ואני יכול לשלוח אותו במייל לאנשים ומאחורי הקלעים בתוך היוטיוב הזה הכל כתוב
בשפת מכונה הוא מבצע את מה שביקשתי ממנו מדפיס AABBB אנחנו פה רואים את התוצאה אז עוד פעם כותבים פקודות עושים ריבילד הופכים את הפקודות האלו לקובץ אקזה זה בעצם התהליך שקורה מאחורי הקלעים אנחנו, מה הולכים לעשות?
הולכים לתת לו חלק מסוים כבר ישר בשפת מכונה. למה? כי עשינו את הקוד הזדוני שלנו. דרך אגב, איפה הוא? הוא פה, C-Sharp X64.
הנה הוא. אתם רואים? הוא כבר בשפת מכונה, כי זה מה שנתנו לי. יופי, אז אני מסמן את כל הבאפר הזה, בגודל 657 במקרה הזה. זה בתים, מספר הבתים, ואני מכניס אותו כאן.
זה הדבר הראשון שעשיתי. אני אעשה את זה על מסך מלא, שיהיה לנו יותר נוח. אז בינתיים כל מה שעשיתי זה לקחתי, הגדרתי משתנה בזיכרון באף, בשם באף, שהוא מורכב מהמון המון מספרים, 657 מספרים, כאשר כל מספר כתוב באקסה, 0x זה אומר אני כותב לך באקסה, שלא תחשוב בטעות שנניח מספר 60
זה השישים הרגיל, לא, זה 60 באקסה. מה זה 60 באקסה? בואו נראה. אם מפעילים מחשבון והולכים פה לאקסה, דרך אגב עשיתי פרוגרמר, המחשבון של מתכנתים, אקסה, אני כותב 60 באקסה, המספר ברגיל שלנו זה 96.
זו תצוגה שונה של מספר 96, במספור עד 16 זה 60, במספור של 0-1-1-0 זה כזה דבר, 1-1-0, 0-1-1. זה דרך אגב מספור עד 8, 0-7.
אז תלוי כמה ספרות יש לי, יש לי דרכים שונות להציג את אותו מספר 96. כדי שהוא לא יחשוב שזה 60 הרגיל, אני כותב לו 0x ואז הוא מבין שזה בעצם באקסה וזה אומר שזה 96 במה שאנחנו רגילים לראות אותו.
למה כותבים באקסה? כי זה יותר נוח. כל מספר באקסה, מספר אחד, ספרה אחת באקסה מסמנת בדיוק ארבע סיביות, ארבע ביטים ואז אין שום בעיות של תרגום.
אפשר לעשות תרגום ישיר, כל סיבית לארבע ביטים. לעומת זאת בדצימלי הרגיל לפעמים זה ספרה אחת, לפעמים זה שתי ספרות זה מבלבל אז זה פשוט יותר נוח לכתוב ככה זה נקרא תרגום ישיר טוב עשינו משתנה בזיכרון בשם באף בוא נעשה עוד משתנה בזיכרון נכון אתם לא מתקמצנים על כמה בתים בזיכרון על ארבע בתים בזיכרון משתנה בשם סייז למה סייז בא
לי לקרוא לו סייז ובפנים יישב בעצם הגודל של המערך הזה מה זה הגודל של המערך הזה כמה מספרים יש בתוכו כרגע אמרנו שיש בתוכו 657 מספרים אז זה המספר שיושב בפנים דרך אגב אני יכול לא לכתוב את המספר הזה להגיד לו מערך ואני ישר מאתחל אותו בגלל שאני מקים את המשתנה מקים את המערך מקציב לו זיכרון עם פקודת new וישר מאתחל בתוכו ערכים מכניס
לתוכו מספרים אז הוא ידע לבד את הגודל שלו אז הגודל שלו ייכנס פה לסייז כי אני אצטרך את הגודל הזה אני אומר לו תכניס לי פה לתא זיכרון בשם סייז במשתנה בשם סייז את הגודל, למה אני אצטרך אותו? כי אני הולך להקציב עכשיו תא שטח חדש, תא חדש של זיכרון בשם אדרס, אתם רואים? האדרס הזה, ואני משתמש בווירצ'ואל אלוקיישן. מה הוא אומר לי? הוא אומר, אני
לא יודע מה זה ווירצ'ואל אלוקיישן, אתה רוצה שנעשה איזה פונקציה? הוא אומר, מה זה הפקודה הזאת? אני לא מכיר את הפקודה הזאת, כי שכחנו לייבא את זה מתוך מערכת ההפעלה.
הוא אומר, אני לא מכיר את זה, אני יכול לבנות לך פונקציה שעושה את מה שאתה רוצה. כאילו, אני לא מכיר את זה, אני מציע לך, אולי אתה רוצה לבנות אותה לבד.
אני אומר, לא, אני שכחתי לייבא את זה. אז בואו נעלה פה למעלה. למעלה למעלה, לפני המיין שלנו, לפני הפונקציה שלנו, זאת הפונקציית מיין שאליה אנחנו נכנסים ומריצים את הקוד.
זאת הפונקציה שמורצת אוטומט. לפניה אנחנו כותבים, כאילו מחוץ לפונקציה, אבל בתוך הקלאס, לפני הפונקציה אנחנו כותבים dll import הנה צריך לעשות using יופי אז יש לנו פה using הזה שהוספנו זה אומר שאנחנו משתמשים בפונקציות של runtime interrupt services לא משנה מייבאים פונקציה שיודעת לעשות dll import לקרנל 32
מייבא מתוך קרנל 32 זה אומר מdll חיצוני מספרייה חיצונית אנחנו מייבאים משהו מה זה הספרייה החיצונית הזאת זה חלק ממערכת ההפעלה למעשה אנחנו מייבאים מבחוץ פונקציה שנקראת Virtual Allocation.
אנחנו גם מייבאים פונקציה שנקראת Create Thread. אנחנו גם מייבאים מתוך קרנל 32, מתוך ה-DLL שמייקרוסופט כתבו לנו, משתמשים בפונקציות שהם כתבו במערכת ההפעלה Wait for signal כדי שימתין שהתהליך שלי ירוץ.
זאת אומרת, הקצאת זיכרון, יצירת תהליך בזיכרון והמתנה שהוא הסתיים. ועוד משהו, אני מכריז סתם על משתנה ריק, משתנה שנקרא PageExecute Read ו-Write שהמספר שלו 40 באקסה.
סתם משתנה בזיכרון, אין לו שום משמעות, פשוט אני אשתמש בזה בפקודה אחרי זה, במקום לכתוב 0x40 אני אכתוב PageExecute Read-Write, ככה יהיה לנו יותר ברור שנדע מה זה ה-0x40 הזה.
אחרי שאני מייבא כל מיני פונקציות מ-DLL חיצוני, אני מתחיל את הקוד שלנו ב-Main, את התוכנית שלנו שנקראת Main, והיא מתחילה לרוץ, היא מייצרת את המערך הזה, אחרי זה מכניסה את הגודל של המערך לתוך משתנה בשם סייז, אחרי זה מקצה זיכרון בגודל הזה של המערך.
הקצאת הזיכרון הזאת, תא הזיכרון הזה הוא עם הרשאת אקזיקיוט מותר להריץ, אותו מותר לקרוא ממנו ומותר לכתוב אליו. זה הרשאות שיש לנו, כמו שיש לנו הרשאות על הקובץ, כך יש לנו הרשאות על אזור בזיכרון, על דפי זיכרון, כמו על קבצים.
עכשיו תשאלו אותי בשביל מה אתה מקציב זיכרון ועכשיו אתה גם הולך להעתיק לזיכרון הזה את הבאפר הזה נכון את כל מה שהיה פה אני מעתיק בעצם עושה קופי מהבאפר לזיכרון הזה את כל הגודל אני מעתיק שאלה למה לא להשתמש בתא הזיכרון הזה כי בתא הזיכרון הזה אי אפשר להריץ ממנו את הקוד האזור הזיכרון הזה של משתנה רגיל שזה למעשה סתם משתנה רגיל עם מלא מספרים אי אפשר להגיד למערכת להריץ
משם את הקוד כי אין שם הרשעת אקזיקיוט. בגלל שאין שם הרשאת אקזיקיוט אני מקציב תא חדש של זיכרון ומעתיק לשם את כל התוכן הזה. אחרי שהעתקתי את זה, אתם רואים? מרשל קופי, עשיתי קופי,