יצירת מנתח ASIM

הושלם

משתמשי Advanced Security Information Model (ASIM) משתמשים במנתחים אחדים במקום בשמות טבלאות בשאילתות שלהם, כדי להציג נתונים בתבנית מנומול ולכלול את כל הנתונים הרלוונטיים לסכימה בשאילתה. אחד מנתחים, כמקור, השתמש במנתחים ספציפיים למקור כדי לטפל בפרטים הספציפיים של כל מקור.

Microsoft Sentinel מספק מנתחים מוכללים ספציפיים למקור עבור מקורות נתונים רבים. ייתכן שתרצה לשנות, או לפתח, מנתחים ספציפיים למקור אלה במצבים הבאים:

כאשר המכשיר שלך מספק אירועים המתאימים סכימת ASIM, אך מנתח ספציפי למקור עבור המכשיר שלך והסכימה הרלוונטית אינו זמין ב- Microsoft Sentinel.

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

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

ייתכן שלמכשיר שלך יש גירסה שונה מהגירסה הנתמכת על-ידי מנתח ASIM.

האירועים עשויים להיאסף, לשנות ולהועבר על-ידי מערכת מתווך.

תהליך פיתוח מנתח מותאם אישית

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

  1. אסוף יומני רישום לדוגמה.

  2. זהה את הסכימות או הסכימות שהאירועים שנשלחו מהמקור מייצגים.

  3. מפה את שדות אירוע המקור אל הסכימה או הסכימות שזוהו.

  4. פתח מנתח ASIM אחד או יותר עבור המקור שלך. יהיה עליך לפתח מנתח סינון ומנתח ללא פרמטרים עבור כל סכימה הרלוונטית למקור.

  5. בדוק את המנתח.

  6. פרוס את המנתחים בסביבות העבודה של Microsoft Sentinel.

  7. עדכן את המנתח המותאם אישית הרלוונטי של ASIM כדי להפנות למנתח המותאם אישית החדש.

  8. ייתכן שתרצה גם לתרום את המנתחים שלך להפצה הראשית של ASIM. מנתחים תורמים עשויים גם להיות זמינים בכל סביבות העבודה כמנתחים מוכללים.

אסוף יומני רישום לדוגמה

כדי לבנות מנתחי ASIM יעילים, אתה זקוק לקבוצה מייצגת של יומני רישום, שבמקרה זה תדרוש הגדרה של מערכת המקור והתחברותה ל- Microsoft Sentinel. אם מכשיר המקור אינו זמין, שירותי תשלום בענן מאפשרים לך לפרוס מכשירים רבים לפיתוח ולבדיקה.

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

קבוצה מייצגת של יומני רישום צריכה לכלול:

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

מיפוי

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

  • מפה את כל השדות הכרחיים ואת השדות המומלצים, רצויים גם כן.
  • נסה למפות את כל המידע הזמין מהמקור לשדות מנומלים. אם האפשרות אינה זמינה כחלק מהסכימה שנבחרה, שקול למיפוי לשדות הזמינים בסכימות אחרות.
  • מפה ערכים עבור שדות במקור לערכים המנומלים המותרים על-ידי ASIM. הערך המקורי מאוחסן בשדה נפרד, כגון EventOriginalResultDetails.

מנתחים מפתחים

פתח הן סינון והן מנתח ללא פרמטרים עבור כל סכימה רלוונטית.

מנתח מותאם אישית הוא שאילתת KQL שפותחה בדף יומני Microsoft Sentinel. שאילתת המנתח כוללת שלושה חלקים:

סינון > ניתוח מבנה טקסט > של שדות הכנת שדות

סינון הרשומות הרלוונטיות

במקרים רבים, טבלה ב- Microsoft Sentinel כוללת סוגים מרובים של אירועים. לדוגמה:

  • הטבלה Syslog כוללת נתונים ממקורות מרובים.
  • טבלאות מותאמות אישית עשויות לכלול מידע ממקור יחיד המספק יותר מסוג אירוע אחד והוא יכול להתאים לסכימות שונות.

לכן, מנתח צריך תחילה לסנן רק את הרשומות הרלוונטיות לסכימת היעד.

סינון ב- KQL מתבצע באמצעות האופרטור where . לדוגמה, אירוע Sysmon 1 מדווח על יצירת תהליך, ולכן הוא מנומול בסכימה ProcessEvent . האירוע Sysmon event 1 מהווה חלק מטבלת האירוע , לכן עליך להשתמש במסנן הבא:

Event | where Source == "Microsoft-Windows-Sysmon" and EventID == 1

חשוב

מנתח לא אמור לסנן לפי זמן. השאילתה המשתמשת במנתח תחיל טווח זמן.

סינון לפי סוג מקור באמצעות רשימת מעקב

במקרים מסוימים, האירוע עצמו אינו מכיל מידע המאפשר סינון עבור סוגי מקור ספציפיים.

לדוגמה, אירועי DNS של Infoblox נשלחים כהודעות Syslog, ושקשה להבחין ביניהן להודעות Syslog הנשלחות ממקורות אחרים. במקרים כאלה, המנתח מסתמך על רשימת מקורות המגדירה את האירועים הרלוונטיים. רשימה זו נשמרת ברשימת המעקב של ASimSourceType.

כדי להשתמש ברשימת המעקב ASimSourceType במנתחים שלך:

  • כלול את השורה הבאה בתחילת המנתח:
let Sources_by_SourceType=(sourcetype:string){_GetWatchlist('ASimSourceType') | where SearchKey == tostring(sourcetype) | extend Source=column_ifexists('Source','') | where isnotempty(Source)| distinct Source };
  • הוסף מסנן המשתמש ברשימת המעקב במקטע סינון מנתח. לדוגמה, מנתח ה- DNS Infoblox כולל את הפרטים הבאים במקטע הסינון:
| where Computer in (Sources_by_SourceType('InfobloxNIOS'))

כדי להשתמש בדוגמה זו במנתח:

  • החלף את המחשב בשם השדה הכולל את פרטי המקור עבור המקור שלך. באפשרותך לשמור זאת כמחשב עבור מנתחים המבוססים על Syslog.

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

סינון בהתבסס על פרמטרי מנתח

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

בעת סינון, ודא שאתה:

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

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

srcipaddr=='*' or ClientIP==srcipaddr
array_length(domain_has_any) == 0 or Name has_any (domain_has_any)

מיטוב סינון

כדי להבטיח את ביצועי המנתח, שים לב להמלצות הסינון הבאות:

  • סנן תמיד לפי שדות מוכללים ולא שדות שנותנו מבנה טקסט. על אף שלפעמים קל יותר לסנן באמצעות שדות שנותנו, אך הדבר משפיע באופן דרמטי על הביצועים.
  • השתמש באופרטורים המספקים ביצועים מיטביים. באופן ספציפי, ==, has ו- startswith. שימוש באופרטורים כגון מכיל או התאמה regex משפיע גם הוא באופן דרמטי על הביצועים.

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

לקבלת דוגמה, עיין בסעיף הבא של מנתח DNS של Infoblox. המנתח בודק תחילה כי השדה SyslogMessage כולל את לקוח המילה. עם זאת, ניתן להשתמש במונח במקום אחר בהודעה, כך שלאחר ניתוח השדה Log_Type, המנתח בודק שוב שמילה הלקוח אכן היתה הערך של השדה.

Syslog | where ProcessName == "named" and SyslogMessage has "client"
…
      | extend Log_Type = tostring(Parser[1]),
      | where Log_Type == "client"

ניתוח

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

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

מרכזיה תיאור
פצל ניתוח מבנה טקסט של מחרוזת של ערכים מופרדים.
parse_csv ניתוח מבנה טקסט של מחרוזת ערכים המעוצבים כקווים CSV (ערכים המופרדים באמצעות פסיקים).
ניתוח מבנה טקסט ניתוח מבנה טקסט של ערכים מרובים ממחרוזת שרירותית באמצעות תבנית, שעשויה להיות תבנית פשוטה יותר עם ביצועים טובים יותר או ביטוי רגיל.
extract_all ניתוח מבנה טקסט של ערכים בודדים ממחרוזת שרירותית באמצעות ביטוי רגיל. extract_all יש ביצועים דומים לניתוח מבנה טקסט אם הביטוי האחרון משתמש בביטוי רגיל.
תמצית חילוץ ערך יחיד ממחרוזת שרירותית באמצעות ביטוי רגיל. שימוש בחילוץ מספק ביצועים טובים יותר מאשר ניתוח extract_all אם נדרש ערך בודד. עם זאת, השימוש בהפעלות מרובות של חילוץ על-פני אותה מחרוזת מקור יעיל פחות ממחרוזת ניתוח או ניתוח extract_all אחת ויש להימנע מכך.
parse_json ניתוח מבנה הטקסט של הערכים במחרוזת המעוצבת כ- JSON. אם דרושים רק כמה ערכים מה- JSON, שימוש בניתוח מבנה טקסט, חילוץ או extract_all מספק ביצועים טובים יותר.
parse_xml ניתוח מבנה הטקסט של הערכים במחרוזת המעוצבת כ- XML. אם דרושים רק כמה ערכים מה- XML, שימוש בניתוח מבנה טקסט, חילוץ או extract_all מספק ביצועים טובים יותר.

בנוסף לניתוח מחרוזת, שלב הניתוח עשוי לדרוש עיבוד נוסף של הערכים המקוריים, כולל:

  • המרת עיצוב וסוג. ייתכן שיהיה צורך בעיצוב של שדה המקור, לאחר חילוץ שדה המקור כדי להתאים לשדה הסכימה המשמש כיעד. לדוגמה, ייתכן שיהיה עליך להמיר מחרוזת המייצגת תאריך ושעה לשדה תאריך/שעה. פונקציות כגון todatetime ו- tohex מועילות במקרים אלה.

  • בדיקת ערך. ייתכן שיהיה צורך למפות את הערך של שדה המקור, לאחר חילוץ, לערכת הערכים שצוינו עבור שדה הסכימה המשמש כיעד. לדוגמה, מקורות מסוימים מדווחים על קודי תגובה מספריים של DNS, בעוד שהסכימה מתאריך את קודי התגובה הנפוצים יותר של טקסט. הפונקציות iff ו- case עשויים להועיל למיפוי כמה ערכים.

    לדוגמה, מנתח ה- DNS של Microsoft מקצה את השדה EventResult בהתבסס על מזהה האירוע וקוד התגובה באמצעות משפט iff, באופן הבא:

    extend EventResult = iff(EventId==257 and ResponseCode==0 ,'Success','Failure')
    

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

    let RCodeTable = datatable(ResponseCode:int,ResponseCodeName:string) [ 0, 'NOERROR', 1, 'FORMERR'....];
    ...
     | lookup RCodeTable on ResponseCode
     | extend EventResultDetails = case (
     isnotempty(ResponseCodeName), ResponseCodeName,
     ResponseCode between (3841 .. 4095), 'Reserved for Private Use',
     'Unassigned')
    

מיפוי ערכים

במקרים רבים, יש לנירמול את הערך המקורי שחולץ. לדוגמה, ב- ASIM כתובת MAC משתמשת בנקודתיים כמפריד, בעוד שהמקור עשוי לשלוח כתובת MAC מופרדת באמצעות מקף. האופרטור הראשי לשינוי ערכים הוא מורחב, לצד ערכה רחבה של מחרוזת KQL, פונקציות מספריות ופונקציות תאריך, כפי שצוין בסעיף 'ניתוח' לעיל.

משפטי מקרה שימוש, iff ובדיקת מידע כאשר יש צורך למפות ערכה של ערכים לערכים המותרים על-ידי שדה היעד.

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

let NetworkProtocolLookup = datatable(Proto:real, NetworkProtocol:string)[
        6, 'TCP',
        17, 'UDP'
   ];
    let DnsResponseCodeLookup=datatable(DnsResponseCode:int,DnsResponseCodeName:string)[
      0,'NOERROR',
      1,'FORMERR',
      2,'SERVFAIL',
      3,'NXDOMAIN',
      ...
   ];
   ...
   | lookup DnsResponseCodeLookup on DnsResponseCode
   | lookup NetworkProtocolLookup on Proto

שים לב שבדיקת מידע שימושית ויעילה גם כאשר למיפוי יש שני ערכים אפשריים בלבד.

כאשר תנאי המיפוי מורכבים יותר, השתמש בפונקציות iffאו case. הפונקציה iff מאפשרת מיפוי של שני ערכים:

| extend EventResult = 
      iff(EventId==257 and ResponseCode==0,'Success','Failure’)

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

| extend DnsResponseCodeName = 
      case (
        DnsResponseCodeName != "", DnsResponseCodeName,
        DnsResponseCode between (3841 .. 4095), 'Reserved for Private Use',
        'Unassigned'
      )

הכנת שדות בערכת התוצאות

המנתח חייב להכין את השדות בערכת התוצאות כדי להבטיח שהשדות המנומולים נמצאים בשימוש.

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

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

נקודת אחיזה לניתוח וריאציות

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

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

let AzureFirewallNetworkRuleLogs = AzureDiagnostics
    | where Category == "AzureFirewallNetworkRule"
    | where isnotempty(msg_s);
let parseLogs = AzureFirewallNetworkRuleLogs
    | where msg_s has_any("TCP", "UDP")
    | parse-where
        msg_s with           networkProtocol:string 
        " request from "     srcIpAddr:string
        ":"                  srcPortNumber:int
    …
    | project-away msg_s;
let parseLogsWithUrls = AzureFirewallNetworkRuleLogs
    | where msg_s has_all ("Url:","ThreatIntel:")
    | parse-where
        msg_s with           networkProtocol:string 
        " request from "     srcIpAddr:string
        " to "               dstIpAddr:string
    …
union parseLogs,  parseLogsWithUrls…

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

פריסת מנתחים

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

כדי לפרוס מספר גדול של מנתחים, מומלץ להשתמש בתבניות ARM של מנתח, באופן הבא:

  1. צור קובץ YAML המבוסס על התבנית הרלוונטית עבור כל סכימה וכלול בו את השאילתה שלך. התחל עם התבנית YAML הרלוונטית לסוג הסכימה והנתח שלך, לסינון או ללא פרמטרים.

  2. השתמש בממיר התבניות ASIM Yaml ל- ARM כדי להמיר את קובץ YAML לתבנית ARM.

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

  4. פרוס את התבנית שלך באמצעות פורטל Azure או PowerShell.

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