Raccogliere i log degli avvisi di Dataminr
Questo documento spiega come importare i log di Dataminr Alerts in Google Security Operations utilizzando Google Cloud Storage V2, una funzione Cloud Run e Cloud Scheduler.
Dataminr Pulse fornisce informazioni in tempo reale basate sull'AI da oltre 500.000 fonti di dati pubblici globali, tra cui il deep web e il dark web. La piattaforma fornisce avvisi tempestivi su minacce informatiche emergenti, vulnerabilità, attacchi ransomware, violazioni dei dati e rischi digitali che interessano la tua organizzazione e terze parti. L'API Dataminr Pulse utilizza l'autenticazione con credenziali client OAuth 2.0 e la paginazione basata sul cursore per recuperare gli avvisi.
Prima di iniziare
Assicurati di soddisfare i seguenti prerequisiti:
- Un'istanza Google SecOps
- Un progetto Google Cloud con le seguenti API abilitate:
- API Cloud Storage
- API Cloud Run Functions
- API Cloud Scheduler
- API Cloud Pub/Sub
- Autorizzazioni per creare e gestire bucket GCS, funzioni Cloud Run, argomenti Pub/Sub e job Cloud Scheduler
- Autorizzazioni per gestire le policy IAM nei bucket GCS
- Un account Dataminr Pulse attivo con accesso API abilitato
- Credenziali API Dataminr Pulse (ID client e client secret)
- Almeno un elenco di avvisi Dataminr Pulse configurato nel tuo account Dataminr
Creare un bucket Google Cloud Storage
- Vai alla console Google Cloud.
- Seleziona il tuo progetto o creane uno nuovo.
- Nel menu di navigazione, vai a Cloud Storage > Bucket.
- Fai clic su Crea bucket.
Fornisci i seguenti dettagli di configurazione:
Impostazione Valore Assegna un nome al bucket Inserisci un nome univoco globale (ad esempio dataminr-alert-logs).Tipo di località Scegli in base alle tue esigenze (regione singola, due regioni, più regioni) Località Seleziona la posizione (ad esempio, us-central1).Classe di archiviazione Standard (consigliato per i log a cui si accede di frequente) Controllo dell'accesso Uniforme (consigliato) Strumenti di protezione (Facoltativo) Attiva il controllo delle versioni degli oggetti o la policy di conservazione Fai clic su Crea.
Raccogliere le credenziali Dataminr
Per consentire alla funzione Cloud Run di recuperare i dati degli avvisi, devi disporre delle credenziali API con autenticazione delle credenziali client OAuth 2.0 dal tuo rappresentante dell'account Dataminr.
Ottenere le credenziali API
- Contatta il rappresentante dell'account Dataminr o il team di assistenza per richiedere l'accesso all'API.
- Fornisci le seguenti informazioni:
- Nome della tua organizzazione
- Caso d'uso: integrazione con Google Chronicle SIEM
- Accesso richiesto: API Dataminr Pulse per il rischio informatico
Dataminr fornisce le credenziali API e ti offre:
- ID client: il tuo identificatore client OAuth 2.0 univoco
- Client secret: la chiave segreta del client OAuth 2.0
Verifica le credenziali API
Per verificare che le credenziali funzionino, esegui questo 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 risposta corretta restituisce un oggetto JSON contenente un campo
access_token:{ "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI...", "token_type": "Bearer", "expire": 3600 }
Raccogliere gli ID elenco avvisi
- Accedi all'applicazione web Dataminr Pulse all'indirizzo
https://app.dataminr.com. - Vai agli elenchi di avvisi (watchlists) configurati.
Annota gli ID degli elenchi di avvisi che vuoi importare in Google SecOps.
Crea un account di servizio per la funzione Cloud Run
- Nella console Google Cloud, vai a IAM e amministrazione > Service account.
- Fai clic su Crea account di servizio.
- Fornisci i seguenti dettagli di configurazione:
- Nome del service account: inserisci
dataminr-alert-collector - Descrizione service account: inserisci
Service account for Dataminr Alerts Cloud Run function to write alert data to GCS
- Nome del service account: inserisci
- Fai clic su Crea e continua.
- Nella sezione Concedi a questo account di servizio l'accesso al progetto, aggiungi i seguenti ruoli:
- Fai clic su Seleziona un ruolo, cerca e seleziona Amministratore oggetti di archiviazione.
- Fai clic su Aggiungi un altro ruolo, cerca e seleziona Cloud Run Invoker.
- Fai clic su Continua.
- Fai clic su Fine.
Concedi autorizzazioni IAM sul bucket GCS
- Vai a Cloud Storage > Bucket.
- Fai clic sul nome del bucket (ad esempio
dataminr-alert-logs). - Vai alla scheda Autorizzazioni.
- Fai clic su Concedi l'accesso.
- Fornisci i seguenti dettagli di configurazione:
- Aggiungi entità: inserisci l'email del account di servizio (ad esempio,
dataminr-alert-collector@PROJECT_ID.iam.gserviceaccount.com). - Assegna i ruoli: seleziona Storage Object Admin.
- Aggiungi entità: inserisci l'email del account di servizio (ad esempio,
- Fai clic su Salva.
Crea un argomento Pub/Sub
L'argomento Pub/Sub attiva la funzione Cloud Run quando un messaggio viene pubblicato da Cloud Scheduler.
- Nella console Google Cloud, vai a Pub/Sub > Argomenti.
- Fai clic su Crea argomento.
- Fornisci i seguenti dettagli di configurazione:
- ID argomento: inserisci
dataminr-alert-trigger - Aggiungi una sottoscrizione predefinita: lascia selezionata l'opzione
- ID argomento: inserisci
- Fai clic su Crea.
Crea la funzione Cloud Run
- Nella console Google Cloud, vai a Cloud Run Functions.
- Fai clic su Crea funzione.
Fornisci i seguenti dettagli di configurazione:
Impostazione Valore Ambiente 2ª gen. Nome della funzione dataminr-alert-collectorRegione Seleziona la stessa regione del bucket GCS Tipo di trigger Cloud Pub/Sub Argomento Pub/Sub dataminr-alert-triggerMemoria allocata 512 MiB Timeout 540 secondi Service account di runtime dataminr-alert-collectorFai clic su Avanti.
Imposta Runtime su Python 3.12.
Imposta Punto di ingresso su
main.Nel file
requirements.txt, aggiungi le seguenti dipendenze:functions-framework==3.* google-cloud-storage==2.* requests==2.*Nel file
main.py, incolla il seguente codice: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}") raiseFai clic su Esegui il deployment.
Attendi che venga eseguito il deployment della funzione. Al termine del deployment, lo stato cambia in un segno di spunta verde.
Configura le variabili di ambiente
- Dopo aver eseguito il deployment della funzione, vai a Cloud Run Functions > dataminr-alert-collector.
- Fai clic su Modifica ed esegui il deployment di una nuova revisione.
- Fai clic sulla scheda Variabili e secret (o espandi Impostazioni di runtime, build, connessioni e sicurezza per 1ª generazione).
Aggiungi le seguenti variabili di ambiente:
Chiave Valore di esempio GCS_BUCKETdataminr-alert-logsGCS_PREFIXdataminr_alertsSTATE_KEYdataminr_state/cursor.jsonCLIENT_IDIl tuo ID client OAuth 2.0 di Dataminr CLIENT_SECRETIl client secret OAuth 2.0 di Dataminr ALERT_LISTSElenco separato da virgole degli ID degli avvisi Dataminr MAX_RECORDS1000PAGE_SIZE40LOOKBACK_HOURS24Fai clic su Esegui il deployment.
Crea un job Cloud Scheduler
Cloud Scheduler pubblica un messaggio nell'argomento Pub/Sub in base a una pianificazione, attivando la funzione Cloud Run per eseguire il polling di Dataminr Pulse per nuovi avvisi.
- Nella console Google Cloud, vai a Cloud Scheduler.
- Fai clic su Crea job.
Fornisci i seguenti dettagli di configurazione:
Impostazione Valore Nome dataminr-alert-pollRegione Seleziona la stessa regione della funzione Frequenza */5 * * * *(ogni 5 minuti)Fuso orario Seleziona il tuo fuso orario (ad esempio, UTC)Fai clic su Continua.
Nella sezione Configura l'esecuzione:
- Tipo target: seleziona Pub/Sub.
- Argomento: seleziona
dataminr-alert-trigger - Corpo del messaggio: inserisci
{"poll": true}
Fai clic su Crea.
Verifica la funzione Cloud Run
- In Cloud Scheduler, individua il job
dataminr-alert-poll. - Fai clic su Forza esecuzione per attivare un'esecuzione immediata.
- Vai a Cloud Run Functions > dataminr-alert-collector > Log.
Verifica che la funzione sia stata eseguita correttamente controllando le voci di log, ad esempio:
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.ndjsonVai a Cloud Storage > Bucket > dataminr-alert-logs.
Vai al prefisso
dataminr_alerts/.Verifica che i file NDJSON vengano creati con i dati degli avvisi Dataminr.
Recupera l'account di servizio Google SecOps e configura il feed
Google SecOps utilizza un account di servizio univoco per leggere i dati dal tuo bucket GCS. Devi concedere a questo account di servizio l'accesso al tuo bucket.
Recupera l'email del account di servizio
- Vai a Impostazioni SIEM > Feed.
- Fai clic su Aggiungi nuovo feed.
- Fai clic su Configura un singolo feed.
- Nel campo Nome feed, inserisci un nome per il feed (ad esempio,
Dataminr Alerts). - Seleziona Google Cloud Storage V2 come Tipo di origine.
- Seleziona Avvisi Dataminr come Tipo di log.
- Fai clic su Ottieni service account.
Verrà visualizzata un'email univoca del account di servizio, ad esempio:
chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.comCopia questo indirizzo email per utilizzarlo nella sezione successiva.
Fai clic su Avanti.
Specifica i valori per i seguenti parametri di input:
URL bucket di archiviazione: inserisci l'URI del bucket GCS con il percorso del prefisso:
gs://dataminr-alert-logs/dataminr_alerts/Opzione di eliminazione della fonte: seleziona l'opzione di eliminazione in base alle tue preferenze:
- Mai: non elimina mai i file dopo i trasferimenti (opzione consigliata per i test).
- Elimina file trasferiti: elimina i file dopo il trasferimento riuscito.
Elimina file trasferiti e directory vuote: elimina i file e le directory vuote dopo il trasferimento riuscito.
Età massima file: includi i file modificati nell'ultimo numero di giorni (il valore predefinito è 180 giorni).
Spazio dei nomi dell'asset: spazio dei nomi dell'asset.
Etichette di importazione: l'etichetta da applicare agli eventi di questo feed (ad esempio,
DATAMINR_ALERT).
Fai clic su Avanti.
Controlla la nuova configurazione del feed nella schermata Finalizza e poi fai clic su Invia.
Concedi le autorizzazioni IAM al account di servizio Google SecOps
Il account di servizio Google SecOps deve avere il ruolo Visualizzatore oggetti Storage nel bucket GCS.
- Vai a Cloud Storage > Bucket.
- Fai clic sul nome del bucket (ad esempio
dataminr-alert-logs). - Vai alla scheda Autorizzazioni.
- Fai clic su Concedi l'accesso.
- Fornisci i seguenti dettagli di configurazione:
- Aggiungi entità: incolla l'email del account di servizio Google SecOps.
- Assegna i ruoli: seleziona Visualizzatore oggetti Storage.
Fai clic su Salva.
Tabella di mappatura UDM
| Campo log | Mappatura UDM | Logic |
|---|---|---|
| alertId | metadata.product_log_id | Valore copiato direttamente |
| alertType.color | about.labels.alertType_color | Valore copiato direttamente |
| alertType.id | about.labels.alertType_id | Valore copiato direttamente |
| alertType.name | about.labels.alertType_name | Valore copiato direttamente |
| availableRelatedAlerts | about.labels.availableRelatedAlerts | Convertito in stringa |
| didascalia | metadata.description | Valore copiato direttamente |
| cat.name | security_result.category_details | Valore copiato direttamente |
| cat.id | security_result.detection_fields.categories_id | Valore copiato direttamente |
| cat.idStr | security_result.detection_fields.categories_idStr | Valore copiato direttamente |
| cat.path | security_result.detection_fields.categories_path | Valore copiato direttamente |
| cat.requested | security_result.detection_fields.categories_requested | Valore copiato direttamente |
| cat.retired | security_result.detection_fields.categories_retired | Convertito in stringa |
| cat.topicType | about.labels.categories_topicType | Valore copiato direttamente |
| cat.name | security_result.category | Imposta POLICY_VIOLATION se cat.name == "Cybersecurity - Policy"; NETWORK_MALICIOUS se in ["Cybersecurity - Threats & Vulnerabilities", "Cybersecurity - Crime & Malicious Activity", "Threats & Precautions", "Threats"]; NETWORK_SUSPICIOUS se =~ "Cybersecurity"; MAIL_PHISHING se =~ "Email and Web Servers"; DATA_EXFILTRATION se =~ "Data Exposure and Breaches"; POLICY_VIOLATION se =~ "Government, Policy, & Political Affairs"; PHISHING se =~ "(Malware |
| comp.dm_bucket.name | security_result.about.resource.attribute.labels.dmbucket%{bucket.id} | Valore copiato direttamente |
| comp.dm_sector.name | security_result.about.resource.attribute.labels.dmsector%{sector.id} | Valore copiato direttamente |
| comp.id | security_result.about.resource.attribute.labels.companies_id | Valore copiato direttamente |
| comp.idStr | security_result.about.resource.attribute.labels.companies_idStr | Valore copiato direttamente |
| comp.locations.city | security_result.about.location.city | Valore di loc.city se loc_index == 0 |
| comp.locations.country, comp.locations.state.symbol | security_result.about.location.country_or_region | Concatenato come %{loc.country} - %{loc.state.symbol} se loc_index == 0 ed entrambi non sono vuoti |
| comp.locations.postalCode | security_result.about.resource.attribute.labels.locations_postalCode | Valore copiato direttamente se loc_index == 0 e non vuoto |
| comp.locations.state.name | security_result.about.location.state | Valore copiato direttamente se loc_index == 0 |
| comp.locations.city | about.labels.loc_%{loc_index}_city | Valore copiato direttamente se loc_index != 0 e non vuoto |
| comp.locations.country, comp.locations.state.symbol | about.labels.loc_%{loc_index}_country_or_region | Concatenato come %{loc.country} - %{loc.state.symbol} se loc_index != 0 ed entrambi non sono vuoti |
| comp.locations.postalCode | securityresult.about.resource.attribute.labels.locations%{loc_index}_postalCode | Valore copiato direttamente se loc_index != 0 e non vuoto |
| comp.locations.state.name | about.labels.loc_%{loc_index}_state_name | Valore copiato direttamente se loc_index != 0 e non vuoto |
| comp.name | security_result.about.resource.name | Valore copiato direttamente |
| comp.requested | security_result.about.resource.attribute.labels.companies_requested | Valore copiato direttamente |
| comp.retired | security_result.about.resource.attribute.labels.companies_retired | Convertito in stringa |
| comp.ticker | security_result.about.resource.attribute.labels.companies_ticker | Valore copiato direttamente |
| comp.topicType | security_result.about.resource.attribute.labels.companies_topicType | Valore copiato direttamente |
| eventLocation.coordinates.0 | principal.location.region_coordinates.latitude | Valore copiato direttamente |
| eventLocation.coordinates.1 | principal.location.region_coordinates.longitude | Valore copiato direttamente |
| eventLocation.name | principal.location.name | Valore copiato direttamente |
| eventLocation.places | principal.labels.location_places | Unito dall'array con separatore virgola |
| eventLocation.probability | principal.labels.eventLocation_probability | Convertito in stringa |
| eventLocation.radius | principal.labels.eventLocation_radius | Convertito in stringa |
| eventMapLargeURL | principal.labels.eventMapLargeURL | Valore copiato direttamente |
| eventMapSmallURL | principal.labels.eventMapSmallURL | Valore copiato direttamente |
| eventTime | @timestamp | Convertito da ms epoch a timestamp |
| eventVolume | about.labels.eventVolume | Convertito in stringa |
| expandAlertURL | metadata.url_back_to_product | Valore copiato direttamente |
| expandMapURL | principal.labels.expandMapURL | Valore copiato direttamente |
| headerColor | about.labels.headerColor | Valore copiato direttamente |
| headerLabel | about.labels.headerLabel | Valore copiato direttamente |
| metadata.cyber.addresses.ip | principal.ip | Estratto utilizzando il pattern grok se index == 0 |
| metadata.cyber.addresses.port | principal.port | Valore copiato direttamente se index == 0, convertito in numero intero |
| metadata.cyber.addresses.port | principal.labels.addresses_%{index}_port | Valore copiato direttamente se indice != 0 |
| metadata.cyber.addresses.version | principal.labels.metadata_cyberaddresses%{index}_version | Valore copiato direttamente |
| metadata.cyber.asns | network.asn | Valore copiato direttamente se index == 0 |
| metadata.cyber.asns | about.labels.metadatacyber%{index}_asn | Valore copiato direttamente se indice != 0 |
| metadata.cyber.hashValues.value | security_result.about.file.sha1 | Valore copiato direttamente se type == SHA1, in minuscolo |
| metadata.cyber.hashValues.value | security_result.about.file.sha256 | Valore copiato direttamente se type == SHA256, in minuscolo |
| metadata.cyber.malwares | security_result.associations.name | Valore copiato direttamente |
| metadata.cyber.malwares | security_result.associations.type | Impostato su MALWARE |
| metadata.cyber.orgs | network.organization_name | Valore copiato direttamente se index == 0 |
| metadata.cyber.orgs | about.labels.metadatacyber%{index}_orgs | Valore copiato direttamente se indice != 0 |
| metadata.cyber.products | principal.application | Valore copiato direttamente se index == 0 |
| metadata.cyber.products | principal.labels.metadata_cyberproducts%{index} | Valore copiato direttamente se indice != 0 |
| metadata.cyber.threats | security_result.threat_name | Valore copiato direttamente se index == 0 |
| metadata.cyber.threats | security_result.about.labels.metadata_cyberthreats%{index} | Valore copiato direttamente se indice != 0 |
| metadata.cyber.URLs | security_result.about.url | Valore copiato direttamente se index == 0 |
| metadata.cyber.URLs | securityresult.about.labels.url%{index} | Valore copiato direttamente se indice != 0 |
| metadata.cyber.malwares.0 | security_result.category | Imposta su SOFTWARE_MALICIOUS se esiste |
| metadata.cyber.vulnerabilities.cvss | extensions.vulns.vulnerabilities.cvss_base_score | Valore copiato direttamente |
| metadata.cyber.vulnerabilities.exploitPocLinks | extensions.vulns.vulnerabilities.cve_description | Unito dall'array con separatore "n" |
| metadata.cyber.vulnerabilities.id | extensions.vulns.vulnerabilities.cve_id | Valore copiato direttamente |
| metadata.cyber.vulnerabilities.products.productName | extensions.vulns.vulnerabilities.about.application | Valore copiato direttamente se index == 0 |
| metadata.cyber.vulnerabilities.products.productVendor | extensions.vulns.vulnerabilities.vendor | Valore copiato direttamente se index == 0 |
| metadata.cyber.vulnerabilities.products.productVersion | extensions.vulns.vulnerabilities.about.platform_version | Valore copiato direttamente se index == 0, spazi rimossi |
| metadata.cyber.vulnerabilities.products.productName | extensions.vulns.vulnerabilities.about.labels.productName_%{index} | Valore copiato direttamente se indice != 0 |
| metadata.cyber.vulnerabilities.products.productVendor | extensions.vulns.vulnerabilities.about.labels.productVendor_%{index} | Valore copiato direttamente se indice != 0 |
| metadata.cyber.vulnerabilities.products.productVersion | extensions.vulns.vulnerabilities.about.labels.productVersion_%{index} | Valore copiato direttamente se index != 0, spazi rimossi |
| parentAlertId | about.labels.parentAlertId | Valore copiato direttamente |
| post.languages.lang | target.labels.post_languageslang%{index} | Valore copiato direttamente |
| post.languages.position | target.labels.post_languagesposition%{index} | Convertito in stringa |
| post.link | target.labels.post_link | Valore copiato direttamente |
| post.media.link | principal.resource.name | Valore copiato direttamente se index == 0 |
| post.media.description | target.resource.attribute.labels.post_media_description | Valore copiato direttamente se index == 0 |
| post.media.display_url | target.resource.attribute.labels.post_media_display_url | Valore copiato direttamente se index == 0 |
| post.media.isSafe | target.resource.attribute.labels.post_media_isSafe | Convertito in stringa se index == 0 |
| post.media.media_url | target.resource.attribute.labels.post_media_media_url | Valore copiato direttamente se index == 0 |
| post.media.sizes.large.h | target.resource.attribute.labels.post_media_sizes_large_h | Convertito in stringa se index == 0 |
| post.media.sizes.large.resize | target.resource.attribute.labels.post_media_sizes_large_resize | Valore copiato direttamente se index == 0 |
| post.media.sizes.large.w | target.resource.attribute.labels.post_media_sizes_large_w | Convertito in stringa se index == 0 |
| post.media.sizes.medium.h | target.resource.attribute.labels.post_media_sizes_medium_h | Convertito in stringa se index == 0 |
| post.media.sizes.medium.resize | target.resource.attribute.labels.post_media_sizes_medium_resize | Valore copiato direttamente se index == 0 |
| post.media.sizes.medium.w | target.resource.attribute.labels.post_media_sizes_medium_w | Convertito in stringa se index == 0 |
| post.media.sizes.small.h | target.resource.attribute.labels.post_media_sizes_small_h | Convertito in stringa se index == 0 |
| post.media.sizes.small.resize | target.resource.attribute.labels.post_media_sizes_small_resize | Valore copiato direttamente se index == 0 |
| post.media.sizes.small.w | target.resource.attribute.labels.post_media_sizes_small_w | Convertito in stringa se index == 0 |
| post.media.sizes.thumb.h | target.resource.attribute.labels.post_media_sizes_thumb_h | Convertito in stringa se index == 0 |
| post.media.sizes.thumb.resize | target.resource.attribute.labels.post_media_sizes_thumb_resize | Valore copiato direttamente se index == 0 |
| post.media.sizes.thumb.w | target.resource.attribute.labels.post_media_sizes_thumb_w | Convertito in stringa se index == 0 |
| post.media.source | target.resource.attribute.labels.post_media_source | Valore copiato direttamente se index == 0 |
| post.media.thumbnail | target.resource.attribute.labels.post_media_thumbnail | Valore copiato direttamente se index == 0 |
| post.media.title | target.resource.attribute.labels.post_media_title | Valore copiato direttamente se index == 0 |
| post.media.url | target.resource.attribute.labels.post_media_url | Valore copiato direttamente se index == 0 |
| post.media.video_info.duration_millis | target.resource.attribute.labels.post_media_video_info_duration_millis | Convertito in stringa se index == 0 |
| post.media.video_info.aspect_ratio | target.resource.attribute.labels.post_media_video_info_aspect_ratio | Concatenato come %{med.video_info.aspect_ratio.0}, %{med.video_info.aspect_ratio.1} se index == 0 |
| post.media.video_info.variants.bitrate | target.resource.attribute.labels.post_media_video_info_variantsbitrate%{var_index} | Convertito in stringa |
| post.media.video_info.variants.content_type | target.resource.attribute.labels.post_media_video_info_variants_contenttype%{var_index} | Valore copiato direttamente |
| post.media.video_info.variants.url | target.resource.attribute.labels.post_media_video_info_variantsurl%{var_index} | Valore copiato direttamente |
| post.media.type | principal.resource.resource_subtype | Valore copiato direttamente se index == 0 |
| post.media.link | about.resource.name | Valore copiato direttamente se indice != 0 |
| post.media.description | about.resource.attribute.labels.post_media_description | Valore copiato direttamente se indice != 0 |
| post.media.display_url | about.resource.attribute.labels.post_media_display_url | Valore copiato direttamente se indice != 0 |
| post.media.isSafe | about.resource.attribute.labels.post_media_isSafe | Convertito in stringa se index != 0 |
| post.media.media_url | about.resource.attribute.labels.post_media_media_url | Valore copiato direttamente se indice != 0 |
| post.media.sizes.large.h | about.resource.attribute.labels.post_media_sizes_large_h | Convertito in stringa se index != 0 |
| post.media.sizes.large.resize | about.resource.attribute.labels.post_media_sizes_large_resize | Valore copiato direttamente se indice != 0 |
| post.media.sizes.large.w | about.resource.attribute.labels.post_media_sizes_large_w | Convertito in stringa se index != 0 |
| post.media.sizes.medium.h | about.resource.attribute.labels.post_media_sizes_medium_h | Convertito in stringa se index != 0 |
| post.media.sizes.medium.resize | about.resource.attribute.labels.post_media_sizes_medium_resize | Valore copiato direttamente se indice != 0 |
| post.media.sizes.medium.w | about.resource.attribute.labels.post_media_sizes_medium_w | Convertito in stringa se index != 0 |
| post.media.sizes.small.h | about.resource.attribute.labels.post_media_sizes_small_h | Convertito in stringa se index != 0 |
| post.media.sizes.small.resize | about.resource.attribute.labels.post_media_sizes_small_resize | Valore copiato direttamente se indice != 0 |
| post.media.sizes.small.w | about.resource.attribute.labels.post_media_sizes_small_w | Convertito in stringa se index != 0 |
| post.media.sizes.thumb.h | about.resource.attribute.labels.post_media_sizes_thumb_h | Convertito in stringa se index != 0 |
| post.media.sizes.thumb.resize | about.resource.attribute.labels.post_media_sizes_thumb_resize | Valore copiato direttamente se indice != 0 |
| post.media.sizes.thumb.w | about.resource.attribute.labels.post_media_sizes_thumb_w | Convertito in stringa se index != 0 |
| post.media.source | about.resource.attribute.labels.post_media_source | Valore copiato direttamente se indice != 0 |
| post.media.thumbnail | about.resource.attribute.labels.post_media_thumbnail | Valore copiato direttamente se indice != 0 |
| post.media.title | about.resource.attribute.labels.post_media_title | Valore copiato direttamente se indice != 0 |
| post.media.url | about.resource.attribute.labels.post_media_url | Valore copiato direttamente se indice != 0 |
| post.media.video_info.duration_millis | about.resource.attribute.labels.post_media_video_info_duration_millis | Convertito in stringa se index != 0 |
| post.media.video_info.aspect_ratio | about.resource.attribute.labels.post_media_video_info_aspect_ratio | Concatenato come %{med.video_info.aspect_ratio.0}, %{med.video_info.aspect_ratio.1} se l'indice è diverso da 0 |
| post.media.video_info.variants.bitrate | about.resource.attribute.labels.post_media_video_info_variantsbitrate%{var_index} | Convertito in stringa |
| post.media.video_info.variants.content_type | about.resource.attribute.labels.post_media_video_info_variants_contenttype%{var_index} | Valore copiato direttamente |
| post.media.video_info.variants.url | about.resource.attribute.labels.post_media_video_info_variantsurl%{var_index} | Valore copiato direttamente |
| post.media.type | about.resource.resource_subtype | Valore copiato direttamente se indice != 0 |
| post.translatedText | target.labels.post_translatedText | Valore copiato direttamente |
| post.text | target.labels.post_text | Valore copiato direttamente |
| post.timestamp | target.resource.attribute.creation_time | Convertito da ms epoch a timestamp |
| publisherCategory.color | target.labels.publisherCategory_color | Valore copiato direttamente |
| publisherCategory.name | target.labels.publisherCategory_name | Valore copiato direttamente |
| publisherCategory.shortName | target.labels.publisherCategory_shortName | Valore copiato direttamente |
| relatedTerms.url | principal.labels.relatedTerms_%{terms.text} | Valore copiato direttamente |
| relatedTermsQueryURL | principal.labels.relatedTermsQueryURL | Valore copiato direttamente |
| sect.id | about.labels.sectors_id | Valore copiato direttamente |
| sect.idStr | about.labels.sectors_idStr | Valore copiato direttamente |
| sect.name | about.labels.sectors_name | Valore copiato direttamente |
| sect.retired | about.labels.sectors_retired | Convertito in stringa |
| sect.topicType | about.labels.sectors_topicType | Valore copiato direttamente |
| source.channels.0 | principal.application | Valore copiato direttamente |
| source.displayName | principal.user.user_display_name | Valore copiato direttamente |
| source.link | principal.url | Valore copiato direttamente |
| source.verified | principal.labels.source_verified | Convertito in stringa |
| subCaption.bullets.content | about.labels.subCaption_bullets_content | Valore copiato direttamente |
| subCaption.bullets.media | about.labels.subCaption_bullets_media | Valore copiato direttamente |
| subCaption.bullets.source | about.labels.subCaption_bullets_source | Valore copiato direttamente |
| watchlist.id | about.labels.watchlistsMatchedByType_id | Valore copiato direttamente |
| watchlist.externalTopicIds | about.labels.watchlistsMatchedByType_externalTopicIds | Unito dall'array con separatore virgola |
| watchlist.name | about.labels.watchlistsMatchedByType_name | Valore copiato direttamente |
| watchlist.type | about.labels.watchlistsMatchedByType_type | Valore copiato direttamente |
| watchlist.userProperties.omnilist | about.labels.watchlistsMatchedByType_userProperties_omnilist | Valore copiato direttamente |
| watchlist.userProperties.uiListType | about.labels.watchlistsMatchedByType_userProperties_uiListType | Valore copiato direttamente |
| watchlist.userProperties.watchlistColor | about.labels.watchlistsMatchedByType_userProperties_watchlistColor | Valore copiato direttamente |
| watchlist.locationGroups.locations.id | about.labels.watchlistsMatchedByTypelocationGroups%{lg_i}_locationsid%{loc_i} | Valore copiato direttamente |
| watchlist.locationGroups.locations.lng | about.labels.watchlistsMatchedByTypelocationGroups%{lg_i}_locationslng%{loc_i} | Convertito in stringa se lg_i != 0 o loc_i != 0 |
| watchlist.locationGroups.locations.lat | about.labels.watchlistsMatchedByTypelocationGroups%{lg_i}_locationslat%{loc_i} | Convertito in stringa se lg_i != 0 o loc_i != 0 |
| watchlist.locationGroups.locations.name | about.labels.watchlistsMatchedByTypelocationGroups%{lg_i}_locationsname%{loc_i} | Valore copiato direttamente se lg_i != 0 o loc_i != 0 |
| watchlist.locationGroups.id | about.labels.watchlistsMatchedByType_locationGroupsid%{lg_i} | Valore copiato direttamente |
| watchlist.locationGroups.name | about.labels.watchlistsMatchedByType_locationGroupsname%{lg_i} | Valore copiato direttamente |
| watchlist.locationGroups.locations.lng | about.location.region_coordinates.longitude | Valore copiato direttamente se lg_i == 0 e loc_i == 0 |
| watchlist.locationGroups.locations.lat | about.location.region_coordinates.latitude | Valore copiato direttamente se lg_i == 0 e loc_i == 0 |
| watchlist.locationGroups.locations.name | about.location.name | Valore copiato direttamente se lg_i == 0 e loc_i == 0 |
| source.entityName | principal.hostname | Valore copiato direttamente |
| metadata.event_type | Impostato su "GENERIC_EVENT"; modificato in "SCAN_HOST" se principal_ip o principal.hostname non sono vuoti |
Hai bisogno di ulteriore assistenza? Ricevi risposte dai membri della community e dai professionisti di Google SecOps.