לדלג לתוכן

מה זה Shellcode, ולמה הוא נקרא ככה

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

אז מה זה בעצם

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

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

למה זה כל כך קטן ומצומצם

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

יש עוד אילוץ שהופך את זה למאתגר עוד יותר - הימנעות מבייטים "אסורים". לדוגמה, אם ה-shellcode שלכם מוזרק דרך פונקציה שמעתיקה מחרוזות (כמו strcpy), הוא לא יכול להכיל את הבייט 0x00, כי הפונקציה תעצור שם באמצע. אז חוקרי חולשות פיתחו טכניקות לכתוב shellcode שנמנע במכוון מבייטים בעייתיים, בזמן שהוא עדיין עושה בדיוק את מה שהתכוונו.

הגנות מודרניות שינו את הכללים

בעבר, הדרך הפשוטה ביותר לנצל חולשה הייתה לכתוב shellcode ישירות על הסטאק ולקפוץ אליו. הגנת NX (סימון אזורי זיכרון כלא-ניתנים-להרצה) שינתה את זה מהיסוד - היום, גם אם הצלחתם להזריק shellcode לזיכרון, המעבד פשוט מסרב להריץ אותו. זו הסיבה שנולדו טכניקות כמו ROP, שמאפשרות לעקוף את ההגנה הזאת בלי להריץ קוד "חדש" בכלל, אלא באמצעות שילוב חכם של קוד קיים בתוכנית.

עדיין, shellcode לא נעלם. במקרים רבים, גם כשמשתמשים ב-ROP, המטרה הסופית של השרשרת היא לבטל את הגנת NX (למשל דרך קריאה לפונקציה כמו mprotect) ואז בכל זאת להריץ shellcode "קלאסי". אז ROP ו-shellcode לא מחליפים אחד את השני - הם עובדים יחד.

שימושים שונים ל-shellcode

לא כל shellcode נועד "לפתוח shell". חוקרי חולשות כותבים גם:

  • Reverse shell - shellcode שגורם למכונה הנפרצת להתחבר בחזרה למכונה של התוקף, שימושי כשהמכונה הנפרצת נמצאת מאחורי חומת אש.
  • Bind shell - shellcode שפותח פורט ומחכה לחיבור נכנס.
  • Download and execute - shellcode קצר שתפקידו רק להוריד ולהריץ תוכנית גדולה יותר, מכיוון שהמקום הפנוי מוגבל מדי לקוד עשיר.

איך לומדים לכתוב shellcode

כתיבת shellcode דורשת הבנה סבירה של אסמבלי ושל קריאות מערכת (system calls) - הדרך שבה תוכנית מבקשת שירותים ממערכת ההפעלה, כמו פתיחת shell. זה שלב שמגיע בטבעיות אחרי שכבר מבינים גלישת חוצץ ואת יסודות האסמבלי, ולא נקודת התחלה.

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

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

הצטרפו לקהילה בדיסקורד

לסיכום

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