מעבר מ-SPL ל-YARA-L 2.0
המדריך הזה מיועד למשתמשים שכבר מכירים את שפת עיבוד החיפוש (SPL) של Splunk. הוא מספק מבוא קצר ל-YARA-L 2.0: שפת הליבה ליצירת חיפושים, מרכזי בקרה וכללי זיהוי ב-Google Security Operations.
הסבר על המבנה של YARA-L 2.0
YARA-L 2.0 היא שפת השאילתות המאוחדת שמשמשת ב-Google SecOps לחיפוש איומים מתקדם, ליצירת לוחות בקרה בזמן אמת וליצירת כללי זיהוי ברמת דיוק גבוהה בכל נתוני היומן של הארגון בזמן שהם מוזנים למערכת.
השפה פועלת בשילוב עם מנוע הזיהוי של Google SecOps ומאפשרת לכם לחפש איומים ואירועים אחרים בכמויות גדולות של נתונים.
הבדלים בסיסיים במבנה בין SPL ל-YARA-L
ב-SPL משתמשים בסדרה של פקודות שמשורשרות יחד עם תווי קו אנכי (|), ואילו YARA-L מבוססת על קטעים. אתם מגדירים שאילתה באמצעות קטעים נפרדים – כמו events, outcome ו-condition – כדי לתאר תבנית שאתם רוצים לחפש, לזהות או להציג.
בטבלה הבאה מוצגת השוואה בין המבנה הבסיסי של SPL לבין המבנה של YARA-L:
| פונקציה | SPL (פרוצדורלי) | YARA-L (declarative) |
|---|---|---|
| מושג מרכזי | לבצע טרנספורמציה של זרם נתונים שלב אחר שלב באמצעות צינור עיבוד נתונים של פקודות. | ניתוח והחלה של מבנה מרובה חלקים של תנאים וטרנספורמציות על זרם של נתוני אבטחה ותפעול, זיהוי איומים וחילוץ תובנות חשובות. |
| זרימת נתונים | פרוצדורלי. התוצאות של פקודה אחת מועברות כקלט לפקודה הבאה. | מבנה הצהרתי לעיבוד אופטימלי של דפוסים בקנה מידה עצום וליצירת קורלציה ביניהם. כך לא צריך לחשוב על יעילות. |
| קורלציה בין אירועים | מסתמך על פקודות מפורשות כמו join, transaction ו-stats. |
מובנה על ידי הגדרת כמה אירועים והתאמה ביניהם על סמך שדה משותף בלוגי של השאילתה. |
| עיבוד החלק הנצפה בלבד | החיפוש מתבצע בחלון חיפוש סטטי (לדוגמה, last
60m). כל חיפוש חדש הוא בקשה חדשה. |
הטיפול הוא כחלון זמן רציף ומשתנה שמוגדר בתוך השאילתה (לדוגמה, over 5m). |
| תחביר | מבוססות על פקודות (לדוגמה, index=web). |
תמציתי ומבוסס על לוגיקה (לדוגמה, metadata.event_type=
"USER_LOGIN"). |
מבנה ספציפי של שאילתות
ב-YARA-L יש מבנה ספציפי לשאילתות, ששונה מהפקודות הרציפות עם צינורות (|) של SPL. ב-SPL, התוצאות נוצרות על ידי שרשור פקודות, אבל ב-YARA-L, היבטים שונים של השאילתה מוגדרים בקטעים נפרדים.
כל שאילתה או כלל ב-YARA-L מחולקים לקטעים נפרדים עם שמות, שקובעים את ההתנהגות של השאילתה. המבנה הזה מאפשר ניתוח רב-שלבי ומתאם.
| פקודה | פעולה | אופציונלי | חובה |
|---|---|---|
meta |
הגדרה של מטא-נתונים תיאוריים לכלל, כמו מחבר, תיאור וחומרה. | אופציונלי לחיפוש וללוחות בקרה. נדרש רק לכללים. |
events |
מגדיר ומסנן אירועים. מגדיר את כל מקורות הנתונים (בעיקר אירועי UDM) שצריך לקחת בחשבון ומסנן אותם באמצעות שדות UDM. מידע נוסף על התחביר של הקטע [`events`](/chronicle/docs/yara-l/events-syntax) | חובה (הלוגיקה המרכזית של השאילתה) לחיפוש, למרכזי בקרה ולכללים. |
match |
הכלל מקבץ לפי אירועים ומאפשר לציין את חלון הזמן הנתמך (לדוגמה, by 5m). מידע נוסף על [התחביר של הקטע `match`](https://docs.cloud.google.com/chronicle/docs/yara-l/match-syntax) |
אופציונלי עבור חיפושים סטטיסטיים שבהם מתבצעת צבירה. נדרש רק לשאילתות של התאמה בין כמה אירועים. חובה לציין זמן בכללים, ואפשר לציין זמן בחיפושים ובמרכזי בקרה. |
outcome |
מחשב מדדים חיוניים ומקבל תובנות (לדוגמה, count(), avg()). מידע נוסף על תחביר הקטע [outcome] |
זה שינוי אופציונלי. |
condition |
הגדרת הלוגיקה שצריכה להתקיים כדי להחזיר תוצאות (בחיפוש) או להפעיל התראה (בכלל). הפונקציה מעריכה את הקריטריונים של משתנה השאילתה כדי לקבוע אם התוצאה רלוונטית (לדוגמה, event > 5). מידע נוסף על התחביר של הקטע [<code>condition</code>](/chronicle/docs/yara-l/condition-syntax) |
אופציונלי בחיפוש ובמרכזי הבקרה. נדרש רק לכללים. |
dedup |
הסרת אירועים כפולים על ידי קיבוץ שלהם על סמך משתנים חיוניים (לדוגמה, target.user.userid, target.ip, principal.hostname). מידע נוסף על [שימוש בביטול כפילויות בחיפוש ובלוחות הבקרה](/chronicle/docs/investigation/deduplication-yaral). |
זה שינוי אופציונלי. לא זמין בכללים. |
order |
ממיין את התוצאות של אירועים שנאספו לפי שדות ספציפיים (לדוגמה, asc). |
אופציונלי (רלוונטי רק כשמשתמשים ב-match). לא זמין בכללים. |
limit |
מגביל את המספר המקסימלי של אירועים שמוחזרים מהשאילתה. | אופציונלי (רלוונטי רק כשמשתמשים בהתאמה). לא זמין בכללים. |
select |
מציין את רשימת השדות של UDM שייכללו בתוצאות השאילתה. | זה שינוי אופציונלי. לא זמין בכללים. |
unselect |
מציינת את רשימת השדות של UDM שצריך להחריג מתוצאות השאילתה. | זה שינוי אופציונלי. לא זמין בכללים. |
פקודות נפוצות ב-SPL וב-YARA-L
מבנה הקטעים של YARA-L מאפשר להשתמש באותן פקודות נפוצות שקיימות ב-SPL. בקטע הזה מפורטים נקודות הדמיון וההבדלים.
פקודת SPL search = קטע YARA-L events
הפקודה search ב-SPL מקבילה לקטע events ב-YARA-L. בקטע events מוגדרים האירועים ואופן הסינון הראשוני שלהם. סעיפים אחרים (כמו match או outcome) הם אופציונליים, אבל סעיף events הוא בסיסי לכל כלל.
לדוגמה:
metadata.event_type = "USER_LOGIN"
או:
principal.hostname != "" AND metadata.event_type = "NETWORK_CONNECTION"
בקטע events של כללים (ובשאילתות מתקדמות), משתמשים במשתני אירוע כדי לפשט את הלוגיקה.
משתנה אירוע פועל כקיבוץ לוגי של מסננים, ומייצג אירוע ספציפי או קבוצת אירועים שעומדים בקריטריונים מסוימים.
לדוגמה, כדי להגדיר משתנה אירוע, כמו $e, משתמשים בו כקידומת לכל האירועים והמסננים שקשורים אליו בקטע events של השאילתה. אחר כך אפשר להשתמש במשתנה הזה בקטעים אחרים של השאילתה (כמו match או outcome) כדי להפנות לקבוצה הספציפית הזו של אירועים ושדות הנתונים שלהם.
השימוש הכי נפוץ במשתני אירועים הוא בכללי זיהוי. בדוגמה הבאה אפשר לראות איך משתמשים במשתנה event ($e) בכלל כדי לקבץ אירועים ולמצוא את מספר ניסיונות הכניסה שנכשלו של משתמש ביום אחד. הכלל מופעל אם הוא חורג מהסף שהוגדר.
בדוגמה של הכלל, כל אירוע מוגדר באמצעות משתנה האירוע ($e). יש גם הפניה למשתנה $e ב-metadata.id כדי לקשר את המטא-נתונים של הכלל בחזרה לאירועים המוגדרים.
rule DailyFailedLoginAttempts {
meta:
author = "Alex"
description = "Detects a high number of failed login attempts for a single user within a day."
events:
// Alias for each event
$e.metadata.event_type = "USER_LOGIN"
$e.security_result.action = "FAIL"
$e.principal.user.userid != ""
$userid = $e.principal.user.userid
match:
// Group events by principal.user.userid within a 24-hour window
$userid over 1d
outcome:
// Count the number of unique event IDs for each user per day
$daily_failed_login_count = count($e.metadata.id)
condition:
// Trigger a detection if the daily failed login count exceeds a threshold
// You should adjust this threshold based on your environment's baseline.
#e > 0
}
כדי לוודא שהכלל מופעל, צריך לעיתים קרובות לבדוק את ספירת האירועים המקובצים. אפשר לציין ספירה מינימלית בקטע condition באמצעות משתנה האירוע. לדוגמה, התנאי (#e > 0) בודק אם קיים לפחות אירוע אחד שתואם לקריטריונים.
פקודת SPL eval = קטע YARA-L outcome
הפקודה eval היא פונקציית SPL בסיסית שמשמשת לשינוי ולהגדרה של ערכי שדות בתוצאות החיפוש.
- מטרה: חישוב והגדרה של ערכי שדות חדשים.
- למה זה משמש? הפונקציה הזו מחשבת ביטויים מתמטיים, מחרוזות או ביטויים בוליאניים.
- תוצאה: התוצאה של ההערכה יוצרת שדה חדש או מחליפה את הערך של שדה קיים.
- שרשור: אפשר לשרשר כמה ביטויים באמצעות פסיק (לדוגמה,
| eval A=1, B=A+1). - עיבוד רציף: ביטויים בשרשרת מעובדים ברצף, כך שחישובים מאוחרים יותר יכולים להתייחס לשדות שנוצרו או שונו על ידי ביטויים קודמים ולהסתמך עליהם.
בדוגמאות שבטבלה הבאה (ובדוגמאות שאחריה) מוסבר מבנה הפקודה הזה:
| פונקציה | תיאור | דוגמה ל-YARA-L |
|---|---|---|
| אופרטורים בוליאניים | בשימוש ב-events וב-condition. איך משתמשים ב-OR בקטע של התנאי |
|
| שדות מחושבים | בשימוש בקטע outcome. |
|
| יצירה דינמית של שמות שדות | בשימוש בקטע outcome. |
דוגמאות מופיעות במאמר השוואה בין SPL ל-YARA-L. |
דוגמה: יצירת שדה חדש שמכיל את התוצאה של חישוב
באמצעות YARA-L, יוצרים שדה חדש, bytes, בכל אירוע. כדי לחשב את מספר הבייטים, מוסיפים את הערכים בשדה bytes (נשלח) ואת הערכים בשדה bytes (התקבל).
metadata.event_type = "SCAN_NETWORK"
principal.hostname != ""
$host = principal.hostname
match:
$host
outcome:
$bytes = cast.as_int(sum(network.sent_bytes))
דוגמה: שרשור ערכים משני שדות
משתמשים בנקודה (.) כדי לשרשר את הערכים בשדה first_name עם הערכים בשדה last_name. משתמשים במירכאות ("") כדי להוסיף תו רווח בין שני השדות. כשמשרשרים, המערכת קוראת את הערכים כמחרוזות, בלי קשר לערך בפועל.
ב-SPL, השאילתה תיראה בערך כך:
| eval full_name = first_name+" "+last_name
ב-YARA-L, שאילתת החיפוש תיראה בערך כך:
principal.user.first_name = $first_name
principal.user.last_name = $last_name
outcome:
$full_name = strings.concat($first_name, " ", $last_name)
בדוגמה הבאה, שמתבססת על הדוגמה של שאילתת ההתחברות שנכשלה, אפשר למצוא משתמשים שהיו להם חמש (5) התחברויות שנכשלו או יותר בטווח של 10 דקות (10m) אחת מהשנייה (באמצעות משתני אירועים ומשתני placeholder):
metadata.event_type = "USER_LOGIN"
security_result.action = "FAIL"
target.user.userid = $userid
match:
$userid by 10m
outcome:
$login_count= count(metadata.id)
condition:
$login_count > 5
פקודת SPL where = קטע YARA-L condition
הפקודה SPL where שקולה לשילוב של הקטע events, outcome או condition ב-YARA-L. בקטע events אפשר להצהיר על אירועים ולציין מאפיינים ספציפיים שלהם (לדוגמה, principal.hostname = "xyz"). אחרי שמצהירים על האירועים, אפשר להשתמש באופרטורים בוליאניים, באופרטורים להשוואה ובתוצאות של פונקציות צבירה (מהקטע outcome) כדי להגדיר את הפרמטרים שהאירועים צריכים לעמוד בהם כדי שהשאילתה תחזיר תוצאה.
בדוגמה הבאה אפשר לראות איך מגדירים תנאי סף לספירה מצטברת. השאילתה בנויה כך שהיא סופרת את המספר הכולל של אירועי התחברות שנכשלו לכל מזהה משתמש, ואז משתמשת בקטע condition כדי להציג תוצאות רק לגבי משתמשים שנרשמו לגביהם חמש או יותר התחברויות שנכשלו.
metadata.event_type = "USER_LOGIN"
security_result.action = "FAIL"
match:
target.user.userid
outcome:
// metadata.id counts all unique events associated with failed logins.
$count = count(metadata.id)
//metadata.id counts all unique events associated with blocked logins.
condition:
$count > 5
פקודת SPL dedup = קטע YARA-L dedup
הפקודה SPL dedup שוות ערך לקטע dedup ב-YARA-L. משתמשים בקטע dedup כדי לבטל כפילויות של תוצאות שצוינו על ידי אירוע בקטע events.
לדוגמה:
principal.hostname = "foo"
dedup:
target.ip
איך משתמשים בביטול כפילויות בחיפוש ובמרכזי בקרה, במיוחד לגבי הנחיות לביצועים.
פקודת SPL stats = קטע YARA-L match או outcome (או שניהם)
ב-SPL, הצבירה מטופלת בדרך כלל על ידי משפחת הפקודות stats, שבהן מציינים את סוג הצבירה (למשל, count, distinct count, max, min) ואת השדה "group by".
ב-YARA-L, הקטעים match ו-outcome מספקים את היכולת הזו ביחד:
לוגיקת הצבירה: בקטע
matchמוגדרת קבוצת האירועים שצריך להתייחס אליהם (match: $grouping_field by time) כדי ליצור צבירה. בקטעoutcomeמוגדרות פונקציות הצבירה הספציפיות שצריך לחשב על סמך הקבוצה הזו (לדוגמה,count(), min(), max()).חלון זמן: בקטע
matchאפשר לציין חלון זמן לקיבוץ אירועים. משתמשים במילת המפתחover(לכללים) או ב-by(לחיפוש וללוחות בקרה) (לדוגמה,match: $userid by 1h). הפונקציונליות הזו דומה ל-SPL, כמו"timechart","streamstats"ו-"eventstats". מידע נוסף זמין במאמר בנושא חלונות זמן.
דוגמה: חישוב סכום הבייטים שמקובצים לפי שם מארח ראשי וכתובת IP של יעד
בדוגמה הבאה נעשה שימוש בקטע match כדי להגדיר קבוצת צבירה על סמך שם המארח הראשי וכתובת ה-IP של היעד בחלון זמן של יום אחד. לאחר מכן, סכום הבייטים שנשלחו מחושב בקטע outcome.
metadata.event_type = "NETWORK_CONNECTION"
network.sent_bytes > 0
principal.hostname != ""
target.ip != ""
// Define placeholder variables for grouping
$principal_hostname = principal.hostname
$target_ip = target.ip
// Group events by principal hostname, target IP, and day
match:
$principal_hostname, $target_ip by day
// Calculate the sum of sent bytes for each group
outcome:
$daily_bytes_sent = sum(network.sent_bytes)
מיפוי SPL ל-YARA-L
ב-SPL, הנתונים מעובדים שלב אחרי שלב באמצעות פקודות שמועברות בצינור עיבוד נתונים, ואילו ב-YARA-L משתמשים במבנה הצהרתי שמבוסס על קטעים כדי להגדיר דפוסים ופעולות. למרות ההבדלים המהותיים האלה בגישה, עוצמת הביטוי של YARA-L מאפשרת לכם לבצע הרבה מאותן משימות שאתם רגילים לבצע ב-SPL, החל מסינון בסיסי ועד צבירות ומתאמים מורכבים.
בקטע הזה מוסברים ההבדלים באמצעות מיפוי של פונקציות SPL מוכרות למקבילות שלהן במסגרת YARA-L.
השוואה בין SPL ל-YARA-L
בטבלה הזו מוצגת השוואה בין פונקציות ומושגים נפוצים בשפת SPL לבין המקבילים שלהם ב-YARA-L 2.0, או הסבר על האופן שבו המושג מטופל במבנה של שאילתת YARA-L.
| פקודה או קונספט של SPL | מטרה | מקבילה ל-YARA-L | תיאור ומיפוי YARA-L | דוגמה להטמעה של YARA-L |
|---|---|---|---|---|
search |
סינון ראשוני של נתונים | הקטע events |
הגדרת שדות ותנאים של אירועים. לא צריך להוסיף את הקידומת events: לחיפוש או למרכזי בקרה. לדוגמה |
|
where |
סינון נוסף של התוצאות | הקטעים events ו-condition |
החלת לוגיקה בוליאנית, לרוב על תוצאות מצטברות. לדוגמה |
|
eval |
חישוב ערכים חדשים משדות קיימים, צבירות, חיפושי נתונים | outcome או events |
לדוגמה |
|
stats |
צבירת נתונים (count, sum, avg) |
match או outcome |
קיבוץ לפי שדות ב-match. חישוב צבירות ב-outcome. תוכלו לראות דוגמאות לצבירה ודוגמאות לפקודות SPL. |
|
dedup |
הסרת אירועים כפולים על סמך שדה אחד או יותר | הקטע dedup |
ציינו את השדות שבהם אתם רוצים לבטל כפילויות. |
|
table |
הגדרה של פלט העמודה בטבלה | select או unselect
|
בשימוש במרכזי בקרה. בחיפוש, מוצגים outcome משתנים. |
|
sort |
התוצאות מוצגות בסדר עולה או יורד | order section |
דוגמה מופיעה בתא הסמוך. |
|
limit |
הגבלת מספר התוצאות שמוחזרות | הקטע limit |
דוגמה בתא הסמוך. |
|
| פונקציות עם כמה ערכים | מטופל באמצעות פונקציות mv* (mvexpand, mvfilter) |
תמיכה מובנית | מערכת YARA-L מבטלת אוטומטית את הקינון של מערכים בקטע events. במקרה הצורך, פונקציות של מערכים זמינות ב- outcome. |
דוגמאות לפונקציות עם כמה ערכים |
| חלון זמן | earliest=-5m, latest=now |
הקטע match, over, by |
לזיהויים רציפים, משתמשים ב-match: $field over 5m or by 5m. למרכזי בקרה בממשק המשתמש של החיפוש, צריך להשתמש ב-match: $field by 5m. |
דוגמאות מופיעות בקטע חלונות זמן. |
שאילתות צבירה ושאילתות סטטיסטיות
ב-YARA-L, פונקציות צבירה ופונקציות סטטיסטיות ממוקמות בדרך כלל בקטע outcome, והצבירה מבוססת על הקטע match.
הפקודה stats היא המנגנון העיקרי להטמעת צבירת נתונים בשאילתות YARA-L. הוא הופך נתוני אירועים גולמיים למדדי אבטחה מסוכמים. הפקודה eval מטפלת בטרנספורמציות ברמת השדה, שורה אחר שורה (בדומה לביטוי SELECT), והפקודה stats מבצעת צבירה ברמת הקבוצה (בדומה ל-GROUP BY ב-SQL).
בטבלה הבאה מפורטים התחביר והשימוש העיקריים, ומוסבר איך להשתמש ביעילות בנתונים סטטיסטיים כדי להטמיע לוגיקת אבטחה מתוחכמת שמבוססת על דפוסי נתונים וחריגים סטטיסטיים.
| פונקציית SPL | תיאור | מקבילה ל-YARA-L | דוגמה להטמעה של YARA-L |
|---|---|---|---|
count |
סופר את מספר האירועים. | count() |
|
dc (count_distinct) |
סופרת את הערכים הייחודיים בשדה. | count_distinct() |
|
sum |
חישוב סכום הערכים בשדה. | sum() |
|
avg |
חישוב הערך הממוצע של שדה. | avg() |
|
min/max |
מציאת הערך המינימלי או המקסימלי בשדה. | min() או max() |
|
median() |
מציאת ערך החציון. | window.median |
|
first() and last() |
הפונקציה מחזירה ערכים לפי סדר האירועים בתוצאות החיפוש. | window.first/window.last |
|
STDDEV() |
מחשבת את סטיית התקן, שמודדת את הפיזור של קבוצת נתונים. | window.stddev |
|
פרטים נוספים זמינים בקטע פונקציות נוספות.
לדוגמה, שאילתה מרובת שלבים יכולה לעקוב אחרי כמה ניסיונות כניסה שנכשלו בצבירות בשכבות. פרטים נוספים זמינים במאמרים דוגמה לצבירה רב-שלבית ויצירת שאילתות רב-שלביות ב-YARA-L.
צבירה רב-שלבית (ממוצע שעתי עד שבועי)
בדוגמה הרב-שלבית הזו, הנתונים מצטברים בהתחלה כדי למצוא את מספר הבייטים שהועברו לכל מארח בכל שעה. לאחר מכן, המערכת משתמשת בצבירה הזו כדי לחשב את הממוצע הכולל של כל מרווחי השעה ב-7 הימים האחרונים.
stage bytes_per_host {
metadata.event_type = "SCAN_NETWORK"
principal.hostname != ""
$host = principal.hostname
match:
$host by hour
outcome:
$bytes = cast.as_int(sum(network.sent_bytes))
}
$host = $bytes_per_host.host
match:
$host
outcome:
$hour_buckets = array_distinct(timestamp.get_timestamp($bytes_per_host.window_start))
$num_hour_buckets = count_distinct($bytes_per_host.window_start)
$avg_hourly_bytes = avg($bytes_per_host.bytes)
פונקציות מרובות ערכים (קריאת מערך)
התחביר של YARA-L בנוי כך שהוא מבין שלשדה יכולים להיות כמה ערכים. כשכותבים שאילתה שכוללת אירוע עם שדה מרובה ערכים בקטע events, השפה בודקת באופן אוטומטי כל ערך במערך. לא צריך להשתמש בפונקציה מיוחדת כדי לסנן את המערך, אלא רק לציין את התנאי שרוצים להתאים. לדוגמה, אם השדה principal.ip של אירוע ביומן מכיל את הערך הבא, מנוע YARA-L בודק באופן אוטומטי כל ערך במערך principal.ip. אם אחד מהערכים הוא "10.1.1.5", התנאי מתקיים.
["10.1.1.5", "10.2.2.6", "10.3.3.7"]
בטבלה הבאה מוצגת השוואה בין YARA-L לבין SPL בנוגע לניהול שדות מרובי-ערכים בנתוני יומן. שדות מרובי ערכים, כמו מערך של כתובות IP או רשימה של קבוצות משתמשים, הם תכונה נפוצה ביומנים מובנים.
| פונקציית SPL | מטרה | מקבילה ל-YARA-L | דוגמה להטמעה של YARA-L |
|---|---|---|---|
mvfilter() |
הפונקציה מסננת שדה עם כמה ערכים כדי לשמור רק את הערכים התואמים. | כשמשתמשים בו בקטע events של שאילתת YARA-L, צריך לציין את השדה שרוצים להתאים. מערכת YARA-L בודקת באופן אוטומטי אם יש ערך במערך הקבוצות שתואם לערך admin. |
|
mvcount() |
הפונקציה סופרת את מספר הערכים בשדה מרובה ערכים. | count() הוגדר לשדה בקטע השאילתה outcome. אין צורך לבטל את הקינון של ערכים כלשהם קודם. |
אפשר לעיין בדוגמה ספירת מספר המשתמשים ששייכים לקבוצת צוות ה-IT. |
mvexpand |
יוצר אירוע חדש לכל ערך בשדה עם כמה ערכים. | מטפל בשדות מרובי-ערכים באופן מובנה ומשתמע; ביטול הקינון מתבצע באופן אוטומטי. | אפשר לעיין בדוגמה ספירת מספר המשתמשים ששייכים לקבוצת צוות ה-IT. |
mvjoin |
הפונקציה מחברת את כל הערכים משדה עם כמה ערכים למחרוזת אחת לצורך עיצוב הנתונים. | הערכים מאוחסנים אוטומטית כמערך בתוצאות. הפלט של YARA-L הוא מובנה, ולא מחרוזת שטוחה. השדה מוצג כמערך אם צריך לבצע עוד שינויים במערך. לפרטים, אפשר להשתמש בפונקציות של מערכים. |
דוגמה: ספירת מספר הכניסות admin
בדוגמה הבאה, התנאי $metadata.event_type = "USER_LOGIN" מסנן אירועים שבהם event_type הוא "USER_LOGIN":
events:
metadata.event_type = "USER_LOGIN"
// Changed to a more appropriate event type for login
principal.user.group_identifiers = "admin"
outcome:
// This counts each unique event ID where the principal user is in the `"admin"` group.
$admin_login_count = count(metadata.id)
השדה $principal.user.group_identifiers= "admin" הוא שדה חוזר (מערך).
- ביטול קינון מרומז: YARA-L מבצעת באופן אוטומטי ביטול קינון של השדה הזה באופן פנימי במהלך הערכת השאילתה.
- בדיקת תנאי: אירוע יעמוד בתנאי אם אחד מהערכים במערך
$principal.user.group_identifiersשווה ל-"admin". - לא צריך פקודה מפורשת: בניגוד ל-SPL, לא צריך פקודה ספציפית לביטול הקינון כמו
mvexpand.
ההשפעה על קטע הצבירה (outcome) פירושה שהביטול המובלע של הקינון הוא חיוני בקטע outcome (לדוגמה, outcome: $admin_login_count = count(metadata.id))). חשוב לשים לב להשפעה הבאה:
- אירוע UDM יחיד שמכיל כמה ערכים תואמים בשדה חוזר יכול ליצור כמה שורות פנימיות לצורך הערכת השאילתה.
- מכיוון שהקטע
eventsכבר ביטל את ההטמעה של האירועים על סמך כל ערך תואם ב-$principal.user.group_identifiers, הצבירה שלcount(metadata.id)סופרת כל אחד מהמופעים האלה שבוטלה ההטמעה שלהם.
דוגמה: ספירת מספר המשתמשים ששייכים לקבוצת צוות ה-IT
SPL:
index=<your_index_name> user_id="jsmith"
| where match(memberOf, "Domain Admins|IT Staff|HR")
| mvexpand memberOf
| stats count by memberOf
| mvexpand actions
| table memberOf, count, actions
YARA-L (חיפוש):
principal.user.userid = "jsmith"
additional.fields["memberOf"] = $group
$group = /Domain Admins|IT Staff|HR/ nocase
match:
$group by 1h
outcome:
$group_count = count_distinct(metadata.id)
$memberOf = array_distinct($group)
$risk_score = max(50)
דוגמה: יצירת כלל ששולח התראה כשמופיע ערך גיבוב (hash) ספציפי של קובץ
SPL:
| eval file_hashes="hash12345,hash67890,hashABCDE"
| makemv delim="," file_hashes
| mvexpand file_hashes
| search file_hashes="hash67890"
| table _time, file_hashes
YARA-L (כלל):
rule specific_file_hash_detected {
meta:
rule_name = "Specific File Hash Detected"
description = "Detects events where a specific file hash is present."
severity = "Medium"
events:
$e.target.file.sha256 = "hash67890"
outcome:
$time = array_distinct($e.metadata.event_timestamp.seconds)
$file_hashes = array_distinct($e.target.file.sha256)
condition:
$e
}
חלון זמן
ב-YARA-L, חלון זמן הוא שיטה ליצירת קורלציה בין אירועים בתקופה ספציפית ומתגלגלת. כשמשתמשים בחלון הזה בכללים, הוא נע כל הזמן עם הנתונים הנכנסים, וכך מתאפשר איתור רציף בזמן אמת של דפוסים שמתפתחים לאורך זמן.
התהליך הזה הוא חלק מרכזי בתכנון של זיהוי אוטומטי, והוא אחד היתרונות בשימוש ב-YARA-L. כשמציינים את חלון הזמן, הגילויים ומרכזי הבקרה פועלים באופן רציף עם נתונים בזמן אמת.
| התכונה | SPL | YARA-L |
|---|---|---|
| היעד העיקרי | חיפוש סטטי, ניתוח אד-הוק | זיהוי רציף, קורלציה אוטומטית |
| הפונקציות העיקריות |
earliest, latest, span, transaction
|
over, by |
| דוגמה ל-5 דקות | earliest=-5m (חיפוש סטטי)או
transaction maxspan=5m
|
match: [event] over 5m (זיהוי רציף בכללים)או
[event] by 5m (חיפוש ומרכזי בקרה)
|
בדוגמאות שבקטע הזה מוצג ההבדל בין חלון זמן מתגלגל (באמצעות by) לבין חלון זמן נע (באמצעות over) ב-YARA-L.
חלון זמן מתגלגל (by <time_unit>)
מושג: חלונות עוקבים (tumbling windows) שמשמשים בחיפוש YARA-L יוצרים מרווחי זמן קבועים בגודל קבוע שלא חופפים. המערכת מעבדת כל אירוע על ידי הקצאה של כל אירוע לדלי זמן ספציפי אחד בלבד, על סמך חותמת הזמן שלו. המרווחים הקבועים האלה הם מוחלטים, והם תואמים באופן מדויק לסמני זמן סטנדרטיים, כמו ימים, שעות או דקות.
שימוש: בדרך כלל משתמשים בפונקציה הזו בשאילתות חיפוש ובמרכזי בקרה של Google SecOps כדי לצבור נתונים בפלחי זמן נפרדים.
דוגמה: ספירה יומית של התחברויות המוצלחות לכל משתמש
שאילתת החיפוש הזו מקבצת אירועי התחברות מוצלחים לפי כל משתמש ייחודי בכל יום קלנדרי. בדוגמה הבאה מוצג חלון עוקב (tumbling window) של חיפוש YARA-L (by day):
events:
//Filter for successful login events
metadata.event_type = "USER_LOGIN"
principal.user.userid != ""
match:
//Group by each unique user ID, aggregated over a calendar day.
principal.user.userid by day
outcome:
//Count how many successful logins occurred for this user on this specific day.
$daily_success_count = count(metadata.id)
//Get the timestamp of the FIRST event within this daily group.
$first_event_time = window.first(metadata.event_timestamp.seconds, timestamp.get_timestamp(metadata.event_timestamp.seconds))
//Get the timestamp of the LAST event within this daily group.
$last_event_time = window.last(metadata.event_timestamp.seconds, timestamp.get_timestamp(metadata.event_timestamp.seconds))
איך זה עובד: אם למשתמש jdoe יש 10 התחברויות מוצלחות ב-Nov 17 ו-15 ב-Nov 18, השאילתה הזו יוצרת שתי שורות נפרדות עבור jdoe, אחת לכל יום, עם המספרים המתאימים. הקטגוריה Nov 17 כוללת אירועים מ-2025-11-17 00:00:00 to 23:59:59 UTC.
חלון זמן משתנה (over <duration>)
מושג: חלונות הזזה, שמשמשים בכללי YARA-L, הם חלונות זמן נעים שאולי חופפים זה לזה, עם משך זמן מוגדר. הם מתאימים במיוחד ליצירת קורלציה בין אירועים שמתרחשים בקרבה מסוימת זה לזה.
שימוש: משמש בעיקר בכללי YARA-L כדי לזהות תבניות או רצפים של אירועים בפרק זמן רציף.
דוגמה: זיהוי של כמה ניסיונות כניסה שנכשלו תוך 5 דקות
דוגמה לכלל YARA-L הזה יוצרת זיהוי אם למשתמש יחיד יש יותר מ-5 failed logins ניסיונות במהלך תקופה של 5-minute ימים:
rule TooManyFailedLogins_SlidingWindow {
meta:
author = "Alex"
description = "Detects when a user has more than 5 failed logins within a 5-minute sliding window."
severity = "Medium"
events:
// Define an event variable $e for failed login attempts
$e.metadata.event_type = "USER_LOGIN"
$e.security_result.action = "FAIL"
$e.principal.user.userid != ""
$userid = $e.principal.user.userid
match:
// Group events by userid over a continuous 5-minute sliding window.
// Any events for the same $userid within 5 minutes of each other are grouped.
$userid over 5m
outcome:
// Count the number of failed login events within each 5-minute window for the grouped userid.
$failed_count = count($e.metadata.id)
condition:
// Trigger a detection if the count of failed logins in ANY 5-minute window is greater than 5.
#e > 5
}
איך זה עובד: המערכת עוקבת באופן רציף אחרי ניסיונות התחברות שנכשלו. בכל רגע נתון, המערכת מתייחסת לנתוני האירועים של כל משתמש ב-5 הדקות האחרונות. לדוגמה, אם בין 10:02:30 ל-10:07:30, המשתמש jdoe צובר שישה ניסיונות כניסה שנכשלו, מופעל זיהוי. החלון הזה זז כל הזמן קדימה, ומאפשר זיהוי דפוסים בזמן אמת, בלי קשר לגבולות של לוח השנה.
המאמרים הבאים
- סקירה כללית מעמיקה על YARA-L 2.0
- תחביר מלא של שפת YARA-L 2.0
- מידע ולמידה על כתיבת כללים במנוע הזיהוי
- חדש בבלוגים של Google SecOps
הבעיה עדיין לא נפתרה? קבלת תשובות מחברי הקהילה וממומחי Google SecOps.