יצירת כללי זיהוי מורכבים
במאמר הזה מוסבר איך ליצור כלל מורכב בפלטפורמת Google Security Operations. התהליך כולל חיבור של כמה כללי YARA-L 2.0 כדי לזהות דפוסי תקיפה מורכבים. זיהויים מורכבים בנויים ככללים מרובי-אירועים, והם שומרים על אותה תחביר בסיסי כמו כללים רגילים של אירוע יחיד. מידע נוסף זמין במאמר סקירה כללית על זיהויים משולבים.
הסבר על מבנה הכללים
כללי זיהוי משולבים הם תמיד כללים של כמה אירועים, והם פועלים לפי אותו מבנה ותחביר כמו כלל של אירוע יחיד.
כלל מורכב כולל את הרכיבים החיוניים הבאים:
הקטע
events: מגדיר את הקלט, כלומר את הזיהויים או האירועים הספציפיים שהכלל מנתח.בקטע
match: מציינים איך לחבר את הקלטים בחלון זמן מוגדר.הקטע
condition: מכיל את הלוגיקה הסופית שקובעת אם האירועים המצורפים עומדים בקריטריונים להפעלת התראה.
הגדרת הקלט בקטע events
השלב הראשון ביצירת כלל זיהוי מורכב הוא להגדיר את הקלט של הכלל בקטע events. הקלט לכללים מורכבים מגיע מאוספים, שבהם מאוחסנים הזיהויים שנוצרו על ידי שאילתות אחרות.
ב-Google SecOps יש שתי שיטות לגשת לנתונים מאוספים.
הפניה לתוכן לזיהוי באמצעות משתנים או תוויות מטא
כדי לגשת לנתונים מזיהוי בלי להפנות לאירועי ה-UDM המקוריים,
אפשר להשתמש במשתני outcome, במשתני match או בתוויות meta. אנחנו ממליצים על הגישה הזו כי היא מספקת גמישות רבה יותר ותאימות טובה יותר בין סוגי כללים שונים.
לדוגמה, כמה כללים יכולים לאחסן מחרוזת (כמו כתובת URL, שם קובץ או מפתח רישום) במשתנה outcome משותף אם אתם מחפשים את המחרוזת הזו בהקשרים שונים. כדי לגשת למחרוזת הזו מכלל מורכב, מתחילים עם detection ומאתרים את המידע הרלוונטי באמצעות אלמנטים ממשאב האוסף.
דוגמה: נניח שכלל זיהוי מפיק את המידע הבא:
משתנה התוצאה:
dest_domain = "cymbal.com"שדה UDM:
target.hostname = "cymbal.com"
בכלל המורכב, אפשר לגשת לנתונים האלה באמצעות הנתיבים הבאים:
detection.detection.variables["dest_domain"].string_valכדי לגשת למשתנה התוצאהdest_domain.
detection.collection_elements.references.event.target.hostnameכדי לגשת לשדהtarget.hostnameב-UDM.detection.time_window.start_time.secondsכדי לגשת לחותמת הזמן של תחילת הזיהוי.
Collection API ו-SecurityResult API מספקים גישה לשני סוגי הנתונים:
- מטא-נתונים של זיהוי וערכי תוצאות (
detection.detection) - אירועי UDM בסיסיים מכללים שמפנים אליהם (
collection_elements)
תוכן של זיהוי הפניות עם מזהה או שם של כלל
אפשר להפנות לכלל לפי השם או המזהה שלו. אנחנו ממליצים על הגישה הזו אם לוגיקת הזיהוי שלכם תלויה בכללים ספציפיים ואתם רוצים לצמצם את הנתונים שמנותחים רק לתוצאות של הכללים האלה. הפניה לכללים רלוונטיים לפי שם או מזהה משפרת את הביצועים ומונעת זמן קצוב לתפוגה על ידי צמצום הנתונים המנותחים. לדוגמה, אתם יכולים לשלוח שאילתה ישירות לשדות כמו target.url או principal.ip מזיהוי קודם ידוע.
הפניה לכלל לפי מזהה הכלל (מומלץ): משתמשים בשדה
detection.detection.rule_idכדי להפנות לכלל לפי המזהה. מזהה הכלל מופיע בכתובת ה-URL של הכלל ב-Google SecOps. לכללים שנוצרו על ידי משתמשים יש מזהים בפורמטru_UUID, ולגלאים מוכנים מראש יש מזהים בפורמטur_UUID. לדוגמה:detection.detection.rule_id = "ru_e0d3f371-6832-4d20-b0ad-1f4e234acb2b"הפניה לכלל לפי שם הכלל: משתמשים בשדה
detection.detection.rule_nameכדי להפנות לכלל לפי שם. אפשר לציין את השם המדויק של הכלל או להשתמש בביטוי רגולרי כדי להתאים אותו. לדוגמה:detection.detection.rule_name = "My Rule Name"detection.detection.rule_name = "/PartOfName/"
איחוד מקורות קלט בקטע match
כדי לקשר בין זיהויים, אירועים או ישויות שקשורים זה לזה בכלל מורכב, מגדירים את הקטע match באמצעות משתנים שהוגדרו בקטע events. המשתנים האלה יכולים לכלול תוויות של כללים, משתני תוצאה, משתני התאמה, שדות זיהוי או רכיבי איסוף.
מידע על התחביר מופיע במאמר בנושא תחביר של קטע התאמה.
כללים מורכבים: אינטרוולים של זמן וחלונות של קפיצות
כללים מורכבים מתאימים לזיהויים ולאירועים במרווח זמן ולא בנקודת זמן יחידה. הם תואמים לחלון קפיצה מורכב אם חלון הזמן של זיהוי הקלט חופף לחלון הקפיצה הזה (לדוגמה, הפעילות הייתה פעילה במהלך בלוק הזמן הזה).
זיהוי אחד יכול להפעיל כמה התראות אם הזיהוי משתרע על הגבול בין חלונות קצובים סמוכים (בגלל עיכובים בצינור עיבוד הנתונים, ההתאמות ההיסטוריות האלה מופיעות מאוחר יותר). באופן ספציפי, חלון קצוב של כלל מורכב מפעיל התאמה אם חלון הזמן של זיהוי הקלט (WindowStart עד WindowEnd) חופף לחלון הקצוב.
לדוגמה:
- חלונות הקפיצה של כלל מורכב הם של 60 דקות: קפיצה 1 (18:58 עד 19:58) וקפיצה 2 (19:58 עד 20:58).
- גלאי של יצרן במעלה הזרם מזהה חלון של 19:57:54 עד 20:56:54 (משך של 59 דקות).
- חלון ההפקה התחיל בשעה 19:57:54 (6 שניות לפני שהקפיצה הראשונה הסתיימה) והסתיים בשעה 20:56:54 (במהלך הקפיצה השנייה), ולכן יש חפיפה בין חלון ההפקה לבין שני חלונות הקפיצה.
- הפעולה הזו מפעילה שני זיהויים מורכבים (אחד עבור קפיצה 1 ואחד עבור קפיצה 2), ועוזרת למנוע תוצאות שליליות שגויות. אם כלל היצרן לא תאם בחפיפה, לא תתבצע בדיקה של החפיפה החלקית עבור קפיצה 1 או קפיצה 2, והקשר בין הזיהוי לבין אירועים אחרים יוחמץ.
מידע נוסף ודוגמאות לאופן שבו מציינים חלונות קצובים (hopping window) זמינים במאמר בנושא חלונות קצובים (hopping window).
הגדרת הקטע "condition"
מגדירים את הקטע condition כדי להעריך את התוצאות של הקטע match.
אם התנאי הוא true, נוצרת התראה. מידע על התחביר מופיע במאמר תחביר של קטע התנאים.
החלת טכניקות מתקדמות על כללים מורכבים
כאן מוסבר איך להשתמש בשיטות מתקדמות כשיוצרים כללים מורכבים.
שילוב של אירועים וזיהויים
כללים מורכבים יכולים לשלב כמה מקורות נתונים, כולל אירועי UDM, נתוני תרשים ישויות ושדות זיהוי. ההנחיות הבאות רלוונטיות:
שימוש במשתנים נפרדים לכל מקור: מקצים משתני אירוע ייחודיים לכל מקור נתונים (לדוגמה,
$eלאירועים,$dלזיהויים), כאשר מקור הנתונים כולל אירועים, ישויות וזיהויים.איחוד מקורות על סמך הקשר משותף: אפשר לקשר בין מקורות נתונים באמצעות ערכים משותפים, כמו מזהי משתמשים, כתובות IP או שמות דומיין בתנאים של הכלל.
הגדרת חלון התאמה: תמיד צריך לכלול פסקה
matchעם חלון זמן של עד 48 שעות.
דוגמה: שילוב של אירועים וזיהויים
rule CheckCuratedDetection_with_EDR_and_EG {
meta:
author = "noone@cymbal.com"
events:
$d.detection.detection.rule_name = /SCC: Custom Modules: Configurable Bad Domain/
$d.detection.collection_elements.references.event.network.dns.questions.name = $domain
$d.detection.collection_elements.references.event.principal.asset.hostname = $hostname
$e.metadata.log_type = "LIMACHARLIE_EDR"
$e.metadata.product_event_type = "NETWORK_CONNECTIONS"
$domain = re.capture($e.principal.process.command_line, "\\s([a-zA-Z0-9.-]+\\.[a-zA-Z0-9.-]+)$")
$hostname = re.capture($e.principal.hostname, "([^.]*)")
$prevalence.graph.metadata.entity_type = "DOMAIN_NAME"
$prevalence.graph.metadata.source_type = "DERIVED_CONTEXT"
$prevalence.graph.entity.hostname = $domain
$prevalence.graph.entity.domain.prevalence.day_count = 10
$prevalence.graph.entity.domain.prevalence.rolling_max <= 5
$prevalence.graph.entity.domain.prevalence.rolling_max > 0
match:
$hostname over 1h
outcome:
$risk_score = 80
$CL_target = array($domain)
condition:
$e and $d and $prevalence
}
יצירת זיהויים מורכבים רציפים
זיהויים משולבים ברצף מזהים דפוסים של אירועים קשורים שבהם רצף הזיהויים חשוב, כמו זיהוי של ניסיון התחברות באמצעות כוח גס, ואחריו התחברות מוצלחת. הדפוסים האלה יכולים לשלב כמה זיהויים בסיסיים, אירועי UDM גולמיים או שילוב של שניהם.
כדי ליצור זיהוי משולב ברצף, צריך לאכוף את הסדר הזה בתוך הכלל. כדי לאכוף את הרצף הצפוי, משתמשים באחת מהשיטות הבאות:
חלונות נעים: הגדרת רצף של זיהויים באמצעות חלונות נעים בתנאי
match.השוואות של חותמות זמן: השוואה בין חותמות הזמן של הזיהויים בלוגיקה של הכלל כדי לוודא שהם מתרחשים בסדר שנבחר.
דוגמה: זיהויים מורכבים רציפים
events:
$d1.detection.detection.rule_name = "fileEvent_rule"
$userid = $d1.detection.detection.variables["user"].string_val
$hostname = $d1.detection.detection.variables["hostname"].string_val
$d2.detection.detection.rule_name = "processExecution_rule"
$userid = $d2.detection.detection.variables["user"].string_val
$hostname = $d2.detection.detection.variables["hostname"].string_val
$d3.detection.detection.rule_name = "networkEvent_rule"
$userid = $d3.detection.detection.variables["user"].string_val
$hostname = $d3.detection.detection.variables["hostname"].string_val
$d3.detection.collection_elements.references.event.metadata.event_timestamp.seconds > $d2.detection.collection_elements.references.event.metadata.event_timestamp.seconds
match:
$userid over 24h after $d1
הבעיה עדיין לא נפתרה? קבלת תשובות מחברי הקהילה וממומחי Google SecOps.