Posts

AFL Under the hood (Part 1)

בפוסט הקודם נתתי הקדמה לפאזר AFL – איך הוא עובד ברמה הגבוהה, מהם השימושים שלו וגם דוגמה פשוטה לאופן השימוש בו. כעת, לאחר שהכרנו את הכלי במבט על, הגיע הזמן לצלול למימוש הפנימי שלו – נביט בקוד של AFL עצמו ואיך הוא מיישם את הרעיונות שמנחים את הפאזר. מה קורה ב afl-gcc ו afl-as ? בואו ניזכר בשלב הראשון של השימוש בפאזר, שהוא לקמפל את קוד המקור עם afl-gcc . התוצר של הפעולה הזאת הוא הבינארי שלנו עם קוד אינסטרומנטציה בתוכו. למעשה, afl-gcc הוא לא יותר ממעטפת קטנה, שמוסיפה \ עורכת כמה פרמטרים ל gcc וגורמת לו להשתמש באסמבלר אחר, שהוא afl-as – שם קורה הקסם האמיתי והאינסטרומנטציה נוספת אל התוכנית שלנו. הקלט שמועבר אל afl-as הוא קוד אסמבלי שעבר קומפילציה של gcc (יש לזכור שכשאומרים קומפילציה לעיתים מתכוונים להפוך קוד לתוצר הסופי, executable , אך לתהליך זה יש כמה תחנות בדרך: compiler->assembler->linker . אנחנו בתחנה האמצעית ועלינו להפוך קוד אסמבלי להוראות מכונה שהמעבד מבין). החלק המעניין מתחיל בפונקציה add_instrumentation ב afl-as.c . הפונקציה בודקת תחילה אם אנחנו נמצאים ב text section ,...

AFL מבוא לפאזינג עם

Image
כמה מילים על פאזינג ותיאוריה בסיסית  פאזינג (Fuzzing) זו שיטה לבדיקת תוכנה, שבבסיסה עומד הרעיון להקריס את התוכנה ע"י מתן קלט לא תקין, קלט אקראי או לא צפוי. באמצעות שיטה זו מוצאים כיום את רוב החולשות בבינארים, והפאזרים חוסכים זמן יקר לחוקרים שיכולים להקדיש אותו לדברים אחרים כמו ניצול החולשות.  אמנם מתן קלט אקראי לגמרי לתוכנה הוא סוג של פאזינג, אך זו לא השיטה שבה עובדים כיום רוב הפאזרים – ניתן לייעל את התהליך:  דרך אחת היא לקחת קלט משתמש תקין ולהתחיל לעוות אותו (להפוך ביט בקלט, אם זה מספר להגדיל אותו או להקטין אותו, לחזור על הקלט וכו') במקום להתחיל מאפס וליצור קלטים אקראיים לחלוטין.  דרך נוספת היא מעקב אחר הזרימה של התוכנה, לראות לאיזה קוד קלט מסוים מוביל אותנו ואם היינו כבר באזור הזה בקוד או שנחשפנו ל"ענף" חדש שהקלט הוביל אותנו אליו. זה נעשה באמצעות הכנסת הוראות נוספות לתוכנה במקומות אסטרטגיים (לדוגמה לפני או אחרי jmpים, קריאות לפונקציות) שיעזרו לנו להבין איפה אנחנו נמצאים בקוד וישלחו את המידע לכלי שלנו. טכניקה זו נקראת אינסטרומנטציה (instrumentation). מה זה AFL ? ...