הסבר על Sandbox2

העיצוב של Sandbox2 מבוסס על טכנולוגיות מוכרות ומבוססות, מסגרת מדיניות ושני תהליכים: Sandbox Executor ו-Sandboxee.

הטכנולוגיות שמעורבות בתהליך

בקטעים הבאים מוסבר על הטכנולוגיות שמרכיבות את שכבת הבסיס של Sandbox2.

מרחבי שמות של Linux

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

  • IPC
  • רשת (אלא אם היא מושבתת באופן מפורש על ידי שיחה עם PolicyBuilder::AllowUnrestrictedNetworking())
  • טעינה (באמצעות תצוגה מותאמת אישית של עץ מערכת הקבצים)
  • PID
  • משתמש
  • UTS

מידע נוסף על מרחבי שמות של Linux זמין בויקיפדיה או בדף ה-man הרלוונטי.

IPC

‫Sandbox2 מאפשר להחליף נתונים שרירותיים בין Sandbox Executor לבין Sandboxee לא מהימן. הוא תומך בהודעות מסוג Type-Length-Value ‏ (TLV), בהעברת תיאורי קבצים ובחילופי פרטי כניסה באמצעות טוקנים ומזהים.

Seccomp-BPF

‫Sandbox2 מסתמך על seccomp-bpf, שהוא תוסף למצב מחשוב מאובטח (seccomp) שמאפשר להשתמש בכללי Berkeley Packet Filter (BPF) כדי לסנן קריאות למערכת.

‫seccomp הוא מתקן ליבה של Linux שמגביל את קריאות המערכת של תהליך, כך שרק exit, sigreturn, read ו-write מותרים. אם תהליך ינסה להפעיל קריאת מערכת אחרת, הוא יופסק. התוסף seccomp-bpf מאפשר יותר גמישות מאשר seccomp. במקום לאפשר קבוצה קבועה של קריאות מערכת, seccomp-bpf מפעיל תוכנית BPF על נתוני קריאות המערכת, ובהתאם לערך ההחזרה של התוכנית, הוא יכול להפעיל את קריאת המערכת, לדלג על קריאת המערכת ולהחזיר ערך פיקטיבי, לסיים את התהליך, ליצור אות או להודיע לכלי המעקב.

Ptrace

קריאת המערכת ptrace (process trace) מספקת פונקציונליות שמאפשרת לתהליך המעקב לצפות בהרצה של תהליך המעקב ולשלוט בה. לתהליך של הכלי למעקב יש שליטה מלאה על התהליך הנעקב אחרי שהוא מצורף אליו. מידע נוסף על ptrace זמין בויקיפדיה או בדף המדריך הרלוונטי.

מדיניות ארגז החול

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

  • מדיניות Syscall
  • הגדרת מרחב שמות

מדיניות ברירת המחדל של קריאות המערכת

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

מדיניות מורחבת של קריאות מערכת

אפשר ליצור את מדיניות ה-syscall המורחבת באמצעות המחלקה PolicyBuilder. המחלקה הזו מגדירה כמה כללים נוחים (למשל AllowStaticStartup, ‏ AllowDynamicStartup, ‏ AllowOpen) שאפשר להשתמש בהם כדי לשפר את הקריאוּת של המדיניות.

ברוב המקרים, עדיף להתחיל עם DefaultPolicyBuilder (sapi::Sandbox2Config::DefaultPolicyBuilder()), שמחזיר PolicyBuilder שהוגדר מראש עם מדיניות בסיסית לספריות טיפוסיות עם שרשור יחיד, וניתן להתאים אותו אישית עם כללים נוספים (כמו .AllowDynamicStartup() ו-.AddLibrariesForBinary() כשמפעילים ארגז חול על קובץ בינארי). ב-Sandboxed API‏ (SAPI), DefaultPolicyBuilder() משמש את sapi::SandboxConfig::DefaultConfig() יחד עם sapi::SandboxConfig::DefaultFlags(),‏ sapi::SandboxConfig::DefaultEnvironmentVariables() ו-sapi::Sandbox2Config::DefaultLimits(). מומלץ ליצור PolicyBuilder ישירות רק אם אי אפשר להשתמש ב-DefaultPolicyBuilder() או אם נדרשת הגדרה מדויקת.

אם רוצים להגביל עוד יותר את קריאות המערכת או לדרוש כללים מורכבים יותר, אפשר לציין פקודות מאקרו גולמיות של BPF באמצעות AddPolicyOnSyscall ו-AddPolicyOnSyscalls. בדוגמה של crc4 נעשה שימוש במנגנון הזה כדי להגביל את הארגומנטים של קריאות המערכת read,‏ write ו-close.

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

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

הגדרת מרחב שמות

האובייקט PolicyBuilder משמש גם להגדרת התצוגה הנפרדת של מערכת הקבצים ב-Sandboxee. אפשר למפות לסביבה של ה-Sandboxee קבצים בודדים (AddFile / AddFileAt), ספריות שלמות (AddDirectory / AddDirectoryAt) וגם אחסון זמני (AddTmpfs). בנוסף, אפשר להשתמש ב-AddLibrariesForBinary כדי למפות באופן אוטומטי את כל הספריות שנדרשות לקובץ ההפעלה שצוין, שמקושר באופן דינמי.

תכונות ניסיוניות בשורת הפקודה

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

  • --sandbox2_danger_danger_permit_all
  • --sandbox2_danger_danger_permit_all_and_log

Sandbox Executor

Sandbox Executor הוא תהליך שלא נמצא בעצמו בארגז חול. זהו תהליך המעקב ptrace שמתחבר אל Sandboxee (תהליך המעקב ptrace). ה-Sandbox Executor גם מגדיר ומריץ מכונה של Monitor שעוקבת אחרי ה-Sandboxee ומספקת מידע על הסטטוס.

ב-Sandbox2 יש שלושה מצבי הפעלה: עצמאי, Sandbox2 Forkserver ו-Custom Forkserver. אם משתמשים ב-forkserver, ה-Sandboxee נוצר כתהליך צאצא של Sandbox Executor. הסבר מפורט על המצבים האלה מופיע כאן.

Sandboxee

ה-Sandboxee הוא התהליך שפועל בסביבה המוגבלת של ארגז החול, שהוגדרה על ידי מדיניות ארגז החול. ‫Sandbox Executor שולח את המדיניות ל-Sandboxee באמצעות IPC. לאחר מכן, ה-Sandboxee מחיל את המדיניות. כל הפרה של המדיניות תוביל לסיום התהליך, אלא אם הוגדר אחרת (ראו מדיניות ארגז החול).