הצלבת נתונים באמצעות שאילתות איחוד חיצוניות

נתמך ב:

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

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

איך מתבצעים צירופים חיצוניים

הקונספט של איחודים חיצוניים ב-YARA-L 2.0 זהה לאיחודים חיצוניים ב-SQL סטנדרטי:

  • ב-left outer join נשמרים כל הרשומות מהצד השמאלי של ה-join.

  • ב-right outer join נשמרות כל הרשומות מהצד הימני של ה-join.

תחביר של צירוף חיצוני (צירוף שמאלי וצירוף ימני) נתמך בכל השאילתות – גם עם תנאי match וגם בלי.

הסבר על איחוד חיצוני שמאלי

באיחוד חיצוני שמאלי (או באיחוד שמאלי), כל הרשומות ממקור הנתונים בצד ימין של מילת המפתח left join נשמרות.

  • אם לרשומה מהצד הימני אין התאמה לאירוע הימני, השדות מהאירוע הימני מוחזרים כ-null.

  • המשמעות של placeholder: כל משתנה placeholder שמשמש בקטע match צריך להפנות לשדה מהאירוע השמאלי כדי להבטיח צבירת נתונים מדויקת בכל קבוצת התוצאות.

דוגמה ל-left join מאירוע לאירוע

בדוגמה הבאה מוצג צירוף חיצוני שמאלי כדי ליצור קורלציה בין אירועי התחברות של משתמש לבין אירועי חיבור לרשת שמתרחשים בהמשך באותו מארח. ה-left join מוודא שכל האירועים של USER_LOGIN נשמרים בקבוצת התוצאות. אם נמצא אירוע NETWORK_CONNECTION תואם ($e2), הנתונים שלו מצורפים. אם לא נמצאת התאמה, השדות של $e2 הם null.


$e1.metadata.event_type = "USER_LOGIN"
$e2.metadata.event_type = "NETWORK_CONNECTION"
left join $e1.principal.hostname = $e2.principal.hostname

הגדרת האירוע השמאלי

בדוגמה הבאה של שאילתה מוגדר הצד השמאלי של הצירוף ($e1), שהוא קבוצת האירועים שנשמרת בתוצאה הסופית:

$e1.metadata.event_type = "USER_LOGIN"

הטבלה הבאה מייצגת את תוצאת השאילתה, ומזהה את קבוצת האירועים הראשונית של התחברות משתמשים:

סוג אירוע שם המארח הראשי כתובת IP
USER_LOGIN workstation-01 192.168.1.101
USER_LOGIN laptop-hr-02 192.168.1.102
USER_LOGIN server-db-03 10.0.0.50
USER_LOGIN kiosk-4 192.168.1.104

הגדרת האירוע הנכון

בדוגמה הבאה של שאילתה מוגדר הצד הימני של הצירוף ($e2), שהוא קבוצת האירועים שמושוות לאירועים בצד שמאל:

$e2.metadata.event_type = "NETWORK_CONNECTION"

הטבלה הבאה מייצגת את קבוצת האירועים של חיבור לרשת שזמינים להתאמה:

סוג אירוע שם המארח הראשי כתובת IP
NETWORK_CONNECTION workstation-01 192.168.1.101
NETWORK_CONNECTION laptop-hr-02 192.168.1.101
NETWORK_CONNECTION kiosk-4 203.0.113.3

הצטרפות לאירועים

עם קטע של התאמה

בדוגמה הבאה מוצגת שאילתת התאמה שמשתמשת בצירוף חיצוני שמאלי בשדה principal.hostname:


  $e1.metadata.event_type = "USER_LOGIN"

  $e2.metadata.event_type = "NETWORK_CONNECTION"

  left join $e1.principal.hostname = $e2.principal.hostname

  $host = $e1.principal.hostname

  match:
    $host over 5m

  • ה-left outer join מוודא שכל אירוע USER_LOGIN ($e1) ייכלל בקבוצת התוצאות הסופית.

  • הערך של ה-placeholder‏ ‎ $host מוקצה מתוך $e1.principal.hostname. ה-left outer join מבטיח את הנוכחות של אירוע $e1, ומוודא שהמשתנה $host תמיד יאוכלס לצורך צבירה.

  • הכלל צובר את התוצאות לפי המארח בחלון זמן של 5 דקות.

תוצאה של הצטרפות

הנתונים שמתקבלים מראים את השילוב של שני האירועים. כל הרשומות מהטבלה הימנית ($e1) נשמרות, והשדות מהטבלה השמאלית ($e2) מוגדרים ל-null אם לא נמצא שם מארח תואם (לדוגמה, עבור server-db-03).

סוג האירוע ($e1) שם המארח הראשי ($host) כתובת IP‏ ($e1) סוג האירוע ($e2) כתובת IP‏ ($e2) סטטוס התאמה
USER_LOGIN workstation-01 192.168.1.101 NETWORK_CONNECTION 192.168.1.101 נמצאה התאמה
USER_LOGIN laptop-hr-02 192.168.1.102 NETWORK_CONNECTION 192.168.1.101 נמצאה התאמה
USER_LOGIN server-db-03 10.0.0.50 null null אין התאמה
USER_LOGIN kiosk-4 192.168.1.104 NETWORK_CONNECTION 203.0.113.3 נמצאה התאמה

דוגמאות לשאילתות מסוג left join

בקטע הזה מוצגות דוגמאות לשאילתות left join.

הצטרפות עם תנאי התאמה

  • Event-entity

    
    $e1.metadata.event_type = "NETWORK_CONNECTION"
    $g1.graph.metadata.entity_type = "ASSET"
    left join $e1.principal.asset.hostname = $g1.graph.entity.asset.hostname
    $host = $e1.principal.asset.hostname
    
    match:
      $host over 5m
    
    
  • Event-datatable

    
    $host = $e1.principal.hostname
    left join $e1.principal.hostname = %all_dt_column_types.hostname
    
    match:
      $host by 5m
    

הצטרפות ללא תנאי התאמה

  • אירוע-אירוע

    
    $e1.metadata.event_type = "USER_LOGIN"
    $e1.principal.ip = "114.241.96.87"
    $e2.metadata.event_type = "NETWORK_CONNECTION"
    left join $e1.principal.hostname = $e2.principal.hostname
    
    
  • Event-entity

    
    $e1.metadata.event_type = "NETWORK_CONNECTION"
    $g1.graph.metadata.entity_type = "ASSET"
    left join $e1.principal.asset.hostname = $g1.graph.entity.asset.hostname
    $host = $e1.principal.asset.hostname
    
    
  • Event-datatable

    
    $host = $e1.principal.hostname
    left join $e1.principal.hostname = %all_dt_column_types.hostname
    
    

איחוד חיצוני ימני (right outer join)

ב-right outer join (או right join) נשמרים כל הרשומות ממקור הנתונים בצד ימין של מילת המפתח right join.

  • אם לרשומה מהאירוע הימני אין התאמה באירוע השמאלי, השדות מהאירוע השמאלי מוחזרים כ-null.

  • המשמעות של placeholder: כל משתנה placeholder שמשמש בקטע match צריך להפנות לשדה מהאירוע הנכון כדי להבטיח צבירת נתונים מדויקת בכל קבוצת התוצאות.

דוגמה ל-right join מאירוע לאירוע

בדוגמה הבאה מוצג right outer join כדי ליצור קורלציה בין אירועי התחברות של משתמשים לבין אירועי חיבור לרשת שמתרחשים בהמשך באותו מארח. הפונקציה right join מוודאת שכל האירועים מסוג NETWORK_CONNECTION יישמרו בקבוצת התוצאות. אם נמצא אירוע USER_LOGIN תואם, הנתונים שלו מצורפים. אם לא נמצאת התאמה, השדות של$e1 הם null.


$e1.metadata.event_type = "USER_LOGIN"

$e2.metadata.event_type = "NETWORK_CONNECTION"

right join $e1.principal.hostname = $e2.principal.hostname

הגדרת האירוע השמאלי

השאילתה הבאה מגדירה את הצד השמאלי של הצירוף ($e1), שהוא קבוצת האירועים האופציונלית בתוצאה הסופית:


$e1.metadata.event_type = "USER_LOGIN"

הטבלה הבאה מייצגת את תוצאת השאילתה, ומזהה את קבוצת האירועים הראשונית של התחברות משתמשים:

סוג אירוע שם המארח הראשי כתובת IP
USER_LOGIN workstation-01 192.168.1.101
USER_LOGIN laptop-hr-02 192.168.1.102
USER_LOGIN server-db-03 10.0.0.50

הגדרת האירוע הנכון

השאילתה הבאה מגדירה את הצד הימני של הצירוף ($e2), שהוא קבוצת האירועים שנשמרת בתוצאה הסופית.


$e2.metadata.event_type = "NETWORK_CONNECTION"

הטבלה הבאה מייצגת את קבוצת האירועים של חיבור לרשת שזמינים להתאמה.

סוג אירוע שם המארח הראשי כתובת IP
NETWORK_CONNECTION workstation-01 192.168.1.101
NETWORK_CONNECTION laptop-hr-02 192.168.1.101
NETWORK_CONNECTION vm-unauth-05 203.0.113.3

הצטרפות לאירועים

בדוגמה הבאה מוצגת שאילתת התאמה עם הצטרפות חיצונית ימנית בשדה principal.hostname:


$e1.metadata.event_type = "USER_LOGIN"

$e2.metadata.event_type = "NETWORK_CONNECTION"

right join $e1.principal.hostname = $e2.principal.hostname

$host = $e1.principal.hostname

match:
  $host over 5m

  • ה-right outer join מוודא שכל אירוע NETWORK_CONNECTION ($e2) ייכלל בקבוצת התוצאות הסופית.

  • הערך של $e2.principal.hostname מוקצה ל-placeholder‏ $host. ה-outer join הימני מבטיח את הנוכחות של אירוע $e2, וכך מוודא שהמשתנה $host תמיד יאוכלס לצורך צבירה.

  • הכלל צובר את התוצאות לפי המארח בחלון זמן של 5 דקות.

תוצאה של הצטרפות

מערך הנתונים שמתקבל מראה את השילוב של שני האירועים. כל הרשומות מהטבלה הימנית ($e2) נשמרות, והשדות מהטבלה השמאלית ($e1) מוגדרים כ-null אם לא נמצא שם מארח תואם (לדוגמה, vm-unauth-05).

סוג האירוע ($e1) שם המארח הראשי ($e1) כתובת IP‏ ($e1) סוג האירוע ($e2) שם המארח הראשי ($host) כתובת IP‏ ($e2) סטטוס התאמה
USER_LOGIN workstation-01 192.168.1.101 NETWORK_CONNECTION workstation-01 192.168.1.101 נמצאה התאמה
USER_LOGIN laptop-hr-02 192.168.1.102 NETWORK_CONNECTION laptop-hr-02 192.168.1.101 נמצאה התאמה
null null null NETWORK_CONNECTION vm-unauth-05 203.0.113.4 אין התאמה

דוגמאות לשאילתות של צירוף ימני

בקטע הזה מופיעות דוגמאות לשאילתות של צירוף ימני.

הצטרפות עם תנאי התאמה

  • אירוע-אירוע

    
    $e1.metadata.event_type = "USER_LOGIN"
    
    $e2.metadata.event_type = "NETWORK_CONNECTION"
    
    right join $e1.principal.hostname = $e2.principal.hostname
    
    $host = $e2.principal.hostname
    
    match:
      $host over 5m
    
    
  • Entity-event

    
    $e1.metadata.event_type = "NETWORK_CONNECTION"
    
    $g1.graph.metadata.entity_type = "ASSET"
    
    right join $g1.graph.entity.asset.hostname = $e1.principal.asset.hostname
    
    $host = $e1.principal.asset.hostname
    
    match:
      $host over 5m
    
    
  • Datatable-event

    
    $host = $e1.principal.hostname
    
    right join %all_dt_column_types.hostname = $e1.principal.hostname
    
    match:
      $host by 5m
    
    

הצטרפות ללא תנאי התאמה

  • אירוע-אירוע

    
    $e1.metadata.event_type = "USER_LOGIN"
    
    $e1.principal.ip = "114.241.96.87"
    
    $e2.metadata.event_type = "NETWORK_CONNECTION"
    
    right join $e1.principal.hostname = $e2.principal.hostname
    
    
  • Entity-event

    
    $e1.metadata.event_type = "NETWORK_CONNECTION"
    
    $g1.graph.metadata.entity_type = "ASSET"
    
    right join $g1.graph.entity.asset.hostname = $e1.principal.asset.hostname
    
    $host = $e1.principal.asset.hostname
    
    
  • Datatable-event

    
    $host = $e1.principal.hostname
    
    right join %all_dt_column_types.hostname = $e1.principal.hostname
    
    

מגבלות

כשיוצרים צירופים חיצוניים, חשוב לקחת בחשבון את המגבלות הבאות:

  • אין תמיכה בחיבור חיצוני מלא (חיבור שמאלי וחיבור ימני ביחד).

  • טווח הזמן של השאילתה עבור הצטרפויות ללא התאמה מוגבל ל-14 ימים לכל היותר.

  • אי אפשר לחבר ישירות שני מקורות הקשריים (לדוגמה, ישות ישירות לטבלת נתונים).

  • האירוע הראשי במודל הנתונים המאוחד (UDM) חייב להיות הצד שנשמר של הצירוף החיצוני. השאילתה לא תקינה אם האירוע הראשי נמצא בצד 'ניתן לאיפוס'.

    • איחוד של אירוע וישות חייב להיות איחוד שמאלי. כך האירוע נשמר בצורה נכונה ($e1).

    • הצטרפות של ישות לאירוע חייבת להיות הצטרפות ימנית. כך האירוע נשמר בצורה נכונה ($e1).

    הדוגמה הבאה לא תקינה כי אירוע UDM‏ ($e1) נמצא בצד שמאל, אבל הצטרפות ימנית שומרת על הצד הימני ($g1), וזה מנוגד לכלל שאירוע UDM חייב להישמר:

    
    // Invalid query
    $e1.metadata.event_type = "NETWORK_CONNECTION"
    $g1.graph.metadata.entity_type = "ASSET"
    right join $e1.principal.asset.hostname = $g1.graph.entity.asset.hostname
    
    

שיטות מומלצות

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

לדוגמה, שאילתה רחבה כמו הבאה:


$e1.metadata.event_type = "USER_LOGIN"
$e2.metadata.event_type = "NETWORK_CONNECTION"
right join $e1.principal.hostname = $e2.principal.hostname

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


$e1.metadata.event_type = "USER_LOGIN"
$e1.principal.ip = "121.121.121.121"
$e1.principal.user.userid = "alex"
$e2.metadata.event_type = "NETWORK_CONNECTION"
$e2.src.hostname = "altostrat.com"
$e1.principal.hostname = $e2.principal.hostname

הבעיה עדיין לא נפתרה? קבלת תשובות מחברי הקהילה וממומחי Google SecOps.