Recopila registros de las Alertas de Dataminr

Compatible con:

En este documento, se explica cómo transferir registros de Dataminr Alerts a Google Security Operations con Google Cloud Storage V2, una función de Cloud Run y Cloud Scheduler.

Dataminr Pulse ofrece inteligencia en tiempo real potenciada por IA a partir de más de 500,000 fuentes de datos públicos globales, incluidas la Web profunda y la Web oscura. La plataforma proporciona advertencias tempranas sobre las amenazas cibernéticas emergentes, las vulnerabilidades, los ataques de ransomware, las violaciones de la seguridad de los datos y los riesgos digitales que afectan a tu organización y a terceros. La API de Dataminr Pulse usa la autenticación de credenciales de cliente de OAuth 2.0 y la paginación basada en cursores para recuperar alertas.

Antes de comenzar

Asegúrate de cumplir con los siguientes requisitos previos:

  • Una instancia de Google SecOps
  • Un proyecto de Google Cloud con las siguientes APIs habilitadas:
    • API de Cloud Storage
    • API de funciones de Cloud Run
    • API de Cloud Scheduler
    • API de Cloud Pub/Sub
  • Permisos para crear y administrar buckets de GCS, funciones de Cloud Run, temas de Pub/Sub y trabajos de Cloud Scheduler
  • Permisos para administrar políticas de IAM en buckets de GCS
  • Una cuenta activa de Dataminr Pulse con acceso a la API habilitado
  • Credenciales de la API de Dataminr Pulse (ID de cliente y secreto del cliente)
  • Al menos una lista de alertas de Dataminr Pulse configurada en tu cuenta de Dataminr

Crear un bucket de Google Cloud Storage

  1. Ve a Google Cloud Console.
  2. Selecciona tu proyecto o crea uno nuevo.
  3. En el menú de navegación, ve a Cloud Storage > Buckets.
  4. Haz clic en Crear bucket.
  5. Proporciona los siguientes detalles de configuración:

    Configuración Valor
    Asigna un nombre a tu bucket Ingresa un nombre global único (por ejemplo, dataminr-alert-logs).
    Tipo de ubicación Elige según tus necesidades (región, birregional, multirregional)
    Ubicación Selecciona la ubicación (por ejemplo, us-central1).
    Clase de almacenamiento Estándar (recomendado para los registros a los que se accede con frecuencia)
    Control de acceso Uniforme (recomendado)
    Herramientas de protección Opcional: Habilita el control de versiones de objetos o la política de retención
  6. Haz clic en Crear.

Recopila las credenciales de Dataminr

Para permitir que la función de Cloud Run recupere datos de alertas, necesitas credenciales de API con autenticación de credenciales de cliente de OAuth 2.0 de tu representante de cuenta de Dataminr.

Obtén credenciales de API

  1. Comunícate con tu representante de cuenta o equipo de asistencia al cliente de Dataminr para solicitar acceso a la API.
  2. Proporciona la siguiente información:
    • Nombre de tu organización
    • Caso de uso: Integración con el SIEM de Google Chronicle
    • Acceso requerido: API de Dataminr Pulse para Cyber Risk
  3. Dataminr aprovisiona credenciales de API y te proporciona lo siguiente:

    • ID de cliente: Es el identificador único de tu cliente de OAuth 2.0.
    • Secreto del cliente: Es la clave secreta de tu cliente de OAuth 2.0.

Verifica las credenciales de la API

  • Para verificar que tus credenciales funcionen, ejecuta el siguiente comando:

    curl -X POST https://gateway.dataminr.com/auth/2/token \
      -H "Content-Type: application/x-www-form-urlencoded" \
      -d "client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&grant_type=api_key"
    

    Una respuesta correcta devuelve un objeto JSON que contiene un campo access_token:

    {
      "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI...",
      "token_type": "Bearer",
      "expire": 3600
    }
    

Recopila IDs de listas de alertas

  1. Accede a la aplicación web de Dataminr Pulse en https://app.dataminr.com.
  2. Navega a tus listas de alertas (listas de seguimiento) configuradas.
  3. Anota los IDs de las listas de alertas que deseas transferir a Google SecOps.

Crea una cuenta de servicio para la función de Cloud Run

  1. En la consola de Google Cloud, ve a IAM y administración > Cuentas de servicio.
  2. Haz clic en Crear cuenta de servicio.
  3. Proporciona los siguientes detalles de configuración:
    • Nombre de la cuenta de servicio: Ingresa dataminr-alert-collector.
    • Descripción de la cuenta de servicio: Ingresa Service account for Dataminr Alerts Cloud Run function to write alert data to GCS.
  4. Haz clic en Crear y continuar.
  5. En la sección Otorga a esta cuenta de servicio acceso al proyecto, agrega los siguientes roles:
    1. Haz clic en Seleccionar un rol, busca Administrador de objetos de Storage y selecciónalo.
    2. Haz clic en Agregar otro rol, busca Invocador de Cloud Run y selecciónalo.
  6. Haz clic en Continuar.
  7. Haz clic en Listo.

Otorga permisos de IAM en el bucket de GCS

  1. Ve a Cloud Storage > Buckets.
  2. Haz clic en el nombre de tu bucket (por ejemplo, dataminr-alert-logs).
  3. Ve a la pestaña Permisos.
  4. Haz clic en Otorgar acceso.
  5. Proporciona los siguientes detalles de configuración:
    • Agregar principales: Ingresa el correo electrónico de la cuenta de servicio (por ejemplo, dataminr-alert-collector@PROJECT_ID.iam.gserviceaccount.com).
    • Asignar roles: Selecciona Administrador de objetos de Storage.
  6. Haz clic en Guardar.

Crea un tema de Pub/Sub

El tema de Pub/Sub activa la función de Cloud Run cuando Cloud Scheduler publica un mensaje.

  1. En la consola de Google Cloud, ve a Pub/Sub > Temas.
  2. Haz clic en Crear tema.
  3. Proporciona los siguientes detalles de configuración:
    • ID del tema: Ingresa dataminr-alert-trigger.
    • Agregar una suscripción predeterminada: Déjala marcada
  4. Haz clic en Crear.

Crea la función de Cloud Run

  1. En la consola de Google Cloud, ve a Cloud Run functions.
  2. Haz clic en Crear función.
  3. Proporciona los siguientes detalles de configuración:

    Configuración Valor
    Entorno 2ª gen.
    Nombre de la función dataminr-alert-collector
    Región Selecciona la misma región que tu bucket de GCS.
    Tipo de activador Cloud Pub/Sub
    Tema de Pub/Sub dataminr-alert-trigger
    Memoria asignada 512 MiB
    Tiempo de espera 540 segundos
    Cuenta de servicio del entorno de ejecución dataminr-alert-collector
  4. Haz clic en Siguiente.

  5. Establece Entorno de ejecución en Python 3.12.

  6. Establece el Punto de entrada como main.

  7. En el archivo requirements.txt, agrega las siguientes dependencias:

    functions-framework==3.*
    google-cloud-storage==2.*
    requests==2.*
    
  8. En el archivo main.py, pega el siguiente código:

    import functions_framework
    import json
    import os
    import logging
    import time
    from datetime import datetime, timedelta, timezone
    from google.cloud import storage
    import requests
    
    logger = logging.getLogger(__name__)
    logger.setLevel(logging.INFO)
    
    storage_client = storage.Client()
    
    TOKEN_URL = "https://gateway.dataminr.com/auth/2/token"
    ALERTS_URL = "https://gateway.dataminr.com/api/3/alerts"
    
    def _get_access_token(client_id: str, client_secret: str) -> str:
        """Obtain an OAuth 2.0 access token from Dataminr."""
        payload = {
            "client_id": client_id,
            "client_secret": client_secret,
            "grant_type": "api_key",
        }
        headers = {"Content-Type": "application/x-www-form-urlencoded"}
        resp = requests.post(TOKEN_URL, data=payload, headers=headers, timeout=30)
        resp.raise_for_status()
        token_data = resp.json()
        access_token = token_data.get("access_token")
        if not access_token:
            raise ValueError("No access_token in token response")
        logger.info("Successfully obtained Dataminr access token.")
        return access_token
    
    def _load_state(bucket_name: str, state_key: str) -> dict:
        """Load the last cursor (alertId) from GCS."""
        try:
            bucket = storage_client.bucket(bucket_name)
            blob = bucket.blob(state_key)
            if blob.exists():
                data = json.loads(blob.download_as_text())
                logger.info(f"Loaded state: {data}")
                return data
        except Exception as e:
            logger.warning(f"State read error: {e}")
        logger.info("No previous state found.")
        return {}
    
    def _save_state(bucket_name: str, state_key: str, state: dict) -> None:
        """Save the cursor state to GCS."""
        bucket = storage_client.bucket(bucket_name)
        blob = bucket.blob(state_key)
        blob.upload_from_string(
            json.dumps(state), content_type="application/json"
        )
        logger.info(f"Saved state: {state}")
    
    def _fetch_alerts(
        access_token: str,
        alert_lists: str,
        page_size: int,
        cursor: str = None,
    ) -> tuple:
        """Fetch a page of alerts from the Dataminr Pulse API."""
        headers = {
            "Authorization": f"Bearer {access_token}",
            "Accept": "application/json",
        }
        params = {
            "lists": alert_lists,
            "num": page_size,
        }
        if cursor:
            params["from"] = cursor
    
        resp = requests.get(
            ALERTS_URL, headers=headers, params=params, timeout=60
        )
    
        # Handle rate limiting via response headers
        rate_remaining = resp.headers.get("x-ratelimit-remaining")
        rate_reset = resp.headers.get("x-ratelimit-reset")
    
        if resp.status_code == 429:
            reset_time = int(rate_reset) if rate_reset else 60
            wait_seconds = max(reset_time - int(time.time()), 1)
            logger.warning(
                f"Rate limited. Waiting {wait_seconds}s before retry."
            )
            time.sleep(wait_seconds)
            resp = requests.get(
                ALERTS_URL, headers=headers, params=params, timeout=60
            )
    
        resp.raise_for_status()
    
        if rate_remaining is not None:
            logger.info(
                f"Rate limit remaining: {rate_remaining}, reset: {rate_reset}"
            )
    
        data = resp.json()
        alerts = data if isinstance(data, list) else data.get("data", [])
        return alerts
    
    @functions_framework.cloud_event
    def main(cloud_event):
        """Cloud Run function entry point triggered by Pub/Sub."""
        bucket_name = os.environ["GCS_BUCKET"]
        prefix = os.environ.get("GCS_PREFIX", "dataminr_alerts")
        state_key = os.environ.get("STATE_KEY", "dataminr_state/cursor.json")
        client_id = os.environ["CLIENT_ID"]
        client_secret = os.environ["CLIENT_SECRET"]
        alert_lists = os.environ["ALERT_LISTS"]
        max_records = int(os.environ.get("MAX_RECORDS", "1000"))
        page_size = min(int(os.environ.get("PAGE_SIZE", "40")), 40)
        lookback_hours = int(os.environ.get("LOOKBACK_HOURS", "24"))
    
        try:
            access_token = _get_access_token(client_id, client_secret)
            state = _load_state(bucket_name, state_key)
            cursor = state.get("last_cursor")
            is_first_run = cursor is None
    
            all_alerts = []
            total_fetched = 0
            pages_fetched = 0
    
            while total_fetched < max_records:
                logger.info(
                    f"Fetching page {pages_fetched + 1} (cursor: {cursor})..."
                )
                alerts = _fetch_alerts(
                    access_token, alert_lists, page_size, cursor=cursor
                )
    
                if not alerts:
                    logger.info("No more alerts returned. Stopping pagination.")
                    break
    
                # Filter by lookback window on first run (no prior cursor)
                if is_first_run:
                    cutoff_ms = int(
                        (
                            datetime.now(timezone.utc)
                            - timedelta(hours=lookback_hours)
                        ).timestamp()
                        * 1000
                    )
                    alerts = [
                        a for a in alerts if a.get("eventTime", 0) >= cutoff_ms
                    ]
    
                all_alerts.extend(alerts)
                total_fetched += len(alerts)
                pages_fetched += 1
    
                # Update cursor to the last alertId in this page
                last_alert = alerts[-1] if alerts else None
                if last_alert and "alertId" in last_alert:
                    cursor = last_alert["alertId"]
                else:
                    break
    
                # Stop if we received fewer alerts than requested
                if len(alerts) < page_size:
                    logger.info("Received partial page. Stopping pagination.")
                    break
    
            logger.info(
                f"Collected {len(all_alerts)} alerts across {pages_fetched} pages."
            )
    
            if not all_alerts:
                logger.info("No new alerts to write.")
                return "No new alerts", 200
    
            # Write alerts as NDJSON to GCS
            now_str = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%SZ")
            blob_path = f"{prefix}/{now_str}.ndjson"
            ndjson_body = "\n".join(
                json.dumps(alert, separators=(",", ":")) for alert in all_alerts
            )
    
            bucket = storage_client.bucket(bucket_name)
            blob = bucket.blob(blob_path)
            blob.upload_from_string(
                ndjson_body, content_type="application/x-ndjson"
            )
    
            _save_state(
                bucket_name,
                state_key,
                {
                    "last_cursor": cursor,
                    "last_run": datetime.now(timezone.utc).isoformat(),
                },
            )
    
            msg = (
                f"Wrote {len(all_alerts)} alerts to "
                f"gs://{bucket_name}/{blob_path}"
            )
            logger.info(msg)
            return msg, 200
    
        except Exception as e:
            logger.error(f"Error collecting Dataminr alerts: {e}")
            raise
    
  9. Haz clic en Implementar.

  10. Espera a que se implemente la función. El estado cambia a una marca de verificación verde cuando se completa la implementación.

Configure las variables de entorno

  1. Después de implementar la función, ve a Cloud Run Functions > dataminr-alert-collector.
  2. Haz clic en Editar e implementar una nueva revisión.
  3. Haz clic en la pestaña Variables y secretos (o expande Configuración del entorno de ejecución, la compilación, las conexiones y la seguridad para la 1ª gen.).
  4. Agrega las siguientes variables de entorno:

    Clave Valor de ejemplo
    GCS_BUCKET dataminr-alert-logs
    GCS_PREFIX dataminr_alerts
    STATE_KEY dataminr_state/cursor.json
    CLIENT_ID Tu ID de cliente de OAuth 2.0 de Dataminr
    CLIENT_SECRET Tu secreto del cliente de OAuth 2.0 de Dataminr
    ALERT_LISTS IDs de la lista de alertas de Dataminr separados por comas
    MAX_RECORDS 1000
    PAGE_SIZE 40
    LOOKBACK_HOURS 24
  5. Haz clic en Implementar.

Crea un trabajo de Cloud Scheduler

Cloud Scheduler publica un mensaje en el tema de Pub/Sub según una programación, lo que activa la función de Cloud Run para sondear Dataminr Pulse en busca de alertas nuevas.

  1. En la consola de Google Cloud, ve a Cloud Scheduler.
  2. Haz clic en Crear trabajo.
  3. Proporciona los siguientes detalles de configuración:

    Configuración Valor
    Nombre dataminr-alert-poll
    Región Selecciona la misma región que tu función.
    Frecuencia */5 * * * * (cada 5 minutos)
    Zona horaria Selecciona tu zona horaria (por ejemplo, UTC).
  4. Haz clic en Continuar.

  5. En la sección Configura la ejecución, haz lo siguiente:

    • Tipo de destino: Selecciona Pub/Sub.
    • Tema: Selecciona dataminr-alert-trigger.
    • Cuerpo del mensaje: Ingresa {"poll": true}.
  6. Haz clic en Crear.

Verifica la función de Cloud Run

  1. En Cloud Scheduler, busca el trabajo dataminr-alert-poll.
  2. Haz clic en Forzar ejecución para activar una ejecución inmediata.
  3. Ve a Cloud Run Functions > dataminr-alert-collector > Registros.
  4. Verifica que la función se haya ejecutado correctamente. Para ello, busca entradas de registro como las siguientes:

    Successfully obtained Dataminr access token.
    Fetching page 1 (cursor: None)...
    Collected 35 alerts across 1 pages.
    Wrote 35 alerts to gs://dataminr-alert-logs/dataminr_alerts/20250115T103000Z.ndjson
    
  5. Ve a Cloud Storage > Buckets > dataminr-alert-logs.

  6. Navega al prefijo dataminr_alerts/.

  7. Verifica que se estén creando archivos NDJSON con datos de alertas de Dataminr.

Recupera la cuenta de servicio de Google SecOps y configura el feed

Las Operaciones de seguridad de Google usan una cuenta de servicio única para leer datos de tu bucket de GCS. Debes otorgar acceso a tu bucket a esta cuenta de servicio.

Obtén el correo electrónico de la cuenta de servicio

  1. Ve a Configuración de SIEM > Feeds.
  2. Haz clic en Agregar feed nuevo.
  3. Haz clic en Configura un feed único.
  4. En el campo Nombre del feed, ingresa un nombre para el feed (por ejemplo, Dataminr Alerts).
  5. Selecciona Google Cloud Storage V2 como el Tipo de fuente.
  6. Selecciona Alertas de Dataminr como el Tipo de registro.
  7. Haz clic en Obtener cuenta de servicio.
  8. Se mostrará un correo electrónico único de la cuenta de servicio, por ejemplo:

    chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.com
    
  9. Copia esta dirección de correo electrónico para usarla en la siguiente sección.

  10. Haz clic en Siguiente.

  11. Especifica valores para los siguientes parámetros de entrada:

    • URL del bucket de almacenamiento: Ingresa el URI del bucket de GCS con la ruta de acceso del prefijo:

      gs://dataminr-alert-logs/dataminr_alerts/
      
    • Opción de borrado de la fuente: Selecciona la opción de borrado según tu preferencia:

      • Nunca: Nunca borra ningún archivo después de las transferencias (se recomienda para las pruebas).
      • Borrar archivos transferidos: Borra los archivos después de una transferencia exitosa.
      • Borrar los archivos transferidos y los directorios vacíos: Borra los archivos y los directorios vacíos después de la transferencia exitosa.

    • Antigüedad máxima del archivo: Incluye los archivos modificados en la cantidad de días más reciente (el valor predeterminado es 180 días).

    • Espacio de nombres del recurso: espacio de nombres del recurso.

    • Etiquetas de transferencia: Es la etiqueta que se aplicará a los eventos de este feed (por ejemplo, DATAMINR_ALERT).

  12. Haz clic en Siguiente.

  13. Revisa la nueva configuración del feed en la pantalla Finalizar y, luego, haz clic en Enviar.

Otorga permisos de IAM a la cuenta de servicio de Google SecOps

La cuenta de servicio de Google SecOps necesita el rol de visualizador de objetos de almacenamiento en tu bucket de GCS.

  1. Ve a Cloud Storage > Buckets.
  2. Haz clic en el nombre de tu bucket (por ejemplo, dataminr-alert-logs).
  3. Ve a la pestaña Permisos.
  4. Haz clic en Otorgar acceso.
  5. Proporciona los siguientes detalles de configuración:
    • Agregar principales: Pega el correo electrónico de la cuenta de servicio de Google SecOps.
    • Asignar roles: Selecciona Visualizador de objetos de Storage.
  6. Haz clic en Guardar.

Tabla de asignación de UDM

Campo de registro Asignación de UDM Lógica
alertId metadata.product_log_id Valor copiado directamente
alertType.color about.labels.alertType_color Valor copiado directamente
alertType.id about.labels.alertType_id Valor copiado directamente
alertType.name about.labels.alertType_name Valor copiado directamente
availableRelatedAlerts about.labels.availableRelatedAlerts Se convirtió en cadena
subtítulo metadata.description Valor copiado directamente
cat.name security_result.category_details Valor copiado directamente
cat.id security_result.detection_fields.categories_id Valor copiado directamente
cat.idStr security_result.detection_fields.categories_idStr Valor copiado directamente
cat.path security_result.detection_fields.categories_path Valor copiado directamente
cat.requested security_result.detection_fields.categories_requested Valor copiado directamente
cat.retired security_result.detection_fields.categories_retired Se convirtió en cadena
cat.topicType about.labels.categories_topicType Valor copiado directamente
cat.name security_result.category Se establece en POLICY_VIOLATION si cat.name == "Cybersecurity - Policy"; NETWORK_MALICIOUS si está en ["Cybersecurity - Threats & Vulnerabilities", "Cybersecurity - Crime & Malicious Activity", "Threats & Precautions", "Threats"]; NETWORK_SUSPICIOUS si =~ "Cybersecurity"; MAIL_PHISHING si =~ "Email and Web Servers"; DATA_EXFILTRATION si =~ "Data Exposure and Breaches"; POLICY_VIOLATION si =~ "Government, Policy, & Political Affairs"; PHISHING si =~ "(Malware
comp.dm_bucket.name security_result.about.resource.attribute.labels.dmbucket%{bucket.id} Valor copiado directamente
comp.dm_sector.name security_result.about.resource.attribute.labels.dmsector%{sector.id} Valor copiado directamente
comp.id security_result.about.resource.attribute.labels.companies_id Valor copiado directamente
comp.idStr security_result.about.resource.attribute.labels.companies_idStr Valor copiado directamente
comp.locations.city security_result.about.location.city Valor de loc.city si loc_index == 0
comp.locations.country, comp.locations.state.symbol security_result.about.location.country_or_region Se concatena como %{loc.country} - %{loc.state.symbol} si loc_index == 0 y ambos no están vacíos
comp.locations.postalCode security_result.about.resource.attribute.labels.locations_postalCode El valor se copia directamente si loc_index == 0 y no está vacío.
comp.locations.state.name security_result.about.location.state El valor se copia directamente si loc_index == 0.
comp.locations.city about.labels.loc_%{loc_index}_city El valor se copia directamente si loc_index != 0 y no está vacío.
comp.locations.country, comp.locations.state.symbol about.labels.loc_%{loc_index}_country_or_region Se concatena como %{loc.country} - %{loc.state.symbol} si loc_index != 0 y ambos no están vacíos
comp.locations.postalCode securityresult.about.resource.attribute.labels.locations%{loc_index}_postalCode El valor se copia directamente si loc_index != 0 y no está vacío.
comp.locations.state.name about.labels.loc_%{loc_index}_state_name El valor se copia directamente si loc_index != 0 y no está vacío.
comp.name security_result.about.resource.name Valor copiado directamente
comp.requested security_result.about.resource.attribute.labels.companies_requested Valor copiado directamente
comp.retired security_result.about.resource.attribute.labels.companies_retired Se convirtió en cadena
comp.ticker security_result.about.resource.attribute.labels.companies_ticker Valor copiado directamente
comp.topicType security_result.about.resource.attribute.labels.companies_topicType Valor copiado directamente
eventLocation.coordinates.0 principal.location.region_coordinates.latitude Valor copiado directamente
eventLocation.coordinates.1 principal.location.region_coordinates.longitude Valor copiado directamente
eventLocation.name principal.location.name Valor copiado directamente
eventLocation.places principal.labels.location_places Se unió desde un array con un separador de comas
eventLocation.probability principal.labels.eventLocation_probability Se convirtió en cadena
eventLocation.radius principal.labels.eventLocation_radius Se convirtió en cadena
eventMapLargeURL principal.labels.eventMapLargeURL Valor copiado directamente
eventMapSmallURL principal.labels.eventMapSmallURL Valor copiado directamente
eventTime @timestamp Se convirtió de ms de época a marca de tiempo
eventVolume about.labels.eventVolume Se convirtió en cadena
expandAlertURL metadata.url_back_to_product Valor copiado directamente
expandMapURL principal.labels.expandMapURL Valor copiado directamente
headerColor about.labels.headerColor Valor copiado directamente
headerLabel about.labels.headerLabel Valor copiado directamente
metadata.cyber.addresses.ip principal.ip Se extrae con un patrón de grok si index == 0
metadata.cyber.addresses.port principal.port El valor se copia directamente si index == 0 y se convierte en un número entero.
metadata.cyber.addresses.port principal.labels.addresses_%{index}_port El valor se copia directamente si el índice no es igual a 0.
metadata.cyber.addresses.version principal.labels.metadata_cyberaddresses%{index}_version Valor copiado directamente
metadata.cyber.asns network.asn El valor se copia directamente si el índice es igual a 0.
metadata.cyber.asns about.labels.metadatacyber%{index}_asn El valor se copia directamente si el índice no es igual a 0.
metadata.cyber.hashValues.value security_result.about.file.sha1 Valor copiado directamente si type == SHA1, en minúsculas
metadata.cyber.hashValues.value security_result.about.file.sha256 El valor se copia directamente si type == SHA256, en minúsculas.
metadata.cyber.malwares security_result.associations.name Valor copiado directamente
metadata.cyber.malwares security_result.associations.type Se estableció como MALWARE
metadata.cyber.orgs network.organization_name El valor se copia directamente si el índice es igual a 0.
metadata.cyber.orgs about.labels.metadatacyber%{index}_orgs El valor se copia directamente si el índice no es igual a 0.
metadata.cyber.products principal.application El valor se copia directamente si el índice es igual a 0.
metadata.cyber.products principal.labels.metadata_cyberproducts%{index} El valor se copia directamente si el índice no es igual a 0.
metadata.cyber.threats security_result.threat_name El valor se copia directamente si el índice es igual a 0.
metadata.cyber.threats security_result.about.labels.metadata_cyberthreats%{index} El valor se copia directamente si el índice no es igual a 0.
metadata.cyber.URLs security_result.about.url El valor se copia directamente si el índice es igual a 0.
metadata.cyber.URLs securityresult.about.labels.url%{index} El valor se copia directamente si el índice no es igual a 0.
metadata.cyber.malwares.0 security_result.category Se establece en SOFTWARE_MALICIOUS si existe.
metadata.cyber.vulnerabilities.cvss extensions.vulns.vulnerabilities.cvss_base_score Valor copiado directamente
metadata.cyber.vulnerabilities.exploitPocLinks extensions.vulns.vulnerabilities.cve_description Se unió desde un array con el separador "n"
metadata.cyber.vulnerabilities.id extensions.vulns.vulnerabilities.cve_id Valor copiado directamente
metadata.cyber.vulnerabilities.products.productName extensions.vulns.vulnerabilities.about.application El valor se copia directamente si el índice es igual a 0.
metadata.cyber.vulnerabilities.products.productVendor extensions.vulns.vulnerabilities.vendor El valor se copia directamente si el índice es igual a 0.
metadata.cyber.vulnerabilities.products.productVersion extensions.vulns.vulnerabilities.about.platform_version El valor se copia directamente si index == 0 y se quitan los espacios.
metadata.cyber.vulnerabilities.products.productName extensions.vulns.vulnerabilities.about.labels.productName_%{index} El valor se copia directamente si el índice no es igual a 0.
metadata.cyber.vulnerabilities.products.productVendor extensions.vulns.vulnerabilities.about.labels.productVendor_%{index} El valor se copia directamente si el índice no es igual a 0.
metadata.cyber.vulnerabilities.products.productVersion extensions.vulns.vulnerabilities.about.labels.productVersion_%{index} El valor se copia directamente si el índice no es igual a 0 y se quitan los espacios.
parentAlertId about.labels.parentAlertId Valor copiado directamente
post.languages.lang target.labels.post_languageslang%{index} Valor copiado directamente
post.languages.position target.labels.post_languagesposition%{index} Se convirtió en cadena
post.link target.labels.post_link Valor copiado directamente
post.media.link principal.resource.name El valor se copia directamente si el índice es igual a 0.
post.media.description target.resource.attribute.labels.post_media_description El valor se copia directamente si el índice es igual a 0.
post.media.display_url target.resource.attribute.labels.post_media_display_url El valor se copia directamente si el índice es igual a 0.
post.media.isSafe target.resource.attribute.labels.post_media_isSafe Se convierte en cadena si index == 0
post.media.media_url target.resource.attribute.labels.post_media_media_url El valor se copia directamente si el índice es igual a 0.
post.media.sizes.large.h target.resource.attribute.labels.post_media_sizes_large_h Se convierte en cadena si index == 0
post.media.sizes.large.resize target.resource.attribute.labels.post_media_sizes_large_resize El valor se copia directamente si el índice es igual a 0.
post.media.sizes.large.w target.resource.attribute.labels.post_media_sizes_large_w Se convierte en cadena si index == 0
post.media.sizes.medium.h target.resource.attribute.labels.post_media_sizes_medium_h Se convierte en cadena si index == 0
post.media.sizes.medium.resize target.resource.attribute.labels.post_media_sizes_medium_resize El valor se copia directamente si el índice es igual a 0.
post.media.sizes.medium.w target.resource.attribute.labels.post_media_sizes_medium_w Se convierte en cadena si index == 0
post.media.sizes.small.h target.resource.attribute.labels.post_media_sizes_small_h Se convierte en cadena si index == 0
post.media.sizes.small.resize target.resource.attribute.labels.post_media_sizes_small_resize El valor se copia directamente si el índice es igual a 0.
post.media.sizes.small.w target.resource.attribute.labels.post_media_sizes_small_w Se convierte en cadena si index == 0
post.media.sizes.thumb.h target.resource.attribute.labels.post_media_sizes_thumb_h Se convierte en cadena si index == 0
post.media.sizes.thumb.resize target.resource.attribute.labels.post_media_sizes_thumb_resize El valor se copia directamente si el índice es igual a 0.
post.media.sizes.thumb.w target.resource.attribute.labels.post_media_sizes_thumb_w Se convierte en cadena si index == 0
post.media.source target.resource.attribute.labels.post_media_source El valor se copia directamente si el índice es igual a 0.
post.media.thumbnail target.resource.attribute.labels.post_media_thumbnail El valor se copia directamente si el índice es igual a 0.
post.media.title target.resource.attribute.labels.post_media_title El valor se copia directamente si el índice es igual a 0.
post.media.url target.resource.attribute.labels.post_media_url El valor se copia directamente si el índice es igual a 0.
post.media.video_info.duration_millis target.resource.attribute.labels.post_media_video_info_duration_millis Se convierte en cadena si index == 0
post.media.video_info.aspect_ratio target.resource.attribute.labels.post_media_video_info_aspect_ratio Se concatena como %{med.video_info.aspect_ratio.0}, %{med.video_info.aspect_ratio.1} si index == 0
post.media.video_info.variants.bitrate target.resource.attribute.labels.post_media_video_info_variantsbitrate%{var_index} Se convirtió en cadena
post.media.video_info.variants.content_type target.resource.attribute.labels.post_media_video_info_variants_contenttype%{var_index} Valor copiado directamente
post.media.video_info.variants.url target.resource.attribute.labels.post_media_video_info_variantsurl%{var_index} Valor copiado directamente
post.media.type principal.resource.resource_subtype El valor se copia directamente si el índice es igual a 0.
post.media.link about.resource.name El valor se copia directamente si el índice no es igual a 0.
post.media.description about.resource.attribute.labels.post_media_description El valor se copia directamente si el índice no es igual a 0.
post.media.display_url about.resource.attribute.labels.post_media_display_url El valor se copia directamente si el índice no es igual a 0.
post.media.isSafe about.resource.attribute.labels.post_media_isSafe Se convierte en cadena si el índice no es 0
post.media.media_url about.resource.attribute.labels.post_media_media_url El valor se copia directamente si el índice no es igual a 0.
post.media.sizes.large.h about.resource.attribute.labels.post_media_sizes_large_h Se convierte en cadena si el índice no es 0
post.media.sizes.large.resize about.resource.attribute.labels.post_media_sizes_large_resize El valor se copia directamente si el índice no es igual a 0.
post.media.sizes.large.w about.resource.attribute.labels.post_media_sizes_large_w Se convierte en cadena si el índice no es 0
post.media.sizes.medium.h about.resource.attribute.labels.post_media_sizes_medium_h Se convierte en cadena si el índice no es 0
post.media.sizes.medium.resize about.resource.attribute.labels.post_media_sizes_medium_resize El valor se copia directamente si el índice no es igual a 0.
post.media.sizes.medium.w about.resource.attribute.labels.post_media_sizes_medium_w Se convierte en cadena si el índice no es 0
post.media.sizes.small.h about.resource.attribute.labels.post_media_sizes_small_h Se convierte en cadena si el índice no es 0
post.media.sizes.small.resize about.resource.attribute.labels.post_media_sizes_small_resize El valor se copia directamente si el índice no es igual a 0.
post.media.sizes.small.w about.resource.attribute.labels.post_media_sizes_small_w Se convierte en cadena si el índice no es 0
post.media.sizes.thumb.h about.resource.attribute.labels.post_media_sizes_thumb_h Se convierte en cadena si el índice no es 0
post.media.sizes.thumb.resize about.resource.attribute.labels.post_media_sizes_thumb_resize El valor se copia directamente si el índice no es igual a 0.
post.media.sizes.thumb.w about.resource.attribute.labels.post_media_sizes_thumb_w Se convierte en cadena si el índice no es 0
post.media.source about.resource.attribute.labels.post_media_source El valor se copia directamente si el índice no es igual a 0.
post.media.thumbnail about.resource.attribute.labels.post_media_thumbnail El valor se copia directamente si el índice no es igual a 0.
post.media.title about.resource.attribute.labels.post_media_title El valor se copia directamente si el índice no es igual a 0.
post.media.url about.resource.attribute.labels.post_media_url El valor se copia directamente si el índice no es igual a 0.
post.media.video_info.duration_millis about.resource.attribute.labels.post_media_video_info_duration_millis Se convierte en cadena si el índice no es 0
post.media.video_info.aspect_ratio about.resource.attribute.labels.post_media_video_info_aspect_ratio Se concatena como %{med.video_info.aspect_ratio.0}, %{med.video_info.aspect_ratio.1} si index != 0
post.media.video_info.variants.bitrate about.resource.attribute.labels.post_media_video_info_variantsbitrate%{var_index} Se convirtió en cadena
post.media.video_info.variants.content_type about.resource.attribute.labels.post_media_video_info_variants_contenttype%{var_index} Valor copiado directamente
post.media.video_info.variants.url about.resource.attribute.labels.post_media_video_info_variantsurl%{var_index} Valor copiado directamente
post.media.type about.resource.resource_subtype El valor se copia directamente si el índice no es igual a 0.
post.translatedText target.labels.post_translatedText Valor copiado directamente
post.text target.labels.post_text Valor copiado directamente
post.timestamp target.resource.attribute.creation_time Se convirtió de ms de época a marca de tiempo
publisherCategory.color target.labels.publisherCategory_color Valor copiado directamente
publisherCategory.name target.labels.publisherCategory_name Valor copiado directamente
publisherCategory.shortName target.labels.publisherCategory_shortName Valor copiado directamente
relatedTerms.url principal.labels.relatedTerms_%{terms.text} Valor copiado directamente
relatedTermsQueryURL principal.labels.relatedTermsQueryURL Valor copiado directamente
sect.id about.labels.sectors_id Valor copiado directamente
sect.idStr about.labels.sectors_idStr Valor copiado directamente
sect.name about.labels.sectors_name Valor copiado directamente
sect.retired about.labels.sectors_retired Se convirtió en cadena
sect.topicType about.labels.sectors_topicType Valor copiado directamente
source.channels.0 principal.application Valor copiado directamente
source.displayName principal.user.user_display_name Valor copiado directamente
source.link principal.url Valor copiado directamente
source.verified principal.labels.source_verified Se convirtió en cadena
subCaption.bullets.content about.labels.subCaption_bullets_content Valor copiado directamente
subCaption.bullets.media about.labels.subCaption_bullets_media Valor copiado directamente
subCaption.bullets.source about.labels.subCaption_bullets_source Valor copiado directamente
watchlist.id about.labels.watchlistsMatchedByType_id Valor copiado directamente
watchlist.externalTopicIds about.labels.watchlistsMatchedByType_externalTopicIds Se unió desde un array con un separador de comas
watchlist.name about.labels.watchlistsMatchedByType_name Valor copiado directamente
watchlist.type about.labels.watchlistsMatchedByType_type Valor copiado directamente
watchlist.userProperties.omnilist about.labels.watchlistsMatchedByType_userProperties_omnilist Valor copiado directamente
watchlist.userProperties.uiListType about.labels.watchlistsMatchedByType_userProperties_uiListType Valor copiado directamente
watchlist.userProperties.watchlistColor about.labels.watchlistsMatchedByType_userProperties_watchlistColor Valor copiado directamente
watchlist.locationGroups.locations.id about.labels.watchlistsMatchedByTypelocationGroups%{lg_i}_locationsid%{loc_i} Valor copiado directamente
watchlist.locationGroups.locations.lng about.labels.watchlistsMatchedByTypelocationGroups%{lg_i}_locationslng%{loc_i} Se convierte en cadena si lg_i != 0 o loc_i != 0
watchlist.locationGroups.locations.lat about.labels.watchlistsMatchedByTypelocationGroups%{lg_i}_locationslat%{loc_i} Se convierte en cadena si lg_i != 0 o loc_i != 0
watchlist.locationGroups.locations.name about.labels.watchlistsMatchedByTypelocationGroups%{lg_i}_locationsname%{loc_i} El valor se copia directamente si lg_i != 0 o loc_i != 0
watchlist.locationGroups.id about.labels.watchlistsMatchedByType_locationGroupsid%{lg_i} Valor copiado directamente
watchlist.locationGroups.name about.labels.watchlistsMatchedByType_locationGroupsname%{lg_i} Valor copiado directamente
watchlist.locationGroups.locations.lng about.location.region_coordinates.longitude El valor se copia directamente si lg_i == 0 y loc_i == 0.
watchlist.locationGroups.locations.lat about.location.region_coordinates.latitude El valor se copia directamente si lg_i == 0 y loc_i == 0.
watchlist.locationGroups.locations.name about.location.name El valor se copia directamente si lg_i == 0 y loc_i == 0.
source.entityName principal.hostname Valor copiado directamente
metadata.event_type Se establece en "GENERIC_EVENT" y se cambia a "SCAN_HOST" si principal_ip o principal.hostname no están vacíos.

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