מטושטשת חלק 2

Fuzzing Part 2 - Fuzzing עם AFL

כפי שכתבתי ב פרק אחרון, במאמר זה אסביר רק כיצד לטשטש כאשר יש גישה לקוד המקור באמצעות AFL. כדי להדגים, לקחתי תוכנת קוד פתוח ישנה שמצאתי ב-GitHub בשם cccalc. כפי שהשם מרמז, זהו מחשבון פשוט שנכתב ב-C. בחרתי בו כי סביר להניח ש-fuzzing ימצא בו בקלות קריסות רבות, וכפי שתראו, השערה זו התבררה כנכונה.

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

ה-main() המקורי נראה פחות או יותר כך (קיצרתי אותו מעט):

הפונקציה העיקרית

בדרך כלל, הוא מכיל שני ענפים: או שהוא מקבל קלט דרך argc, argv[], או דרך קלט רגיל (stdin). אני לא בטוח למה, אבל היוצר של AFL ממליץ במפורש לֹא לטשטש דרך argc, argv[], וכך גם כל שאר המקורות המקוונים. אז שיניתי את זה קצת: קודם כל הסרתי את הקטע שעוסק בקלט שמגיע ממנו argc, argv, ולאחר מכן ניסיתי לייעל אותו ככל האפשר. אחרי הכל, בכל פעם שה-fuzzer מנסה קלט אחר, פונקציה זו מבוצעת. לכן חוסר יעילות יכול להוביל להאטות חמורות. הנה התוצאה הסופית:

תפקיד עיקרי לאחר שינוי

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

קראתי לקובץ עם הפונקציה המשתנה harness.c, וכדי להרכיב את התוכנה עם הקובץ הזה ולא עם main.c, שיניתי את טופס הקובץ automake:

קובץ automake לפני השינוי

ל

קובץ automake לאחר השינוי

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

פקודת automake

כך שהתוכנית תתחבר עם מכשור AFL.

הדבר היחיד שנותר לעשות כעת הוא ליצור את תיקיית הקלט הראשונית עבור AFL, לה קראתי 'in', ואת תיקיית הפלט 'out'. בתיקיית הקלט, שמים קבצי טקסט פשוטים (ללא פורמט) המכילים קלט לגיטימי, כמו "20/2" או "5*4". מכיוון שאנו רוצים להפעיל כמה תהליכי AFL (כל תהליך פועל על ליבת המעבד שלו), אנו יוצרים תיקיית קלט נפרדת עבור כל תהליך.

תיקיית קלט עבור כל תהליך

על מנת לטשטש, פשוט מפעילים את הפקודה:

פקודת הפעלת AFL לשימוש ראשון

לתהליך הראשון, ההוויה השנייה

פקודת הפעלת AFL לשימוש שני

וכן הלאה וכן הלאה.

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

AFL התקדמות GUI
AFL התקדמות GUI

לאחר שנמצאה כמות מספקת (המספר המדויק תלוי בך) של קריסות, בדרך כלל לאחר פרק זמן ארוך ללא התרסקות ייחודית חדשה, תוכל להפסיק את התהליך. עבור כל תהליך של AFL שאתה מפעיל, תיקיה נפרדת תיווצר בתיקיית הפלט:

תיקיית פלט

בתוך התיקיות הללו, הנתונים מסודרים כך:

פלט תוכן תיקיה

חשוב להסביר איזה מידע מכיל כל אחד מאלה:

  • plot_data - מעמיד את המידע בצורה מוליך ליצירת עלילה.
  • fuzzer_stats - סטטיסטיקות על תהליך ה-fuzzing.
  • fuzz_bitmap - מפת סיביות שבה כל בייט מתאים לענף של התוכנית.
    "AFL שומרת על "מפת סיביות של fuzz", כאשר כל בייט בתוך מפת הסיביות מייצג ספירה של מספר הפעמים שענף מסוים בתוך התוכנית המטושטשת נלקח. AFL לא מבצע מיפוי אחד לאחד בין ענף מסוים לבין בתים בתוך מפת הסיביות. במקום זאת, המכשור המוטבע של AFL מציב מזהה קבוע של שני בתים אקראי בכל ענף. בכל פעם שהביצוע מגיע לסניף מכשיר, AFL מבצע XOR של מזהה הסניף החדש ומזהה הסניף האחרון שנראה לפני ההגעה לסניף החדש. זה לוכד גם את הענף הנוכחי וגם את הנתיב הייחודי שנלקח כדי להגיע אליו (כגון כאשר אותה פונקציה נקראת ממספר מיקומים בקוד). לאחר מכן AFL מחיל פונקציית גיבוב על הערך XOR'd כדי לקבוע איזו ערך במפת הסיביות מייצגת את שילוב הענף הזה. בכל פעם ששילוב ענף מסוים מופעל, הבתים המתאים מוגדלים בתוך מפת הסיביות."
  • cmdline - הפקודה שסופקה ל-AFL. בפועל שם התוכנית.
  • .cur_input - הקלט הנוכחי.
  • queue - כל הקלט שנוסה עד עכשיו.
  • קורס ונתקע - התוצאות. כל קובץ בתיקיות אלה מכיל קלט שגרם לקריסות או להיתקע. מצוין בשם של כל קובץ הוא אות הקרנל של הקריסה (לא רלוונטי ב-hangs, כמובן), המזהה של הקלט המשמש את AFL ליצירת הקלט שגרם לקריסה, הזמן שחלף מאז החל AFL לרוץ, והמוטציה המשמשת ליצירת הקלט מהזרע שלה.
עבור לתוכן