Contoh ekstensi parser

Didukung di:

Dokumen ini memberikan contoh pembuatan ekstensi parser dalam berbagai skenario. Untuk mempelajari ekstensi parser lebih lanjut, lihat Membuat ekstensi parser.

Contoh ekstensi parser

Gunakan tabel atribut berikut untuk menemukan contoh kode yang Anda perlukan dengan cepat.

Contoh tanpa kode

Format sumber log Contoh judul Deskripsi Konsep parser dalam contoh ini
JSON
(Jenis log: GCP_IDS)
Mengekstrak kolom Mengekstrak kolom dari log dalam format JSON. No-code
JSON
(Jenis log: WORKSPACE_ALERTS)
Mengekstrak kolom dengan Nilai Prasyarat Ekstrak kolom dari log dalam format JSON dan normalisasi menjadi kolom UDM berulang, dengan prasyarat.

Contoh cuplikan kode

Format sumber log Contoh judul Deskripsi Konsep parser dalam contoh ini
JSON
(Jenis log: GCP_IDS)
Menambahkan Agen Pengguna HTTP
  • Ekstrak Agen Pengguna Network HTTP Parser dan buat target hostname dari requestUrl.
  • Tetapkan Namespace untuk memastikan penamaan sebutan dan pengayaan berbasis Aset dilakukan.
CSV
(Jenis log: MISP_IOC)
Ekstraksi kolom arbitrer ke dalam objek UDM additional Mengekstrak kolom ke UDM > Entity > additional UDM Object > key-value-pair Objek UDM additional
Syslog
(Jenis log: POWERSHELL)
Mengekstrak Prioritas dan Tingkat Keparahan dari Syslog Ekstrak nilai Syslog Facility dan Severity ke kolom Prioritas dan Tingkat Keparahan Hasil Keamanan UDM. Berbasis Grok
JSON dengan header Syslog
(Jenis log: WINDOWS_SYSMON)
Dekorasi berdasarkan pernyataan kondisional
  • Menambahkan dekorasi (informasi kontekstual) ke kolom metadata.description berdasarkan pernyataan kondisional dan memahami jenis data dalam cuplikan kode.
  • Saat menggunakan filter ekstraksi, jenis data asli dapat dipertahankan.
  • Pernyataan bersyarat Grok harus menggunakan jenis data asli untuk mengevaluasi kolom.
  • Berbasis Grok
  • Pernyataan kondisional Grok
  • Jenis data asli kolom yang diekstrak dapat dipertahankan.
  • Pernyataan bersyarat Grok harus menggunakan jenis data asli untuk mengevaluasi kolom.
JSON dengan header Syslog
(Jenis log: WINDOWS_SYSMON)
Mengonversi jenis data
  • Konversi jenis data dalam ekstensi parser menggunakan fungsi convert.
  • Gunakan pernyataan on_error untuk memastikan penanganan error yang tepat dan menghindari kegagalan ekstensi parser yang disebabkan oleh error.
  • Berbasis Grok
  • Mengonversi jenis data
  • Gunakan pernyataan on_error untuk memberikan penanganan error.
JSON dengan header Syslog
(Jenis log: WINDOWS_SYSMON)
Nama variabel sementara untuk keterbacaan Anda dapat menggunakan nama variabel sementara dalam cuplikan kode, lalu mengganti namanya agar cocok dengan nama objek Peristiwa UDM output akhir. Hal ini dapat membantu keterbacaan secara keseluruhan.
  • Berbasis Grok
  • Gunakan nama variabel sementara, lalu ganti namanya menjadi nama UDM output akhir.
JSON dengan header Syslog
(Jenis log: WINDOWS_SYSMON)
Kolom berulang Berhati-hatilah saat menggunakan kolom berulang dalam cuplikan kode, misalnya, kolom security_result.
XML
(Jenis log: WINDOWS_DEFENDER_AV)
Ekstraksi kolom arbitrer ke dalam objek additional
  • Ekstrak dan simpan nilai Platform Version, misalnya, agar dapat melaporkan dan menelusuri versi platform yang sudah usang.
  • Dalam contoh ini, tidak ada kolom UDM standar yang sesuai, sehingga objek additional digunakan untuk menyimpan informasi sebagai pasangan nilai kunci kustom.
Objek additional digunakan untuk menyimpan informasi sebagai key-value pair kustom.
XML
(Jenis log: WINDOWS_DEFENDER_AV)
Ekstraksi kolom arbitrer ke dalam Hostname Utama
  • Mengekstrak Nama Host dari FQDN.
  • Pemrosesan bersyarat digunakan untuk menentukan apakah kolom principal.hostname harus ditimpa.
  • Pernyataan Grok menggunakan ekspresi reguler (regex) untuk mengekstrak kolom hostname. Regex itu sendiri menggunakan grup pengambilan bernama, yang berarti, apa pun yang cocok di dalam tanda kurung akan disimpan di kolom bernama hostname, yang cocok dengan satu atau beberapa karakter hingga menemukan titik. Tindakan ini hanya akan mengambil hostname dalam FQDN.
Pernyataan overwrite Grok
  • Namun, saat menjalankan PREVIEW UDM OUTPUT, error akan ditampilkan: "LOG_PARSING_CBN_ERROR: Kolom hostname sudah ada dalam data dan tidak dapat ditimpa".
  • Dalam pernyataan Grok, grup tangkapan bernama tidak dapat menimpa variabel yang ada, kecuali jika ditentukan secara eksplisit menggunakan pernyataan overwrite. Dalam skenario ini, kita dapat menggunakan nama variabel yang berbeda untuk grup pengambilan bernama dalam pernyataan Grok, atau (seperti yang ditunjukkan dalam contoh ini), menggunakan pernyataan overwrite untuk menimpa variabel nama host yang ada secara eksplisit.
  • Berbasis Grok
  • Pemrosesan bersyarat digunakan untuk menentukan apakah kolom harus ditimpa.
  • Pernyataan Grok menggunakan ekspresi reguler (regex).
  • Pernyataan overwrite Grok

Contoh JSON

Contoh berikut menunjukkan cara membuat ekstensi parser dengan sumber log dalam format JSON.

Tanpa kode - Mengekstrak kolom

Contoh atribut:

  • Format sumber log: JSON
  • Pendekatan pemetaan data: tanpa kode
  • Jenis log: GCP_IDS
  • Tujuan ekstensi parser: Mengekstrak kolom.
  • Deskripsi:

    Beberapa kolom terkait jaringan tidak diekstrak. Karena contoh log ini adalah log terstruktur dalam format JSON, kita dapat menggunakan pendekatan tanpa kode (Bidang data peta) untuk membuat ekstensi parser.

    Kolom asli yang ingin diekstrak adalah:

    • total_packets (string)
    • elapsed_time (string)
    • total_bytes (string)

    Berikut adalah contoh entri log mentah:

    {
    "insertId": "625a41542d64c124e7db097ae0906ccb-1@a3",
    "jsonPayload": {
      "destination_port": "80",
      "application": "incomplete",
      "ip_protocol": "tcp",
      "network": "projects/prj-p-shared-base/global/networks/shared-vpc-production",
      "start_time": "2024-10-29T21:14:59Z",
      "source_port": "41936",
      "source_ip_address": "35.191.200.157",
      "total_packets": "6",
      "elapsed_time": "0",
      "destination_ip_address": "192.168.0.11",
      "total_bytes": "412",
      "repeat_count": "1",
      "session_id": "1289742"
    },
    "resource": {
      "type": "ids.googleapis.com/Endpoint",
      "labels": {
        "resource_container": "projects/12345678910",
        "location": "europe-west4-a",
        "id": "p-europe-west4"
      }
    },
    "timestamp": "2024-10-29T21:15:21Z",
    "logName": "projects/prj-p-shared-base/logs/ids.googleapis.com%2Ftraffic",
    "receiveTimestamp": "2024-10-29T21:15:24.051990717Z"
    }
    

    Contoh ini menggunakan pendekatan tanpa kode untuk membuat ekstensi parser menggunakan pemetaan kolom data berikut:

    Jalur Prasyarat Operator Prasyarat Nilai Prasyarat Jalur Data Mentah Bidang Tujuan*
    jsonPayload.total_bytes NOT_EQUALS "" jsonPayload.total_bytes udm.principal.network.received_bytes
    jsonPayload.elapsed_time NOT_EQUALS "" jsonPayload.elapsed_time udm.principal.network.session_duration.seconds
    jsonPayload.total_packets NOT_EQUALS "" jsonPayload.total_packets udm.principal.network.received_packets

    Menjalankan ekstensi parser berhasil menambahkan tiga kolom yang diekstrak ke dalam objek principal.network.

    metadata.product_log_id = "625a41542d64c124e7db097ae0906ccb-1@a3"
    metadata.event_timestamp = "2024-10-29T21:14:59Z"
    metadata.event_type = "NETWORK_CONNECTION"
    metadata.vendor_name = "Google Cloud"
    metadata.product_name = "IDS"
    metadata.ingestion_labels[0].key = "label"
    metadata.ingestion_labels[0].value = "GCP_IDS"
    metadata.log_type = "GCP_IDS"
    principal.ip[0] = "35.191.200.157"
    principal.port = 41936
    principal.network.received_bytes = 412
    principal.network.session_duration.seconds = "0s"
    principal.network.received_packets = 6
    target.ip[0] = "192.168.0.11"
    target.port = 80
    target.application = "incomplete"
    observer.location.country_or_region = "EUROPE"
    observer.location.name = "europe-west4-a"
    observer.resource.name = "projects/12345678910"
    observer.resource.resource_type = "CLOUD_PROJECT"
    observer.resource.attribute.cloud.environment = "GOOGLE_CLOUD_PLATFORM"
    observer.resource.product_object_id = "p-europe-west4"
    network.ip_protocol = "TCP"
    network.session_id = "1289742"
    

Tanpa kode - Mengekstrak kolom dengan Nilai Prasyarat

Contoh atribut:

  • Format sumber log: JSON
  • Pendekatan pemetaan data: tanpa kode
  • Jenis log: WORKSPACE_ALERTS
  • Tujuan ekstensi parser: Mengekstrak kolom dengan Nilai Prasyarat.
  • Deskripsi:

    Parser asli tidak mengekstrak email address dari pengguna utama yang terpengaruh oleh pemberitahuan DLP (Pencegahan Kebocoran Data).

    Contoh ini menggunakan ekstensi parser tanpa kode untuk mengekstrak email address dan menormalisasinya ke dalam kolom UDM yang diulang, dengan prasyarat.

    Saat menggunakan kolom berulang di ekstensi parser tanpa kode, Anda harus menunjukkan apakah Anda ingin:

    • replace (ganti semua nilai kolom berulang dalam objek UDM yang ada), atau
    • append (tambahkan nilai yang diekstrak ke kolom berulang).

    Untuk mengetahui detail selengkapnya, lihat bagian Kolom berulang.

    Contoh ini mengganti Alamat Email yang ada di kolom principal.user.email_address yang dinormalisasi.

    Prasyarat memungkinkan Anda melakukan pemeriksaan kondisional sebelum melakukan operasi ekstraksi. Pada umumnya, Kolom Prasyarat akan berupa kolom yang sama dengan Kolom Data Mentah yang ingin diekstrak, dengan Operator Prasyarat not Null, misalnya, foo != "".

    Namun, terkadang, seperti dalam contoh kami, nilai Raw Data Field yang ingin Anda ekstrak tidak ada di semua entri log. Dalam hal ini, Anda dapat menggunakan Kolom Prasyarat lain untuk memfilter operasi ekstraksi. Dalam contoh kami, kolom triggeringUserEmail mentah yang ingin diekstrak hanya ada dalam log tempat type = Data Loss Prevention.

    Berikut adalah contoh nilai yang akan dimasukkan ke kolom ekstensi parser tanpa kode:

    Jalur Prasyarat Operator Prasyarat Nilai Prasyarat Jalur Data Mentah Bidang Tujuan*
    type SAMA DENGAN Pencegahan Kebocoran Data data.ruleViolationInfo.triggeringUserEmail udm.principal.user.email_addresses

    Contoh berikut menunjukkan kolom ekstensi parser tanpa kode yang diisi dengan nilai contoh:

    image2

    Menjalankan ekstensi parser berhasil menambahkan email_address ke dalam objek principal.user.

    metadata.product_log_id = "Ug71LGqBr6Q="
    metadata.event_timestamp = "2022-12-18T12:17:35.154368Z"
    metadata.event_type = "USER_UNCATEGORIZED"
    metadata.vendor_name = "Google Workspace"
    metadata.product_name = "Google Workspace Alerts"
    metadata.product_event_type = "DlpRuleViolation"
    metadata.log_type = "WORKSPACE_ALERTS"
    additional.fields["resource_title"] = "bq-results-20221215-112933-1671103787123.csv"
    principal.user.email_addresses[0] = "foo.bar@altostrat.com"
    target.resource.name = "DRIVE"
    target.resource.resource_type = "STORAGE_OBJECT"
    target.resource.product_object_id = "1wLteoF3VHljS_8_ABCD_VVbhFTfcTQplJ5k1k7cL4r8"
    target.labels[0].key = "resource_title"
    target.labels[0].value = "bq-results-20221321-112933-1671103787697.csv"
    about[0].resource.resource_type = "CLOUD_ORGANIZATION"
    about[0].resource.product_object_id = "C01abcde2"
    security_result[0].about.object_reference.id = "ODU2NjEwZTItMWE2YS0xMjM0LWJjYzAtZTJlMWU2YWQzNzE3"
    security_result[0].category_details[0] = "Data Loss Prevention"
    security_result[0].rule_name = "Sensitive Projects Match"
    security_result[0].summary = "Data Loss Prevention"
    security_result[0].action[0] = "ALLOW"
    security_result[0].severity = "MEDIUM"
    security_result[0].rule_id = "rules/00abcdxs183abcd"
    security_result[0].action_details = "ALERT, DRIVE_WARN_ON_EXTERNAL_SHARING"
    security_result[0].alert_state = "ALERTING"
    security_result[0].detection_fields[0].key = "start_time"
    security_result[0].detection_fields[0].value = "2022-12-18T12:17:35.154368Z"
    security_result[0].detection_fields[1].key = "status"
    security_result[0].detection_fields[1].value = "NOT_STARTED"
    security_result[0].detection_fields[2].key = "trigger"
    security_result[0].detection_fields[2].value = "DRIVE_SHARE"
    security_result[0].rule_labels[0].key = "detector_name"
    security_result[0].rule_labels[0].value = "EMAIL_ADDRESS"
    network.email.to[0] = "foo.bar@altostrat.com"
    

Cuplikan Kode - Menambahkan Agen Pengguna HTTP

Contoh atribut:

  • Format sumber log: JSON
  • Pendekatan pemetaan data: cuplikan kode
  • Jenis log: GCP_IDS
  • Tujuan ekstensi parser: Menambahkan Agen Pengguna HTTP.
  • Deskripsi:

    Ini adalah contoh jenis objek UDM non-standar yang tidak didukung oleh pendekatan tanpa kode sehingga memerlukan penggunaan cuplikan kode. Parser default tidak mengekstrak analisis Network HTTP Parser User Agent. Selain itu, untuk konsistensi:

    1. Target Hostname akan dibuat dari requestUrl.
    2. Namespace akan ditetapkan untuk memastikan Penambahan nama dan pengayaan berbasis aset dilakukan.
    # GCP_LOADBALANCING
    # owner: @owner
    # updated: 2022-12-23
    # Custom parser extension that:
    # 1) adds consistent Namespace 
    # 2) adds Parsed User Agent Object 
    filter {
        # Initialize placeholder
        mutate {
            replace => {
                "httpRequest.userAgent" => ""
                "httpRequest.requestUrl" => ""
            }
        }
        json {
            on_error => "not_json"
            source => "message"
            array_function => "split_columns"
        }
        if ![not_json] {
          #1 - Override Namespaces
            mutate {
                replace => {
                    "event1.idm.read_only_udm.principal.namespace" => "TMO"
                }
            }
            mutate {
                replace => {
                    "event1.idm.read_only_udm.target.namespace" => "TMO"
                }
            }
            mutate {
                replace => {
                    "event1.idm.read_only_udm.src.namespace" => "TMO"
                }
            }
            #2 - Parsed User Agent
            if [httpRequest][requestUrl]!= "" {
                grok {
                    match => {
                        "httpRequest.requestUrl" => ["\/\/(?P<_hostname>.*?)\/"]
                    }
                    on_error => "_grok_hostname_failed"
                }
                if ![_grok_hostname_failed] {
                    mutate {
                        replace => {
                            "event1.idm.read_only_udm.target.hostname" => "%{_hostname}"
                        }
                    }
                }
            }
            if [httpRequest][userAgent] != "" {
                mutate {
                    convert => {
                        "httpRequest.userAgent" => "parseduseragent"
                    }
                }
                #Map the converted "user_agent" to the new UDM field "http.parsed_user_agent".
                mutate {
                    rename => {
                        "httpRequest.userAgent" => "event1.idm.read_only_udm.network.http.parsed_user_agent"
                    }
                }
            }
            mutate {
                merge => {
                    "@output" => "event1"
                }
            }
        }
    }
    

Contoh CSV

Contoh berikut menunjukkan cara membuat ekstensi parser dengan sumber log dalam format CSV.

Cuplikan Kode - Ekstraksi kolom arbitrer ke dalam objek additional

Contoh atribut:

  • Format sumber log: CSV
  • Pendekatan pemetaan data: cuplikan kode
  • Jenis log: MISP_IOC
  • Tujuan ekstensi parser: Ekstraksi kolom arbitrer ke dalam objek additional.
  • Deskripsi:

    Dalam contoh ini, integrasi Konteks Entitas UDM MISP_IOC digunakan. Objek UDM pasangan nilai kunci additional akan digunakan untuk mengambil informasi kontekstual yang tidak diekstrak oleh parser default, dan untuk menambahkan kolom khusus per organisasi. Misalnya, URL kembali ke instance MISP tertentu.

    Berikut adalah sumber log berbasis CSV untuk contoh ini:

    1 9d66d38a-14e1-407f-a4d1-90b82aa1d59f
    2 3908
    3 Network activity
    4 ip-dst
    5 117.253.154.123
    6
    7
    8 1687894564
    9
    10
    11
    12
    13
    14 DigitalSide Malware report\: MD5\: 59ce0baba11893f90527fc951ac69912
    15 ORGNAME
    16 DIGITALSIDE.IT
    17 0
    18 Medium
    19 0
    20 2023-06-23
    21 tlp:white,type:OSINT,source:DigitalSide.IT,source:urlhaus.abuse.ch
    22 1698036218

    gambar

    # MISP_IOC
    # owner: @owner
    # updated: 2024-06-21
    # Custom parser extension that:
    # 1) adds a link back to internal MISP tenant 
    # 2) extracts missing fields into UDM > Entity > Additional fields
    filter {
        # Set the base URL for MISP. Remember to replace this placeholder!
        mutate {
            replace => {
                "misp_base_url" => "https://<YOUR_MISP_URL>"
            }
        }
        # Parse the CSV data from the 'message' field. Uses a comma as the separator.
        # The 'on_error' option handles lines that are not properly formatted CSV.
        csv {
            source => "message"
            separator => ","
            on_error => "broken_csv"
        }
        # If the CSV parsing was successful...
        if ![broken_csv] {
            # Rename the CSV columns to more descriptive names.
            mutate {
                rename => {
                    "column2" => "event_id"
                    "column8" => "object_timestamp"
                    "column16" => "event_source_org"
                    "column17" => "event_distribution"
                    "column19" => "event_analysis"
                    "column22" => "attribute_timestamp"
                }
            }
        }
        # Add a link to view the event in MISP, if an event ID is available.
        # "column2" => "event_id"
        if [event_id] != "" {
            mutate {
                replace => {
                    "additional_url.key" => "view_in_misp"
                    "additional_url.value.string_value" => "%{misp_base_url}/events/view/%{event_id}"
                }
            }
            mutate {
                merge => {
                    "event.idm.entity.additional.fields" => "additional_url"
                }
            }
        }
        # Add the object timestamp as an additional field, if available.
        # "column8" => "object_timestamp"
        if [object_timestamp] != "" {
            mutate {
                replace => {
                    "additional_object_timestamp.key" => "object_timestamp"
                    "additional_object_timestamp.value.string_value" => "%{object_timestamp}"
                }
            }
            mutate {
                merge => {
                    "event.idm.entity.additional.fields" => "additional_object_timestamp"
                }
            }
        }
        # Add the event source organization as an additional field, if available.
        # "column16" => "event_source_org"
        if [event_source_org] != "" {
            mutate {
                replace => {
                    "additional_event_source_org.key" => "event_source_org"
                    "additional_event_source_org.value.string_value" => "%{event_source_org}"
                }
            }
            mutate {
                merge => {
                    "event.idm.entity.additional.fields" => "additional_event_source_org"
                }
            }
        }
        # Add the event distribution level as an additional field, if available.
        # Maps numerical values to descriptive strings.
        # "column17" => "event_distribution"
        if [event_distribution] != "" {
            if [event_distribution] == "0" {
                mutate {
                    replace => {
                        "additional_event_distribution.value.string_value" => "YOUR_ORGANIZATION_ONLY"
                    }
                }
            } else if [event_distribution] == "1" {
                mutate {
                    replace => {
                        "additional_event_distribution.value.string_value" => "THIS_COMMUNITY_ONLY"
                    }
                }
            } else if [event_distribution] == "2" {
                mutate {
                    replace => {
                        "additional_event_distribution.value.string_value" => "CONNECTED_COMMUNITIES"
                    }
                }
            } else if [event_distribution] == "3" {
                mutate {
                    replace => {
                        "additional_event_distribution.value.string_value" => "ALL_COMMUNITIES"
                    }
                }
            } else if [event_distribution] == "4" {
                mutate {
                    replace => {
                        "additional_event_distribution.value.string_value" => "SHARING_GROUP"
                    }
                }
            } else if [event_distribution] == "5" {
                mutate {
                    replace => {
                        "additional_event_distribution.value.string_value" => "INHERIT_EVENT"
                    }
                }
            }
            mutate {
                replace => {
                    "additional_event_distribution.key" => "event_distribution"
                }
            }
            mutate {
                merge => {
                    "event.idm.entity.additional.fields" => "additional_event_distribution"
                }
            }
        }
        # Add the event analysis level as an additional field, if available.
        # Maps numerical values to descriptive strings.
        # "column19" => "event_analysis"
        if [event_analysis] != "" {
            if [event_analysis] == "0" {
                mutate {
                    replace => {
                        "additional_event_analysis.value.string_value" => "INITIAL"
                    }
                }
            } else if [event_analysis] == "1" {
                mutate {
                    replace => {
                        "additional_event_analysis.value.string_value" => "ONGOING"
                    }
                }
            } else if [event_analysis] == "2" {
                mutate {
                    replace => {
                        "additional_event_analysis.value.string_value" => "COMPLETE"
                    }
                }
            }
            mutate {
                replace => {
                    "additional_event_analysis.key" => "event_analysis"
                }
            }
            mutate {
                merge => {
                    "event.idm.entity.additional.fields" => "additional_event_analysis"
                }
            }
        }
        # Add the attribute timestamp as an additional field, if available.
        # "column22" => "attribute_timestamp" 
        if [attribute_timestamp] != "" {
            mutate {
                replace => {
                    "additional_attribute_timestamp.key" => "attribute_timestamp"
                    "additional_attribute_timestamp.value.string_value" => "%{attribute_timestamp}"
                }
            }
            mutate {
                merge => {
                    "event.idm.entity.additional.fields" => "additional_attribute_timestamp"
                }
            }
        }
        # Finally, merge the 'event' data into the '@output' field.
        mutate {
            merge => {
                "@output" => "event"
            }
        }
    }
    

    Menjalankan ekstensi parser berhasil menambahkan kolom kustom dari CSV ke objek additional.

    metadata.product_entity_id = "9d66d38a-14e1-407f-a4d1-90b82aa1d59f"
    metadata.collected_timestamp = "2024-10-31T15:16:08Z"
    metadata.vendor_name = "MISP"
    metadata.product_name = "MISP"
    metadata.entity_type = "IP_ADDRESS"
    metadata.description = "ip-dst"
    metadata.interval.start_time = "2023-06-27T19:36:04Z"
    metadata.interval.end_time = "9999-12-31T23:59:59Z"
    metadata.threat[0].category_details[0] = "Network activity"
    metadata.threat[0].description = "tlp:white,type:OSINT,source:DigitalSide.IT,source:urlhaus.abuse.ch - additional info: DigitalSide Malware report: MD5: 59ce0baba11893f90527fc951ac69912"
    metadata.threat[0].severity_details = "Medium"
    metadata.threat[0].threat_feed_name = "DIGITALSIDE.IT"
    entity.ip[0] = "117.253.154.123"
    additional.fields["view_in_misp"] = "https:///events/view/3908"
    additional.fields["object_timestamp"] = "1687894564"
    additional.fields["event_source_org"] = "DIGITALSIDE.IT"
    additional.fields["event_distribution"] = "YOUR_ORGANIZATION_ONLY"
    additional.fields["event_analysis"] = "INITIAL"
    additional.fields["attribute_timestamp"] = "1698036218"
    

Contoh Grok

Contoh berikut menunjukkan cara membuat ekstensi parser berbasis Grok.

Cuplikan Kode (dan Grok) - Mengekstrak Prioritas dan Tingkat Keparahan

Contoh atribut:

  • Format sumber log: Syslog
  • Pendekatan pemetaan data: cuplikan kode menggunakan Grok
  • Jenis log: POWERSHELL
  • Tujuan ekstensi parser: Mengekstrak Prioritas dan Tingkat Keparahan.
  • Deskripsi:

    Dalam contoh ini, ekstensi parser berbasis Grok dibuat untuk mengekstrak nilai Syslog Facility and Severity ke dalam kolom Priority dan Severity Hasil Keamanan UDM.

    filter {
        # Use grok to parse syslog messages. The on_error clause handles messages that don't match the pattern.
        grok {
            match => {
                "message" => [
                    # Extract message with syslog headers.
                    "(<%{POSINT:_syslog_priority}>)%{SYSLOGTIMESTAMP:datetime} %{DATA:logginghost}: %{GREEDYDATA:log_data}"
                ]
            }
            on_error => "not_supported_format"
        }
        # If the grok parsing failed, tag the event as unsupported and drop it.
        if ![not_supported_format] {
            if [_syslog_priority] != "" {
                if [_syslog_priority] =~ /0|8|16|24|32|40|48|56|64|72|80|88|96|104|112|120|128|136|144|152|160|168|176|184/ {
                    mutate { replace => { "_security_result.severity_details" => "EMERGENCY" } } 
                }
                if [_syslog_priority] =~ /1|9|17|25|33|41|49|57|65|73|81|89|97|105|113|121|129|137|145|153|161|169|177|185/ {
                    mutate { replace => { "_security_result.severity_details" => "ALERT" } } 
                }
                if [_syslog_priority] =~ /2|10|18|26|34|42|50|58|66|74|82|90|98|106|114|122|130|138|146|154|162|170|178|186/ {
                    mutate { replace => { "_security_result.severity_details" => "CRITICAL" } }
                }
                if [_syslog_priority] =~ /3|11|19|27|35|43|51|59|67|75|83|91|99|107|115|123|131|139|147|155|163|171|179|187/ {
                    mutate { replace => { "_security_result.severity_details" => "ERROR" } }
                }
                if [_syslog_priority] =~ /4|12|20|28|36|44|52|60|68|76|84|92|100|108|116|124|132|140|148|156|164|172|180|188/ {
                    mutate { replace => { "_security_result.severity_details" => "WARNING" } }
                }
                if [_syslog_priority] =~ /5|13|21|29|37|45|53|61|69|77|85|93|101|109|117|125|133|141|149|157|165|173|181|189/ {
                    mutate { replace => { "_security_result.severity_details" => "NOTICE" } }
                }
                if [_syslog_priority] =~ /6|14|22|30|38|46|54|62|70|78|86|94|102|110|118|126|134|142|150|158|166|174|182|190/ {
                    mutate { replace => { "_security_result.severity_details" => "INFORMATIONAL" } }
                }
                if [_syslog_priority] =~ /7|15|23|31|39|47|55|63|71|79|87|95|103|111|119|127|135|143|151|159|167|175|183|191/ {
                    mutate { replace => { "_security_result.severity_details" => "DEBUG" } }
                }
                # Facilities (mapped to priority)
                if [_syslog_priority] =~ /0|1|2|3|4|5|6|7/ { 
                    mutate { replace => { "_security_result.priority_details" => "KERNEL" } } 
                }
                if [_syslog_priority] =~ /8|9|10|11|12|13|14|15/ { 
                    mutate { replace => { "_security_result.priority_details" => "USER" } } 
                }
                if [_syslog_priority] =~ /16|17|18|19|20|21|22|23/ { 
                    mutate { replace => { "_security_result.priority_details" => "MAIL" } } 
                }
                if [_syslog_priority] =~ /24|25|26|27|28|29|30|31/ { 
                    mutate { replace => { "_security_result.priority_details" => "SYSTEM" } } 
                }
                if [_syslog_priority] =~ /32|33|34|35|36|37|38|39/ { 
                    mutate { replace => { "_security_result.priority_details" => "SECURITY" } } 
                }
                if [_syslog_priority] =~ /40|41|42|43|44|45|46|47/ { 
                    mutate { replace => { "_security_result.priority_details" => "SYSLOG" } } 
                }
                if [_syslog_priority] =~ /48|49|50|51|52|53|54|55/ { 
                    mutate { replace => { "_security_result.priority_details" => "LPD" } } 
                }
                if [_syslog_priority] =~ /56|57|58|59|60|61|62|63/ { 
                    mutate { replace => { "_security_result.priority_details" => "NNTP" } } 
                }
                if [_syslog_priority] =~ /64|65|66|67|68|69|70|71/ { 
                    mutate { replace => { "_security_result.priority_details" => "UUCP" } } 
                }
                if [_syslog_priority] =~ /72|73|74|75|76|77|78|79/ { 
                    mutate { replace => { "_security_result.priority_details" => "TIME" } } 
                }
                if [_syslog_priority] =~ /80|81|82|83|84|85|86|87/ { 
                    mutate { replace => { "_security_result.priority_details" => "SECURITY" } } 
                }
                if [_syslog_priority] =~ /88|89|90|91|92|93|94|95/ { 
                    mutate { replace => { "_security_result.priority_details" => "FTPD" } } 
                }
                if [_syslog_priority] =~ /96|97|98|99|100|101|102|103/ { 
                    mutate { replace => { "_security_result.priority_details" => "NTPD" } } 
                }
                if [_syslog_priority] =~ /104|105|106|107|108|109|110|111/ { 
                    mutate { replace => { "_security_result.priority_details" => "LOGAUDIT" } } 
                }
                if [_syslog_priority] =~ /112|113|114|115|116|117|118|119/ { 
                    mutate { replace => { "_security_result.priority_details" => "LOGALERT" } } 
                }
                if [_syslog_priority] =~ /120|121|122|123|124|125|126|127/ { 
                    mutate { replace => { "_security_result.priority_details" => "CLOCK" } } 
                }
                if [_syslog_priority] =~ /128|129|130|131|132|133|134|135/ { 
                    mutate { replace => { "_security_result.priority_details" => "LOCAL0" } } 
                }
                if [_syslog_priority] =~ /136|137|138|139|140|141|142|143/ { 
                    mutate { replace => { "_security_result.priority_details" => "LOCAL1" } } 
                }
                if [_syslog_priority] =~ /144|145|146|147|148|149|150|151/ { 
                    mutate { replace => { "_security_result.priority_details" => "LOCAL2" } } 
                }
                if [_syslog_priority] =~ /152|153|154|155|156|157|158|159/ { 
                    mutate { replace => { "_security_result.priority_details" => "LOCAL3" } } 
                }
                if [_syslog_priority] =~ /160|161|162|163|164|165|166|167/ { 
                    mutate { replace => { "_security_result.priority_details" => "LOCAL4" } } 
                }
                if [_syslog_priority] =~ /168|169|170|171|172|173|174|175/ { 
                    mutate { replace => { "_security_result.priority_details" => "LOCAL5" } } 
                }
                if [_syslog_priority] =~ /176|177|178|179|180|181|182|183/ { 
                    mutate { replace => { "_security_result.priority_details" => "LOCAL6" } } 
                }
                if [_syslog_priority] =~ /184|185|186|187|188|189|190|191/ { 
                    mutate { replace => { "_security_result.priority_details" => "LOCAL7" } } 
                }
                mutate {
                    merge => {
                        "event.idm.read_only_udm.security_result" => "_security_result"
                    }
                }
            }
            mutate {
                merge => {
                    "@output" => "event"
                }
            }
        }
    }
    

    Melihat hasil dari ekstensi parser akan menampilkan format yang dapat dibaca manusia.

    metadata.product_log_id = "6161053"
    metadata.event_timestamp = "2024-10-31T15:10:10Z"
    metadata.event_type = "PROCESS_LAUNCH"
    metadata.vendor_name = "Microsoft"
    metadata.product_name = "PowerShell"
    metadata.product_event_type = "600"
    metadata.description = "Info"
    metadata.log_type = "POWERSHELL"
    principal.hostname = "win-adfs.lunarstiiiness.com"
    principal.resource.name = "in_powershell"
    principal.resource.resource_subtype = "im_msvistalog"
    principal.asset.hostname = "win-adfs.lunarstiiiness.com"
    target.hostname = "Default Host"
    target.process.command_line = "C:\Program Files\Microsoft Azure AD Sync\Bin\miiserver.exe"
    target.asset.hostname = "Default Host"
    target.asset.asset_id = "Host ID:bf203e94-72cf-4649-84a5-fc02baedb75f"
    security_result[0].severity_details = "INFORMATIONAL"
    security_result[0].priority_details = "USER"
    

Cuplikan Kode (dan Grok) - Dekorasi peristiwa, nama variabel sementara, dan konversi jenis data

Contoh atribut:

  • Format sumber log: JSON dengan header Syslog
  • Pendekatan pemetaan data: cuplikan kode menggunakan Grok
  • Jenis log: WINDOWS_SYSMON
  • Tujuan ekstensi parser: Menata peristiwa, Nama variabel sementara, dan Jenis data.
  • Deskripsi:

    Contoh ini menunjukkan cara melakukan tindakan berikut saat membuat ekstensi parser:

    Dekorasi berdasarkan pernyataan kondisional

    Contoh ini menambahkan (informasi kontekstual) penjelasan tentang arti setiap jenis peristiwa di WINDOWS_SYSMON. Fungsi ini menggunakan pernyataan bersyarat untuk memeriksa EventID, lalu menambahkan Description, misalnya, EventID 1 adalah peristiwa Process Creation.

    Saat menggunakan filter ekstraksi, misalnya, JSON, jenis data asli dapat dipertahankan.

    Dalam contoh berikut, nilai EventID diekstrak sebagai Bilangan Bulat secara default. Pernyataan kondisional mengevaluasi nilai EventID sebagai Bilangan Bulat, bukan String.

    if [EventID] == 1 {
      mutate {
        replace => {
          "_description" => "[1] Process creation"
        }
      }
    }
    

    Konversi jenis data

    Anda dapat mengonversi jenis data dalam ekstensi parser menggunakan fungsi konversi.

    mutate {
      convert => {
        "EventID" => "string"
      }
      on_error => "_convert_EventID_already_string"
    }
    

    Nama variabel sementara untuk keterbacaan

    Anda dapat menggunakan nama variabel sementara dalam cuplikan kode, lalu mengganti namanya agar cocok dengan nama objek Peristiwa UDM output akhir. Hal ini dapat membantu keterbacaan keseluruhan.

    Dalam contoh berikut, variabel description diganti namanya menjadi event.idm.read_only_udm.metadata.description:

    mutate {
      rename => {
        "_description" => "event.idm.read_only_udm.metadata.description"
      }
    }
    

    Kolom berulang

    Ekstensi parser lengkap adalah sebagai berikut:

    filter {
    # initialize variable
    mutate {
      replace => {
        "EventID" => ""
      }
    }
    # Use grok to parse syslog messages.
    # The on_error clause handles messages that don't match the pattern.
    grok {
      match => {
        "message" => [
          "(<%{POSINT:_syslog_priority}>)%{SYSLOGTIMESTAMP:datetime} %{DATA:logginghost}: %{GREEDYDATA:log_data}"
        ]
      }
      on_error => "not_supported_format"
    }
    if ![not_supported_format] {
      json {
        source => "log_data"
        on_error => "not_json"
      }
      if ![not_json] {
        if [EventID] == 1 {
          mutate {
            replace => {
              "_description" => "[1] Process creation"
            }
          }
        }
        if [EventID] == 2 {
          mutate {
            replace => {
              "_description" => "[2] A process changed a file creation time"
            }
          }
        }
        if [EventID] == 3 {
          mutate {
            replace => {
              "_description" => "[3] Network connection"
            }
          }
        }
        if [EventID] == 4 {
          mutate {
            replace => {
              "_description" => "[4] Sysmon service state changed"
            }
          }
        }
        if [EventID] == 5 {
          mutate {
            replace => {
              "_description" => "[5] Process terminated"
            }
          }
        }
        if [EventID] == 6 {
          mutate {
            replace => {
              "_description" => "[6] Driver loaded"
            }
          }
        }
        if [EventID] == 7 {
          mutate {
            replace => {
              "_description" => "[7] Image loaded"
            }
          }
        }
        if [EventID] == 8 {
          mutate {
            replace => {
              "_description" => "[8] CreateRemoteThread"
            }
          }
        }
        if [EventID] == 9 {
          mutate {
            replace => {
              "_description" => "[9] RawAccessRead"
            }
          }
        }
        if [EventID] == 10 {
          mutate {
            replace => {
              "_description" => "[10] ProcessAccess"
            }
          }
        }
        if [EventID] == 11 {
          mutate {
            replace => {
              "_description" => "[11] FileCreate"
            }
          }
        }
        if [EventID] == 12 {
          mutate {
            replace => {
              "_description" => "[12] RegistryEvent (Object create and delete)"
            }
          }
        }
        if [EventID] == 13 {
          mutate {
            replace => {
              "_description" => "[13] RegistryEvent (Value Set)"
            }
          }
        }
        if [EventID] == 14 {
          mutate {
            replace => {
              "_description" => "[14] RegistryEvent (Key and Value Rename)"
            }
          }
        }
        if [EventID] == 15 {
          mutate {
            replace => {
              "_description" => "[15] FileCreateStreamHash"
            }
          }
        }
        if [EventID] == 16 {
          mutate {
            replace => {
              "_description" => "[16] ServiceConfigurationChange"
            }
          }
        }
        if [EventID] == 17 {
          mutate {
            replace => {
              "_description" => "[17] PipeEvent (Pipe Created)"
            }
          }
        }
        if [EventID] == 18 {
          mutate {
            replace => {
              "_description" => "[18] PipeEvent (Pipe Connected)"
            }
          }
        }
        if [EventID] == 19 {
          mutate {
            replace => {
              "_description" => "[19] WmiEvent (WmiEventFilter activity detected)"
            }
          }
        }
        if [EventID] == 20 {
          mutate {
            replace => {
              "_description" => "[20] WmiEvent (WmiEventConsumer activity detected)"
            }
          }
        }
        if [EventID] == 21 {
          mutate {
            replace => {
              "_description" => "[21] WmiEvent (WmiEventConsumerToFilter activity detected)"
            }
          }
        }
        if [EventID] == 22 {
          mutate {
            replace => {
              "_description" => "[22] DNSEvent (DNS query)"
            }
          }
        }
        if [EventID] == 23 {
          mutate {
            replace => {
              "_description" => "[23] FileDelete (File Delete archived)"
            }
          }
        }
        if [EventID] == 24 {
          mutate {
            replace => {
              "_description" => "[24] ClipboardChange (New content in the clipboard)"
            }
          }
        }
        if [EventID] == 25 {
          mutate {
            replace => {
              "_description" => "[25] ProcessTampering (Process image change)"
            }
          }
        }
        if [EventID] == 26 {
          mutate {
            replace => {
              "_description" => "[26] FileDeleteDetected (File Delete logged)"
            }
          }
        }
        if [EventID] == 255 {
          mutate {
            replace => {
              "_description" => "[255] Error"
            }
          }
        }
        mutate {
          rename => {
            "_description" => "event.idm.read_only_udm.metadata.description"
          }
        }
        statedump{}
        mutate {
          merge => {
            "@output" => "event"
          }
        }
      }
    }
    }
    

    Menjalankan ekstensi parser berhasil menambahkan dekorasi ke kolom metadata.description.

    metadata.product_log_id = "6008459"
    metadata.event_timestamp = "2024-10-31T14:41:53.442Z"
    metadata.event_type = "REGISTRY_CREATION"
    metadata.vendor_name = "Microsoft"
    metadata.product_name = "Microsoft-Windows-Sysmon"
    metadata.product_event_type = "12"
    metadata.description = "[12] RegistryEvent (Object create and delete)"
    metadata.log_type = "WINDOWS_SYSMON"
    additional.fields["thread_id"] = "3972"
    additional.fields["channel"] = "Microsoft-Windows-Sysmon/Operational"
    additional.fields["Keywords"] = "-9223372036854776000"
    additional.fields["Opcode"] = "Info"
    additional.fields["ThreadID"] = "3972"
    principal.hostname = "win-adfs.lunarstiiiness.com"
    principal.user.userid = "tim.smith_admin"
    principal.user.windows_sid = "S-1-5-18"
    principal.process.pid = "6856"
    principal.process.file.full_path = "C:\Windows\system32\wsmprovhost.exe"
    principal.process.product_specific_process_id = "SYSMON:{927d35bf-a374-6495-f348-000000002900}"
    principal.administrative_domain = "LUNARSTIIINESS"
    principal.asset.hostname = "win-adfs.lunarstiiiness.com"
    target.registry.registry_key = "HKU\S-1-5-21-3263964631-4121654051-1417071188-1116\Software\Policies\Microsoft\SystemCertificates\CA\Certificates"
    observer.asset_id = "5770385F:C22A:43E0:BF4C:06F5698FFBD9"
    observer.process.pid = "2556"
    about[0].labels[0].key = "Category ID"
    about[0].labels[0].value = "RegistryEvent"
    security_result[0].rule_name = "technique_id=T1553.004,technique_name=Install Root Certificate"
    security_result[0].summary = "Registry object added or deleted"
    security_result[0].severity = "INFORMATIONAL"
    security_result[1].rule_name = "EventID: 12"
    security_result[2].summary = "12"
    

Contoh XML

Contoh berikut menunjukkan cara membuat ekstensi parser dengan sumber log dalam format XML.

Cuplikan Kode - Ekstraksi kolom arbitrer ke dalam objek additional

Contoh atribut:

  • Format sumber log: XML
  • Pendekatan pemetaan data: cuplikan kode
  • Jenis log: WINDOWS_DEFENDER_AV
  • Tujuan ekstensi parser: Ekstraksi kolom arbitrer ke dalam objek additional
  • Deskripsi:

    Tujuan contoh ini adalah mengekstrak dan menyimpan nilai Platform Version, misalnya, agar dapat melaporkan dan menelusuri outdated platform versions.

    Setelah meninjau dokumen Kolom UDM penting, tidak ada kolom UDM standar yang sesuai yang diidentifikasi. Oleh karena itu, contoh ini akan menggunakan objek additional untuk menyimpan informasi ini sebagai pasangan nilai kunci kustom.

    # Parser Extension for WINDOWS_DEFENDER_AV
    # 2024-10-29: cmmartin: Extracting 'Platform Version' into Additional
    filter {
        # Uses XPath to target the specific element(s)
        xml {
            source => "message"
                xpath => {
                    "/Event/EventData/Data[@Name='Platform version']" => "platform_version"
            }
            on_error => "_xml_error"
        }
        # Conditional processing: Only proceed if XML parsing was successful
        if ![_xml_error] {
            # Prepare the additional field structure using a temporary variable
            mutate{
                replace => {
                    "additional_platform_version.key" => "Platform Version"
                    "additional_platform_version.value.string_value" => "%{platform_version}"
                }
                on_error => "no_platform_version"
            }
            # Merge the additional field into the event1 structure.
            if ![no_platform_version] {
                mutate {
                    merge => {
                        "event1.idm.read_only_udm.additional.fields" => "additional_platform_version"
                    }
                }
            }
            mutate {
                merge => {
                    "@output" => "event1"
                }
            }
        }
    }
    

    Menjalankan PREVIEW UDM OUTPUT akan menampilkan bahwa kolom baru telah berhasil ditambahkan.

    metadata.event_timestamp = "2024-10-29T14:08:52Z"
    metadata.event_type = "STATUS_HEARTBEAT"
    metadata.vendor_name = "Microsoft"
    metadata.product_name = "Windows Defender AV"
    metadata.product_event_type = "MALWAREPROTECTION_SERVICE_HEALTH_REPORT"
    metadata.description = "Endpoint Protection client health report (time in UTC)."
    metadata.log_type = "WINDOWS_DEFENDER_AV"
    additional.fields["Platform Version"] = "4.18.24080.9"
    principal.hostname = "win-dc-01.ad.1823127835827.altostrat.com"
    security_result[0].description = "EventID: 1151"
    security_result[0].action[0] = "ALLOW"
    security_result[0].severity = "LOW"
    

Cuplikan Kode (dan Grok) - Ekstraksi kolom arbitrer ke Hostname Utama

Contoh atribut:

  • Format sumber log: XML
  • Pendekatan pemetaan data: cuplikan kode menggunakan Grok
  • Jenis log: WINDOWS_DEFENDER_AV
  • Tujuan ekstensi parser: Ekstraksi kolom arbitrer ke dalam Nama Host Utama
  • Deskripsi:

    Tujuan contoh ini adalah mengekstrak Hostname dari FQDN dan menulis ulang kolom principal.hostname.

    Contoh ini memeriksa apakah kolom Computer name log mentah menyertakan FQDN. Jika begitu, UDM hanya akan mengekstrak bagian Hostname, dan menimpa kolom Principal Hostname UDM.

    Setelah meninjau Parser dan dokumen Bidang UDM penting, jelas bahwa kolom principal.hostname harus digunakan.

    # Parser Extension for WINDOWS_DEFENDER_AV
    # 2024-10-29: Extract Hostname from FQDN and overwrite principal.hostname
    filter {
        # Uses XPath to target the specific element(s)
        xml {
            source => "message"
                xpath => {
                    "/Event/System/Computer" => "hostname"
            }
            on_error => "_xml_error"
        }
        # Conditional processing: Only proceed if XML parsing was successful
        if ![_xml_error] {
      # Extract all characters before the first dot in the hostname variable
            grok {
                match => { "hostname" => "(?<hostname>[^.]+)" }
            }
            mutate {
                replace => {
                    "event1.idm.read_only_udm.principal.hostname" => "%{hostname}"
                }
            }
            mutate {
                merge => {
                    "@output" => "event1"
                }
            }
        }
    }
    

    Ekstensi parser ini menggunakan pernyataan Grok untuk menjalankan ekspresi reguler (regex) guna mengekstrak kolom hostname. Regex itu sendiri menggunakan grup tangkapan bernama, yang berarti, apa pun yang cocok di dalam tanda kurung akan disimpan di kolom bernama hostname, yang cocok dengan satu atau beberapa karakter hingga menemukan titik. Tindakan ini hanya akan mengambil hostname dalam FQDN.

    Namun, saat menjalankan PREVIEW UDM OUTPUT, error akan ditampilkan. Mengapa begitu?

    generic::unknown: pipeline.ParseLogEntry failed:
     LOG_PARSING_CBN_ERROR: "generic::internal: pipeline failed: filter grok (2) failed: 
    field\ "hostname\" already exists in data and is not overwritable"
    

    Pernyataan overwrite Grok

    Dalam pernyataan Grok, grup tangkapan bernama tidak dapat menimpa variabel yang ada kecuali ditentukan secara eksplisit menggunakan pernyataan overwrite. Dalam skenario ini, kita dapat menggunakan nama variabel yang berbeda untuk grup pengambilan bernama dalam pernyataan Grok atau, seperti yang ditunjukkan dalam contoh cuplikan kode berikut, gunakan pernyataan overwrite untuk menimpa variabel hostname yang ada secara eksplisit.

    # Parser Extension for WINDOWS_DEFENDER_AV
    # 2024-10-29: cmmartin: Overwriting principal Hostname
    filter {
      xml {
        source => "message"
          xpath => {
            "/Event/System/Computer" => "hostname"
        }
        on_error => "_xml_error"
      }
      if ![_xml_error] {
        grok {
          match => { "hostname" => "(?<hostname>[^.]+)" }
          overwrite => ["hostname"]
          on_error => "_grok_hostname_error"
        }
        mutate {
          replace => {
            "event1.idm.read_only_udm.principal.hostname" => "%{hostname}"
          }
        }
        mutate {
          merge => {
            "@output" => "event1"
          }
        }
      }
    }
    

    Menjalankan PREVIEW UDM OUTPUT lagi akan menunjukkan bahwa kolom baru telah ditambahkan, setelah mengekstrak hostname dari FQDN.

    metadata.event_timestamp"2024-10-29T14:08:52Z"
    metadata.event_type"STATUS_HEARTBEAT"
    metadata.vendor_name"Microsoft"
    metadata.product_name"Windows Defender AV"
    metadata.product_event_type"MALWAREPROTECTION_SERVICE_HEALTH_REPORT"
    metadata.description"Endpoint Protection client health report (time in UTC)."
    metadata.log_type"WINDOWS_DEFENDER_AV"
    principal.hostname"win-dc-01"
    security_result[0].description"EventID: 1151"
    security_result[0].action[0]"ALLOW"
    security_result[0].severity"LOW"