לדלג לתוכן

0.2 סביבת העבודה תרגול

תרגול - הקמת סביבת העבודה

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

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

הכינו קובץ הדגמה בשם demo.c בתיקיית עבודה נקייה:

#include <stdio.h>

void win() {
    printf("You reached win()!\n");
}

void vuln() {
    char buf[64];
    printf("input> ");
    gets(buf);          // intentionally vulnerable - do not use gets in real code
    printf("got: %s\n", buf);
}

int main() {
    vuln();
    return 0;
}

תרגיל 1 - התקנת הבסיס והמהדר

התקינו את סביבת הבנייה והמנפה, והדרו את demo.c פעם אחת עם ברירות המחדל של gcc.

  • ודאו ש-gcc --version ו-gdb --version עובדים.
  • הדרו: gcc -o demo demo.c (התעלמו מהאזהרה על gets, היא מכוונת).
  • הריצו את הבינארי ותנו לו קלט קצר, וודאו שהוא מדפיס אותו בחזרה.

רמז: אם gcc לא מותקן, החבילה שאתם מחפשים היא build-essential.


תרגיל 2 - התקנת pwntools ותוסף ה-gdb

התקינו את שתי אבני היסוד של הקורס.

  • התקינו את pwntools (מומלץ בתוך venv של פייתון).
  • התקינו את pwndbg (או GEF) כך שייטען אוטומטית בכל הפעלה של gdb.
  • ודאו שהתוסף נטען: פתחו gdb על ./demo והריצו את הפקודה checksec מתוך gdb.

רמז: אחרי ./setup.sh של pwndbg, פתחו gdb מחדש כדי שקובץ ~/.gdbinit ייקרא.

רמז נוסף: אם checksec בתוך gdb נותן שגיאה של "פקודה לא מוכרת", התוסף לא נטען - בדקו את ~/.gdbinit.


תרגיל 3 - הידור בכמה תצורות וקריאת checksec

זה הלב של התרגול. הדרו את demo.c בארבע תצורות שונות, כל אחת עם שם קובץ אחר, והריצו checksec על כל אחת:

  1. התצורה demo_default - ברירות מחדל של gcc (בלי דגלים נוספים).
  2. התצורה demo_nocanary - בלי canary.
  3. התצורה demo_nonx - עם מחסנית ניתנת להרצה (בלי NX).
  4. התצורה demo_nopie_static - בלי PIE וקישור סטטי.

לכל בינארי, רשמו לעצמכם את ערכי חמשת השדות: RELRO, Stack Canary, NX, PIE. ענו על השאלות:

  • איזה דגל גרם ל-Stack Canary להיעלם?
  • באיזו תצורה NX הפך ל-disabled, ולמה זה מסוכן?
  • מה קרה לגודל הקובץ ב-demo_nopie_static לעומת השאר, ולמה?

רמז: הדגלים הרלוונטיים הם -fno-stack-protector, -z execstack, -no-pie, -static. חזרו לטבלה בהרצאה.


תרגיל 4 - שאר ארגז הכלים

התקינו את הכלים שנשתמש בהם בפרקים הבאים, וודאו שכל אחד רץ:

  • התקינו ROPgadget ו-ropper, והריצו אותם על demo_nopie_static (חפשו גאדג'ט pop rdi ; ret). למה דווקא לבינארי הסטטי יש הרבה יותר גאדג'טים?
  • התקינו one_gadget והריצו אותו על ה-libc של המערכת. כמה כתובות קסם הוא מצא, ואילו תנאים (constraints) מופיעים לצידן?
  • התקינו ltrace, והריצו ltrace ./demo_default. אילו פונקציות ספרייה אתם רואים?
  • לבחירתכם: התקינו qemu-user ו-gdb-multiarch לקראת אתגרי ה-ARM בהמשך.

רמז: one_gadget מקבל נתיב ל-libc.so.6, לא לבינארי שלכם. מצאו את הנתיב עם ldd ./demo_default.


תרגיל 5 - כיבוי ASLR ובדיקת גרסת glibc

  • בדקו את מצב ה-ASLR הנוכחי, כבו אותו זמנית, וודאו שהערך השתנה.
  • מצאו את גרסת ה-glibc המדויקת של המערכת שלכם. רשמו אותה - תזדקקו לה כשנעבוד מול אתגרים מרוחקים.

רמז: מצב ה-ASLR נמצא בקובץ /proc/sys/kernel/randomize_va_space. גרסת ה-glibc מתקבלת מ-ldd --version.


אתגר סיום - הרצה של הכל דרך pwntools

כתבו סקריפט פייתון קצר שטוען את demo_default עם context.binary = ELF('./demo_default'), פותח אותו עם process, שולח קלט קצר ומדפיס את התשובה. המטרה כאן היא רק לוודא ש-pwntools מדבר עם הבינארי - זה השלד שנבנה עליו בכל שאר הקורס.

רמז: p.recvall(timeout=1) יתפוס את כל הפלט אחרי שליחת הקלט.

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