Ejemplos de extensiones del analizador

Compatible con:

En este documento, se proporcionan ejemplos de la creación de extensiones del analizador en diferentes situaciones. Para obtener más información sobre las extensiones del analizador, consulta Crea extensiones del analizador.

Ejemplos de extensiones del analizador

Usa las siguientes tablas de atributos para encontrar rápidamente el código de muestra que necesitas.

Ejemplos sin código

Formato de la fuente del registro Título de ejemplo Descripción Conceptos del analizador en este ejemplo
JSON
(tipo de registro: GCP_IDS)
Extraer campos Extrae campos de un registro en formato JSON. Sin código
JSON
(tipo de registro: WORKSPACE_ALERTS)
Extrae campos con valor de condición previa Extrae campos de un registro en formato JSON y normalízalo en un campo UDM repetido, con una condición previa.

Ejemplos de fragmentos de código

Formato de la fuente del registro Título de ejemplo Descripción Conceptos del analizador en este ejemplo
JSON
(tipo de registro: `GCP_IDS`)
Cómo agregar un usuario-agente HTTP
  • Extrae el usuario-agente del analizador HTTP de la red y crea un target hostname a partir del requestUrl.
  • Asigna un espacio de nombres para permitir el enriquecimiento y el alias basados en activos.
CSV
(tipo de registro: MISP_IOC)
Extracción de campos arbitrarios en el objeto additional de UDM Extrae campos en UDM > Entidad > Objeto de UDM additional > par clave-valor Objeto additional de UDM
Syslog
(tipo de registro: POWERSHELL)
Cómo extraer la prioridad y la gravedad de Syslog Extrae los valores de Facility y Severity de Syslog en los campos UDM Security Result Priority y Severity. Basado en Grok
JSON con un encabezado de Syslog
(tipo de registro: WINDOWS_SYSMON)
Decoración basada en una declaración condicional
  • Agrega decoración (información contextual) al campo metadata.description en función de una declaración condicional y la comprensión de los tipos de datos dentro de los fragmentos de código.
  • Cuando se usa un filtro de extracción, se puede conservar el tipo de datos original.
  • Una sentencia condicional de Grok debe usar el tipo de datos original para evaluar el campo.
  • Basado en Grok
  • Instrucción condicional de Grok
  • Es posible que se conserve el tipo de datos original de un campo extraído.
  • Una sentencia condicional de Grok debe usar el tipo de datos original para evaluar el campo.
JSON con un encabezado de Syslog
(tipo de registro: WINDOWS_SYSMON)
Convertir tipos de datos
  • Convierte tipos de datos dentro de una extensión del analizador con la función convert.
  • Usa instrucciones on_error para controlar los errores de forma adecuada y evitar fallas en la extensión del analizador.
  • Basado en Grok
  • Convertir tipos de datos
  • Usa instrucciones on_error para proporcionar el manejo de errores.
JSON con un encabezado de Syslog
(tipo de registro: WINDOWS_SYSMON)
Nombres de variables temporales para facilitar la lectura Puedes usar nombres de variables temporales en fragmentos de código y, luego, cambiarles el nombre para que coincidan con el nombre final del objeto del evento del UDM de salida. Esto puede ayudar a mejorar la legibilidad general.
  • Basado en Grok
  • Usa nombres de variables temporales y, luego, cámbialos por los nombres finales de la UDM de salida.
JSON con un encabezado de Syslog
(tipo de registro: WINDOWS_SYSMON)
Campos repetidos Ten cuidado cuando trabajes con campos repetidos en fragmentos de código, por ejemplo, el campo security_result.
XML
(tipo de registro: WINDOWS_DEFENDER_AV)
Extracción de campos arbitrarios en el objeto additional
  • Extrae y almacena el valor de la versión de la plataforma, por ejemplo, para poder generar informes y buscar versiones de la plataforma desactualizadas.
  • En este ejemplo, no hay ningún campo de UDM estándar adecuado, por lo que se usa el objeto additional para almacenar la información como un par clave-valor personalizado.
El objeto additional se usa para almacenar la información como un par clave-valor personalizado.
XML
(tipo de registro: WINDOWS_DEFENDER_AV)
Extracción de campos arbitrarios en el nombre de host principal
  • Extrae el nombre de host de un FQDN.
  • El procesamiento condicional se usa para determinar si se debe reemplazar el campo principal.hostname.
  • La instrucción Grok usa una expresión regular (regex) para extraer el campo hostname. La expresión regular en sí usa un grupo de captura con nombre, lo que significa que todo lo que coincida dentro de los paréntesis se almacenará en el campo llamado hostname, que coincide con uno o más caracteres hasta que encuentra un punto. Solo se capturará el hostname dentro de un FQDN.
Declaración de Grok overwrite
  • Sin embargo, cuando se ejecuta la salida de UDM de la VERSIÓN PRELIMINAR, se muestra el siguiente error: "LOG_PARSING_CBN_ERROR: El campo hostname ya existe en los datos y no se puede reemplazar".
  • Dentro de una instrucción Grok, un grupo de captura con nombre no puede anular una variable existente, a menos que se especifique explícitamente con la instrucción overwrite. En esta situación, podríamos usar un nombre de variable diferente para el grupo de captura con nombre en la instrucción Grok o, como se muestra en este ejemplo, usar la instrucción de anulación para anular de forma explícita la variable de nombre de host existente.
  • Basado en Grok
  • El procesamiento condicional se usa para determinar si se debe reemplazar un campo.
  • Sentencia Grok que usa expresiones regulares (regex).
  • Declaración de Grok overwrite
JSON, CSV, XML, Syslog y KV Cómo quitar las asignaciones existentes Quita las asignaciones existentes quitando los valores de los campos de UDM.

Ejemplos de JSON

En los siguientes ejemplos, se muestra cómo crear una extensión de analizador en la que la fuente de registro está en formato JSON.

Sin código: Extraer campos

Ejemplo de atributos:

  • Formato de la fuente de registro: JSON
  • Enfoque de asignación de datos: sin código
  • Tipo de registro: GCP_IDS
  • Propósito de la extensión del analizador: Extraer campos.
  • Descripción:

    No se extraen varios campos relacionados con la red. Como esta muestra de registro es un registro estructurado en formato JSON, podemos usar el enfoque de sin código (Map data fields) para crear la extensión del analizador.

    Los campos originales que queremos extraer son los siguientes:

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

    Esta es la entrada de registro sin procesar de muestra:

    {
    "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"
    }
    

    En el ejemplo, se usa el enfoque sin código para crear una extensión del analizador con la siguiente asignación de campos de datos:

    Precondition Path Precondition Operator Precondition Value Ruta de acceso a los datos sin procesar Campo de destino*
    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

    Si ejecutas la extensión del analizador correctamente, se agregarán los tres campos extraídos al objeto 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"
    

Sin código: Extrae campos con el valor de la condición previa

Ejemplo de atributos:

  • Formato de la fuente de registro: JSON
  • Enfoque de asignación de datos: sin código
  • Tipo de registro: WORKSPACE_ALERTS
  • Propósito de la extensión del analizador: Extraer campos con valor de condición previa.
  • Descripción:

    El analizador original no extrae el email address del usuario principal afectado por una alerta de DLP (prevención de pérdida de datos).

    En este ejemplo, se usa una extensión del analizador sin código para extraer el email address y normalizarlo en un campo del UDM repetido, con una condición previa.

    Cuando trabajes con campos repetidos en una extensión del analizador sin código, debes indicar si deseas hacer lo siguiente:

    • replace (anula todos los valores de los campos repetidos en el objeto UDM existente)
    • append (anexa los valores extraídos a los campos repetidos).

    Para obtener más detalles, consulta la sección Campos repetidos.

    En este ejemplo, se reemplazan todas las direcciones de correo electrónico existentes en el campo principal.user.email_address normalizado.

    Las condiciones previas te permiten realizar verificaciones condicionales antes de realizar una operación de extracción. En la mayoría de los casos, el campo de condición previa será el mismo que el campo de datos sin procesar que deseas extraer, con un operador de condición previa de not Null, por ejemplo, foo != "".

    Sin embargo, a veces, como en nuestro ejemplo, el valor del campo de datos sin procesar que deseas extraer no está presente en todas las entradas de registro. En ese caso, puedes usar otro campo de precondición para filtrar la operación de extracción. En nuestro ejemplo, el campo triggeringUserEmail sin procesar que deseas extraer solo está presente en los registros en los que type = Data Loss Prevention.

    Estos son los valores de ejemplo que se deben ingresar en los campos de extensión del analizador sin código:

    Precondition Path Precondition Operator Precondition Value Ruta de acceso a los datos sin procesar Campo de destino*
    type IGUAL A Prevención de pérdida de datos data.ruleViolationInfo.triggeringUserEmail udm.principal.user.email_addresses

    En el siguiente ejemplo, se muestran los campos de extensión del analizador sin código completados con los valores de ejemplo:

    image2

    Si ejecutas la extensión del analizador correctamente, se agregará email_address al objeto 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"
    

Fragmento de código: cómo agregar un usuario-agente HTTP

Ejemplo de atributos:

  • Formato de la fuente de registro: JSON
  • Enfoque de asignación de datos: Fragmento de código
  • Tipo de registro: GCP_IDS
  • Propósito de la extensión del analizador: Agregar el usuario-agente HTTP.
  • Descripción:

    Este es un ejemplo de un tipo de objeto UDM no estándar que no es compatible con el enfoque sin código y, por lo tanto, requiere el uso de un fragmento de código. El analizador predeterminado no extrae el análisis de Network HTTP Parser User Agent. Además, para mantener la coherencia, se hizo lo siguiente:

    1. Se creará un Target Hostname a partir del requestUrl.
    2. Se asignará un Namespace para garantizar que se realice el alias y el enriquecimiento basados en activos.
    # 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"
                }
            }
        }
    }
    

Ejemplo de CSV

En el siguiente ejemplo, se muestra cómo crear una extensión de analizador en la que la fuente de registro está en formato CSV.

Fragmento de código: Extracción de campos arbitrarios en el objeto additional

Ejemplo de atributos:

  • Formato de la fuente de registro: CSV
  • Enfoque de asignación de datos: Fragmento de código
  • Tipo de registro: MISP_IOC
  • Propósito de la extensión del analizador: Extracción de campos arbitrarios en el objeto additional.
  • Descripción:

    En este ejemplo, se usa la integración del contexto de la entidad de UDM de MISP_IOC. El objeto UDM de par clave-valor additional se usará para capturar información contextual que no extrae el analizador predeterminado y para agregar campos específicos de cada organización. Por ejemplo, una URL que dirija a su instancia específica de MISP.

    Esta es la fuente de registros basada en CSV para este ejemplo:

    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

    imagen

    # 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"
            }
        }
    }
    

    Si ejecutas la extensión del analizador correctamente, se agregarán los campos personalizados del CSV al objeto 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"
    

Ejemplos de Grok

En los siguientes ejemplos, se muestra cómo crear extensiones de analizador basadas en Grok.

Fragmento de código (y Grok): Extracción de la prioridad y la gravedad

Ejemplo de atributos:

  • Formato de la fuente de registro: Syslog
  • Enfoque de asignación de datos: fragmento de código con Grok
  • Tipo de registro: POWERSHELL
  • Propósito de la extensión del analizador: Extracción de prioridad y gravedad.
  • Descripción:

    En este ejemplo, se crea una extensión del analizador basada en Grok para extraer los valores de Syslog Facility and Severity en los campos Priority y Severity del resultado de seguridad del 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"
                }
            }
        }
    }
    

    Si ves los resultados de la extensión del analizador, se mostrará el formato legible.

    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"
    

Fragmento de código (y Grok): Decoración de eventos, nombres de variables temporales y conversión de tipos de datos

Ejemplo de atributos:

  • Formato de la fuente de registro: JSON con un encabezado Syslog
  • Enfoque de asignación de datos: fragmento de código con Grok
  • Tipo de registro: WINDOWS_SYSMON
  • Propósito de la extensión del analizador: Decoración de eventos, nombres de variables temporales y tipos de datos.
  • Descripción:

    En este ejemplo, se muestra cómo realizar las siguientes acciones cuando se crea una extensión del analizador:

    Decoración basada en una instrucción condicional

    En este ejemplo, se agregan explicaciones (información contextual) sobre el significado de cada tipo de evento en WINDOWS_SYSMON. Utiliza una instrucción condicional para verificar el EventID y, luego, agrega un Description, por ejemplo, EventID 1 es un evento Process Creation.

    Cuando se usa un filtro de extracción, por ejemplo, JSON, es posible que se conserve el tipo de datos original.

    En el siguiente ejemplo, el valor EventID se extrae como un número entero de forma predeterminada. La sentencia condicional evalúa el valor de EventID como un número entero, no como una cadena.

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

    Conversión de tipo de datos

    Puedes convertir tipos de datos dentro de una extensión del analizador con la función convert.

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

    Nombres de variables temporales para mejorar la legibilidad

    Puedes usar nombres de variables temporales en fragmentos de código y, luego, cambiarles el nombre para que coincidan con el nombre final del objeto del evento del UDM de salida. Esto puede ayudar a mejorar la legibilidad general.

    En el siguiente ejemplo, se cambia el nombre de la variable description a event.idm.read_only_udm.metadata.description:

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

    Campos repetidos

    La extensión del analizador completo es la siguiente:

    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"
          }
        }
      }
    }
    }
    

    Si ejecutas la extensión del analizador correctamente, se agregará la decoración al campo 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"
    

Ejemplos de XML

En los siguientes ejemplos, se muestra cómo crear una extensión de analizador en la que la fuente de registro está en formato XML.

Fragmento de código: Extracción de campos arbitrarios en el objeto additional

Ejemplo de atributos:

  • Formato de la fuente de registro: XML
  • Enfoque de asignación de datos: Fragmento de código
  • Tipo de registro: WINDOWS_DEFENDER_AV
  • Propósito de la extensión del analizador: Extracción de campos arbitrarios en el objeto additional
  • Descripción:

    El objetivo de este ejemplo es extraer y almacenar el valor de Platform Version, por ejemplo, para poder generar informes sobre outdated platform versions y buscarlo.

    Después de revisar el documento Campos importantes del UDM, no se identificó ningún campo estándar del UDM adecuado. Por lo tanto, en este ejemplo, se usará el objeto additional para almacenar esta información como un par clave-valor personalizado.

    # 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"
                }
            }
        }
    }
    

    Si ejecutas la opción PREVIEW UDM OUTPUT, verás que el nuevo campo se agregó correctamente.

    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"
    

Fragmento de código (y Grok): Extracción de campos arbitrarios en el nombre de host principal

Ejemplo de atributos:

  • Formato de la fuente de registro: XML
  • Enfoque de asignación de datos: fragmento de código con Grok
  • Tipo de registro: WINDOWS_DEFENDER_AV
  • Propósito de la extensión del analizador: Extracción de campos arbitrarios en el nombre de host principal
  • Descripción:

    El objetivo de este ejemplo es extraer el Hostname de un FQDN y reemplazar el campo principal.hostname.

    En este ejemplo, se verifica si el campo Computer name del registro sin procesar incluye un FQDN. Si es así, extrae solo la parte Hostname y reemplaza el campo Principal Hostname del UDM.

    Después de revisar el analizador y el documento Campos importantes de UDM, queda claro que se debe usar el campo principal.hostname.

    # 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"
                }
            }
        }
    }
    

    Esta extensión del analizador usa una instrucción Grok para ejecutar una expresión regular (regex) y extraer el campo hostname. La expresión regular en sí usa un grupo de captura con nombre, lo que significa que todo lo que coincida dentro de los paréntesis se almacenará en el campo llamado hostname, que coincide con uno o más caracteres hasta que encuentra un punto. Esto solo capturará el hostname dentro de un FQDN.

    Sin embargo, cuando se ejecuta la salida de UDM de la vista previa, se devuelve un error. ¿Por qué sucede esto?

    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"
    

    Declaración de Grok overwrite

    En una instrucción Grok, un grupo de captura con nombre no puede anular una variable existente, a menos que se especifique explícitamente con la instrucción overwrite. En esta situación, podríamos usar un nombre de variable diferente para el grupo de captura con nombre en la instrucción Grok o, como se muestra en el siguiente ejemplo de fragmento de código, usar la instrucción overwrite para anular de forma explícita la variable hostname existente.

    # 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"
          }
        }
      }
    }
    

    Si vuelves a ejecutar PREVIEW UDM OUTPUT, se mostrará que se agregó el nuevo campo después de extraer hostname de 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"
    

Ejemplos de JSON, CSV, XML, Syslog y KV

En los siguientes ejemplos, se muestra cómo crear una extensión de analizador en la que la fuente de registro está en formato JSON, CSV, XML, Syslog o KV.

Fragmento de código: Quita las asignaciones existentes

Ejemplo de atributos:

  • Formato de la fuente de registros: JSON, CSV, Syslog, XML y KV
  • Enfoque de asignación de datos: Fragmento de código
  • Propósito de la extensión del analizador: Quitar valores para los campos de UDM
  • Descripción:

    El objetivo de estos ejemplos es quitar las asignaciones existentes quitando los valores de los campos del UDM.

    En el siguiente ejemplo, se quita el valor del campo string:

    filter {
       mutate{
         replace => {
             "event.idm.read_only_udm.metadata.vendor_name" => ""
         }
       }
       mutate {
         merge => {
           "@output" => "event"
         }
      }
    }
    

    En el siguiente ejemplo, se quita el valor del campo integer:

    filter {
       mutate {
         replace => {
           "principal_port" => "0"
         }
     }
       mutate {
         convert => {
           "principal_port" => "integer"
         }
     }
       mutate {
         rename => {
           "principal_port" => "event.idm.read_only_udm.principal.port"
         }
     }
       mutate {
         merge => {
           "@output" => "event"
         }
      }
    }
    

    En el siguiente ejemplo, se quita el valor del campo float:

    filter {
       mutate {
           replace => {
             "security_result_object.risk_score" => "0.0" 
           }
           convert => {
             "security_result_object.risk_score" => "float"
           }
           on_error => "default_risk_score_conversion_failed"
         }
       mutate {
           merge => {
               "event.idm.read_only_udm.security_result" => "security_result_object"
           }
           on_error => "security_result_merge_failed"
         }
       mutate {
         merge => {
           "@output" => "event"
         }
     }
    }
    

    En el siguiente ejemplo, se quita el valor del campo boolean:

    filter {
       mutate{
           replace => {
               "tls_established" => "false"
           }
      }
       mutate {
         convert => {
           "tls_established" => "boolean"
         }
       }
       mutate {
         rename => {
           "tls_established" => "event.idm.read_only_udm.network.tls.established"
         }
       }
       mutate {
         merge => {
           "@output" => "event"
         }
      }
    }
    

    En el siguiente ejemplo, se quita el valor del campo extension:

    filter {
       mutate {
           replace => {
              "event.idm.read_only_udm.extensions.auth.auth_details" => ""
           }
           on_error => "logon_type_not_set"
       }
       mutate {
         merge => {
           "@output" => "event"
         }
      }
    }
    

    ¿Necesitas más ayuda? Obtén respuestas de miembros de la comunidad y profesionales de Google SecOps.