Coletar registros de alertas do Dataminr
Este documento explica como ingerir registros de alertas do Dataminr no Google Security Operations usando o Google Cloud Storage V2, uma função do Cloud Run e o Cloud Scheduler.
O Dataminr Pulse oferece inteligência em tempo real com tecnologia de IA de mais de 500.000 fontes de dados públicos globais, incluindo a deep e a dark web. A plataforma envia alertas antecipados sobre ameaças cibernéticas, vulnerabilidades, ataques de ransomware, violações de dados e riscos digitais emergentes que afetam sua organização e terceiros. A API Dataminr Pulse usa autenticação de credenciais de cliente do OAuth 2.0 e paginação baseada em cursor para recuperar alertas.
Antes de começar
Verifique se você tem os pré-requisitos a seguir:
- Uma instância do Google SecOps
- Um projeto do Google Cloud com as seguintes APIs ativadas:
- API Cloud Storage
- API Funções do Cloud Run
- API Cloud Scheduler
- API Cloud Pub/Sub
- Permissões para criar e gerenciar buckets do GCS, funções do Cloud Run, tópicos do Pub/Sub e jobs do Cloud Scheduler
- Permissões para gerenciar políticas do IAM em buckets do GCS
- Uma conta ativa do Dataminr Pulse com acesso à API ativado
- Credenciais da API Dataminr Pulse (ID e chave secreta do cliente)
- Pelo menos uma lista de alertas do Dataminr Pulse configurada na sua conta do Dataminr
Criar um bucket do Google Cloud Storage.
- Acesse o Console do Google Cloud.
- Selecione seu projeto ou crie um novo.
- No menu de navegação, acesse Cloud Storage > Buckets.
- Clique em Criar bucket.
Informe os seguintes detalhes de configuração:
Configuração Valor Nomeie seu bucket Insira um nome exclusivo globalmente, por exemplo, dataminr-alert-logs.Tipo de local Escolha com base nas suas necessidades (região, birregional, multirregional) Local Selecione o local (por exemplo, us-central1).Classe de armazenamento Padrão (recomendado para registros acessados com frequência) Controle de acesso Uniforme (recomendado) Ferramentas de proteção Opcional: ativar o controle de versões de objetos ou a política de retenção Clique em Criar.
Coletar credenciais do Dataminr
Para permitir que a função do Cloud Run recupere dados de alertas, você precisa de credenciais de API com autenticação de credenciais de cliente OAuth 2.0 do representante da sua conta do Dataminr.
Receber credenciais de API
- Entre em contato com o representante da sua conta do Dataminr ou com a equipe de suporte para solicitar acesso à API.
- Informe o seguinte:
- Nome da sua organização
- Caso de uso: integração com o SIEM do Google Chronicle
- Acesso necessário: API Dataminr Pulse para risco cibernético
A Dataminr provisiona credenciais de API e oferece:
- ID do cliente: seu identificador exclusivo do cliente OAuth 2.0.
- Chave secreta do cliente: sua chave secreta do cliente OAuth 2.0
Verificar credenciais da API
Para verificar se as suas credenciais estão funcionando, execute o seguinte 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"Uma resposta bem-sucedida retorna um objeto JSON que contém um campo
access_token:{ "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI...", "token_type": "Bearer", "expire": 3600 }
Coletar IDs de lista de alertas
- Faça login no aplicativo da Web Dataminr Pulse em
https://app.dataminr.com. - Acesse as listas de alertas (listas de observação) configuradas.
Anote os IDs das listas de alertas que você quer ingerir no Google SecOps.
Criar uma conta de serviço para a função do Cloud Run
- No console do Google Cloud, acesse IAM e administrador > Contas de serviço.
- Clique em Criar conta de serviço.
- Informe os seguintes detalhes de configuração:
- Nome da conta de serviço: insira
dataminr-alert-collector - Descrição da conta de serviço: insira
Service account for Dataminr Alerts Cloud Run function to write alert data to GCS
- Nome da conta de serviço: insira
- Clique em Criar e continuar.
- Na seção Conceder acesso a essa conta de serviço ao projeto, adicione os seguintes papéis:
- Clique em Selecionar um papel, pesquise e selecione Administrador de objetos do Storage.
- Clique em Adicionar outro papel, pesquise e selecione Invocador do Cloud Run.
- Clique em Continuar.
- Clique em Concluído.
Conceder permissões do IAM no bucket do GCS
- Acesse Cloud Storage > Buckets.
- Clique no nome do bucket (por exemplo,
dataminr-alert-logs). - Acesse a guia Permissões.
- Clique em Conceder acesso.
- Informe os seguintes detalhes de configuração:
- Adicionar principais: insira o e-mail da conta de serviço (por exemplo,
dataminr-alert-collector@PROJECT_ID.iam.gserviceaccount.com). - Atribuir papéis: selecione Administrador de objetos do Storage.
- Adicionar principais: insira o e-mail da conta de serviço (por exemplo,
- Clique em Salvar.
Criar um tópico do Pub/Sub
O tópico do Pub/Sub aciona a função do Cloud Run quando uma mensagem é publicada pelo Cloud Scheduler.
- No console do Google Cloud, acesse Pub/Sub > Tópicos.
- Clique em Criar tópico.
- Informe os seguintes detalhes de configuração:
- ID do tópico: insira
dataminr-alert-trigger - Adicionar uma assinatura padrão: deixe marcada
- ID do tópico: insira
- Clique em Criar.
Criar a função do Cloud Run
- No console do Google Cloud, acesse Funções do Cloud Run.
- Clique em Criar função.
Informe os seguintes detalhes de configuração:
Configuração Valor Ambiente 2ª geração Nome da função dataminr-alert-collectorRegião Selecione a mesma região do seu bucket do GCS. Tipo de gatilho Cloud Pub/Sub Tópico do Pub/Sub dataminr-alert-triggerMemória alocada 512 MiB Tempo limite 540 segundos Conta de serviço do ambiente de execução dataminr-alert-collectorClique em Próxima.
Defina Ambiente de execução como Python 3.12.
Defina o Ponto de entrada como
main.No arquivo
requirements.txt, adicione as seguintes dependências:functions-framework==3.* google-cloud-storage==2.* requests==2.*No arquivo
main.py, cole o seguinte 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}") raiseClique em Implantar.
Aguarde a implantação da função. O status muda para uma marca de seleção verde quando a implantação é concluída.
Configure as variáveis de ambiente
- Depois que a função for implantada, acesse Cloud Run Functions > dataminr-alert-collector.
- Clique em Editar e implantar nova revisão.
- Clique na guia Variáveis e secrets ou expanda Ambiente de execução, build, conexões e configurações de segurança para a 1ª geração.
Adicione as seguintes variáveis de ambiente:
Chave Valor de exemplo GCS_BUCKETdataminr-alert-logsGCS_PREFIXdataminr_alertsSTATE_KEYdataminr_state/cursor.jsonCLIENT_IDSeu ID do cliente OAuth 2.0 do Dataminr CLIENT_SECRETSua chave secreta do cliente OAuth 2.0 do Dataminr ALERT_LISTSIDs de lista de alertas do Dataminr separados por vírgulas MAX_RECORDS1000PAGE_SIZE40LOOKBACK_HOURS24Clique em Implantar.
Criar um job do Cloud Scheduler
O Cloud Scheduler publica uma mensagem no tópico do Pub/Sub em uma programação, acionando a função do Cloud Run para pesquisar novos alertas no Dataminr Pulse.
- No console do Google Cloud, acesse o Cloud Scheduler.
- Clique em Criar job.
Informe os seguintes detalhes de configuração:
Configuração Valor Nome dataminr-alert-pollRegião Selecione a mesma região da função. Frequência */5 * * * *(a cada 5 minutos)Fuso horário Selecione seu fuso horário (por exemplo, UTC).Clique em Continuar.
Na seção Configurar a execução:
- Tipo de destino: selecione Pub/Sub.
- Tema: selecione
dataminr-alert-trigger - Corpo da mensagem: insira
{"poll": true}.
Clique em Criar.
Verificar a função do Cloud Run
- No Cloud Scheduler, localize o job
dataminr-alert-poll. - Clique em Forçar execução para acionar uma execução imediata.
- Acesse Cloud Run Functions > dataminr-alert-collector > Registros.
Verifique se a função foi executada com sucesso conferindo entradas de registro como:
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.ndjsonAcesse Cloud Storage > Buckets > dataminr-alert-logs.
Navegue até o prefixo
dataminr_alerts/.Verifique se os arquivos NDJSON estão sendo criados com dados de alerta do Dataminr.
Recuperar a conta de serviço do Google SecOps e configurar o feed
O Google SecOps usa uma conta de serviço exclusiva para ler dados do seu bucket do GCS. Você precisa conceder a essa conta de serviço acesso ao seu bucket.
Receber o e-mail da conta de serviço
- Acesse Configurações do SIEM > Feeds.
- Clique em Adicionar novo feed.
- Clique em Configurar um único feed.
- No campo Nome do feed, insira um nome para o feed (por exemplo,
Dataminr Alerts). - Selecione Google Cloud Storage V2 como o Tipo de origem.
- Selecione Alertas do Dataminr como o Tipo de registro.
- Clique em Receber conta de serviço.
Um e-mail exclusivo da conta de serviço será exibido, por exemplo:
chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.comCopie esse endereço de e-mail para usar na próxima seção.
Clique em Próxima.
Especifique valores para os seguintes parâmetros de entrada:
URL do bucket de armazenamento: insira o URI do bucket do GCS com o caminho do prefixo:
gs://dataminr-alert-logs/dataminr_alerts/Opção de exclusão da fonte: selecione a opção de exclusão de acordo com sua preferência:
- Nunca: nunca exclui arquivos após as transferências (recomendado para testes).
- Excluir arquivos transferidos: exclui os arquivos após a transferência ser concluída.
Excluir arquivos transferidos e diretórios vazios: exclui arquivos e diretórios vazios após a transferência bem-sucedida.
Idade máxima do arquivo: inclui arquivos modificados nos últimos dias (o padrão é 180 dias).
Namespace do recurso: namespace do recurso.
Rótulos de ingestão: o rótulo a ser aplicado aos eventos deste feed (por exemplo,
DATAMINR_ALERT).
Clique em Próxima.
Revise a nova configuração do feed na tela Finalizar e clique em Enviar.
Conceder permissões do IAM à conta de serviço do Google SecOps
A conta de serviço do Google SecOps precisa do papel Leitor de objetos do Storage no seu bucket do GCS.
- Acesse Cloud Storage > Buckets.
- Clique no nome do bucket (por exemplo,
dataminr-alert-logs). - Acesse a guia Permissões.
- Clique em Conceder acesso.
- Informe os seguintes detalhes de configuração:
- Adicionar participantes: cole o e-mail da conta de serviço do Google SecOps.
- Atribuir papéis: selecione Leitor de objetos do Storage.
Clique em Salvar.
Tabela de mapeamento do UDM
| Campo de registro | Mapeamento do UDM | Lógica |
|---|---|---|
| alertId | metadata.product_log_id | Valor copiado diretamente |
| alertType.color | about.labels.alertType_color | Valor copiado diretamente |
| alertType.id | about.labels.alertType_id | Valor copiado diretamente |
| alertType.name | about.labels.alertType_name | Valor copiado diretamente |
| availableRelatedAlerts | about.labels.availableRelatedAlerts | Convertido em string |
| caption | metadata.description | Valor copiado diretamente |
| cat.name | security_result.category_details | Valor copiado diretamente |
| cat.id | security_result.detection_fields.categories_id | Valor copiado diretamente |
| cat.idStr | security_result.detection_fields.categories_idStr | Valor copiado diretamente |
| cat.path | security_result.detection_fields.categories_path | Valor copiado diretamente |
| cat.requested | security_result.detection_fields.categories_requested | Valor copiado diretamente |
| cat.retired | security_result.detection_fields.categories_retired | Convertido em string |
| cat.topicType | about.labels.categories_topicType | Valor copiado diretamente |
| cat.name | security_result.category | Definido como POLICY_VIOLATION se cat.name == "Cybersecurity - Policy"; NETWORK_MALICIOUS se estiver em ["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} | Valor copiado diretamente |
| comp.dm_sector.name | security_result.about.resource.attribute.labels.dmsector%{sector.id} | Valor copiado diretamente |
| comp.id | security_result.about.resource.attribute.labels.companies_id | Valor copiado diretamente |
| comp.idStr | security_result.about.resource.attribute.labels.companies_idStr | Valor copiado diretamente |
| comp.locations.city | security_result.about.location.city | Valor de loc.city se loc_index == 0 |
| comp.locations.country, comp.locations.state.symbol | security_result.about.location.country_or_region | Concatenado como %{loc.country} - %{loc.state.symbol} se loc_index == 0 e ambos não estiverem vazios |
| comp.locations.postalCode | security_result.about.resource.attribute.labels.locations_postalCode | Valor copiado diretamente se loc_index == 0 e não estiver vazio |
| comp.locations.state.name | security_result.about.location.state | Valor copiado diretamente se loc_index == 0 |
| comp.locations.city | about.labels.loc_%{loc_index}_city | Valor copiado diretamente se loc_index != 0 e não estiver vazio |
| comp.locations.country, comp.locations.state.symbol | about.labels.loc_%{loc_index}_country_or_region | Concatenado como %{loc.country} - %{loc.state.symbol} se loc_index != 0 e ambos não estiverem vazios |
| comp.locations.postalCode | securityresult.about.resource.attribute.labels.locations%{loc_index}_postalCode | Valor copiado diretamente se loc_index != 0 e não estiver vazio |
| comp.locations.state.name | about.labels.loc_%{loc_index}_state_name | Valor copiado diretamente se loc_index != 0 e não estiver vazio |
| comp.name | security_result.about.resource.name | Valor copiado diretamente |
| comp.requested | security_result.about.resource.attribute.labels.companies_requested | Valor copiado diretamente |
| comp.retired | security_result.about.resource.attribute.labels.companies_retired | Convertido em string |
| comp.ticker | security_result.about.resource.attribute.labels.companies_ticker | Valor copiado diretamente |
| comp.topicType | security_result.about.resource.attribute.labels.companies_topicType | Valor copiado diretamente |
| eventLocation.coordinates.0 | principal.location.region_coordinates.latitude | Valor copiado diretamente |
| eventLocation.coordinates.1 | principal.location.region_coordinates.longitude | Valor copiado diretamente |
| eventLocation.name | principal.location.name | Valor copiado diretamente |
| eventLocation.places | principal.labels.location_places | Unido de matriz com separador de vírgulas |
| eventLocation.probability | principal.labels.eventLocation_probability | Convertido em string |
| eventLocation.radius | principal.labels.eventLocation_radius | Convertido em string |
| eventMapLargeURL | principal.labels.eventMapLargeURL | Valor copiado diretamente |
| eventMapSmallURL | principal.labels.eventMapSmallURL | Valor copiado diretamente |
| eventTime | @timestamp | Convertido de ms de época para carimbo de data/hora |
| eventVolume | about.labels.eventVolume | Convertido em string |
| expandAlertURL | metadata.url_back_to_product | Valor copiado diretamente |
| expandMapURL | principal.labels.expandMapURL | Valor copiado diretamente |
| headerColor | about.labels.headerColor | Valor copiado diretamente |
| headerLabel | about.labels.headerLabel | Valor copiado diretamente |
| metadata.cyber.addresses.ip | principal.ip | Extraído usando o padrão grok se index == 0 |
| metadata.cyber.addresses.port | principal.port | Valor copiado diretamente se index == 0, convertido em número inteiro |
| metadata.cyber.addresses.port | principal.labels.addresses_%{index}_port | Valor copiado diretamente se index != 0 |
| metadata.cyber.addresses.version | principal.labels.metadata_cyberaddresses%{index}_version | Valor copiado diretamente |
| metadata.cyber.asns | network.asn | Valor copiado diretamente se index == 0 |
| metadata.cyber.asns | about.labels.metadatacyber%{index}_asn | Valor copiado diretamente se index != 0 |
| metadata.cyber.hashValues.value | security_result.about.file.sha1 | Valor copiado diretamente se type == SHA1, em letras minúsculas |
| metadata.cyber.hashValues.value | security_result.about.file.sha256 | Valor copiado diretamente se type == SHA256, em letras minúsculas |
| metadata.cyber.malwares | security_result.associations.name | Valor copiado diretamente |
| metadata.cyber.malwares | security_result.associations.type | Definido como MALWARE |
| metadata.cyber.orgs | network.organization_name | Valor copiado diretamente se index == 0 |
| metadata.cyber.orgs | about.labels.metadatacyber%{index}_orgs | Valor copiado diretamente se index != 0 |
| metadata.cyber.products | principal.application | Valor copiado diretamente se index == 0 |
| metadata.cyber.products | principal.labels.metadata_cyberproducts%{index} | Valor copiado diretamente se index != 0 |
| metadata.cyber.threats | security_result.threat_name | Valor copiado diretamente se index == 0 |
| metadata.cyber.threats | security_result.about.labels.metadata_cyberthreats%{index} | Valor copiado diretamente se index != 0 |
| metadata.cyber.URLs | security_result.about.url | Valor copiado diretamente se index == 0 |
| metadata.cyber.URLs | securityresult.about.labels.url%{index} | Valor copiado diretamente se index != 0 |
| metadata.cyber.malwares.0 | security_result.category | Definido como SOFTWARE_MALICIOUS se existir |
| metadata.cyber.vulnerabilities.cvss | extensions.vulns.vulnerabilities.cvss_base_score | Valor copiado diretamente |
| metadata.cyber.vulnerabilities.exploitPocLinks | extensions.vulns.vulnerabilities.cve_description | Unido da matriz com o separador " n" |
| metadata.cyber.vulnerabilities.id | extensions.vulns.vulnerabilities.cve_id | Valor copiado diretamente |
| metadata.cyber.vulnerabilities.products.productName | extensions.vulns.vulnerabilities.about.application | Valor copiado diretamente se index == 0 |
| metadata.cyber.vulnerabilities.products.productVendor | extensions.vulns.vulnerabilities.vendor | Valor copiado diretamente se index == 0 |
| metadata.cyber.vulnerabilities.products.productVersion | extensions.vulns.vulnerabilities.about.platform_version | Valor copiado diretamente se index == 0, espaços removidos |
| metadata.cyber.vulnerabilities.products.productName | extensions.vulns.vulnerabilities.about.labels.productName_%{index} | Valor copiado diretamente se index != 0 |
| metadata.cyber.vulnerabilities.products.productVendor | extensions.vulns.vulnerabilities.about.labels.productVendor_%{index} | Valor copiado diretamente se index != 0 |
| metadata.cyber.vulnerabilities.products.productVersion | extensions.vulns.vulnerabilities.about.labels.productVersion_%{index} | Valor copiado diretamente se o índice for diferente de 0, espaços removidos |
| parentAlertId | about.labels.parentAlertId | Valor copiado diretamente |
| post.languages.lang | target.labels.post_languageslang%{index} | Valor copiado diretamente |
| post.languages.position | target.labels.post_languagesposition%{index} | Convertido em string |
| post.link | target.labels.post_link | Valor copiado diretamente |
| post.media.link | principal.resource.name | Valor copiado diretamente se index == 0 |
| post.media.description | target.resource.attribute.labels.post_media_description | Valor copiado diretamente se index == 0 |
| post.media.display_url | target.resource.attribute.labels.post_media_display_url | Valor copiado diretamente se index == 0 |
| post.media.isSafe | target.resource.attribute.labels.post_media_isSafe | Convertido para string se index == 0 |
| post.media.media_url | target.resource.attribute.labels.post_media_media_url | Valor copiado diretamente se index == 0 |
| post.media.sizes.large.h | target.resource.attribute.labels.post_media_sizes_large_h | Convertido para string se index == 0 |
| post.media.sizes.large.resize | target.resource.attribute.labels.post_media_sizes_large_resize | Valor copiado diretamente se index == 0 |
| post.media.sizes.large.w | target.resource.attribute.labels.post_media_sizes_large_w | Convertido para string se index == 0 |
| post.media.sizes.medium.h | target.resource.attribute.labels.post_media_sizes_medium_h | Convertido para string se index == 0 |
| post.media.sizes.medium.resize | target.resource.attribute.labels.post_media_sizes_medium_resize | Valor copiado diretamente se index == 0 |
| post.media.sizes.medium.w | target.resource.attribute.labels.post_media_sizes_medium_w | Convertido para string se index == 0 |
| post.media.sizes.small.h | target.resource.attribute.labels.post_media_sizes_small_h | Convertido para string se index == 0 |
| post.media.sizes.small.resize | target.resource.attribute.labels.post_media_sizes_small_resize | Valor copiado diretamente se index == 0 |
| post.media.sizes.small.w | target.resource.attribute.labels.post_media_sizes_small_w | Convertido para string se index == 0 |
| post.media.sizes.thumb.h | target.resource.attribute.labels.post_media_sizes_thumb_h | Convertido para string se index == 0 |
| post.media.sizes.thumb.resize | target.resource.attribute.labels.post_media_sizes_thumb_resize | Valor copiado diretamente se index == 0 |
| post.media.sizes.thumb.w | target.resource.attribute.labels.post_media_sizes_thumb_w | Convertido para string se index == 0 |
| post.media.source | target.resource.attribute.labels.post_media_source | Valor copiado diretamente se index == 0 |
| post.media.thumbnail | target.resource.attribute.labels.post_media_thumbnail | Valor copiado diretamente se index == 0 |
| post.media.title | target.resource.attribute.labels.post_media_title | Valor copiado diretamente se index == 0 |
| post.media.url | target.resource.attribute.labels.post_media_url | Valor copiado diretamente se index == 0 |
| post.media.video_info.duration_millis | target.resource.attribute.labels.post_media_video_info_duration_millis | Convertido para string se index == 0 |
| post.media.video_info.aspect_ratio | target.resource.attribute.labels.post_media_video_info_aspect_ratio | Concatenado como %{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} | Convertido em string |
| post.media.video_info.variants.content_type | target.resource.attribute.labels.post_media_video_info_variants_contenttype%{var_index} | Valor copiado diretamente |
| post.media.video_info.variants.url | target.resource.attribute.labels.post_media_video_info_variantsurl%{var_index} | Valor copiado diretamente |
| post.media.type | principal.resource.resource_subtype | Valor copiado diretamente se index == 0 |
| post.media.link | about.resource.name | Valor copiado diretamente se index != 0 |
| post.media.description | about.resource.attribute.labels.post_media_description | Valor copiado diretamente se index != 0 |
| post.media.display_url | about.resource.attribute.labels.post_media_display_url | Valor copiado diretamente se index != 0 |
| post.media.isSafe | about.resource.attribute.labels.post_media_isSafe | Convertido em string se o índice for diferente de 0 |
| post.media.media_url | about.resource.attribute.labels.post_media_media_url | Valor copiado diretamente se index != 0 |
| post.media.sizes.large.h | about.resource.attribute.labels.post_media_sizes_large_h | Convertido em string se o índice != 0 |
| post.media.sizes.large.resize | about.resource.attribute.labels.post_media_sizes_large_resize | Valor copiado diretamente se index != 0 |
| post.media.sizes.large.w | about.resource.attribute.labels.post_media_sizes_large_w | Convertido em string se o índice != 0 |
| post.media.sizes.medium.h | about.resource.attribute.labels.post_media_sizes_medium_h | Convertido em string se o índice != 0 |
| post.media.sizes.medium.resize | about.resource.attribute.labels.post_media_sizes_medium_resize | Valor copiado diretamente se index != 0 |
| post.media.sizes.medium.w | about.resource.attribute.labels.post_media_sizes_medium_w | Convertido em string se o índice != 0 |
| post.media.sizes.small.h | about.resource.attribute.labels.post_media_sizes_small_h | Convertido em string se o índice != 0 |
| post.media.sizes.small.resize | about.resource.attribute.labels.post_media_sizes_small_resize | Valor copiado diretamente se index != 0 |
| post.media.sizes.small.w | about.resource.attribute.labels.post_media_sizes_small_w | Convertido em string se o índice != 0 |
| post.media.sizes.thumb.h | about.resource.attribute.labels.post_media_sizes_thumb_h | Convertido em string se o índice != 0 |
| post.media.sizes.thumb.resize | about.resource.attribute.labels.post_media_sizes_thumb_resize | Valor copiado diretamente se index != 0 |
| post.media.sizes.thumb.w | about.resource.attribute.labels.post_media_sizes_thumb_w | Convertido em string se o índice != 0 |
| post.media.source | about.resource.attribute.labels.post_media_source | Valor copiado diretamente se index != 0 |
| post.media.thumbnail | about.resource.attribute.labels.post_media_thumbnail | Valor copiado diretamente se index != 0 |
| post.media.title | about.resource.attribute.labels.post_media_title | Valor copiado diretamente se index != 0 |
| post.media.url | about.resource.attribute.labels.post_media_url | Valor copiado diretamente se index != 0 |
| post.media.video_info.duration_millis | about.resource.attribute.labels.post_media_video_info_duration_millis | Convertido em string se o índice != 0 |
| post.media.video_info.aspect_ratio | about.resource.attribute.labels.post_media_video_info_aspect_ratio | Concatenado como %{med.video_info.aspect_ratio.0}, %{med.video_info.aspect_ratio.1} se index != 0 |
| post.media.video_info.variants.bitrate | about.resource.attribute.labels.post_media_video_info_variantsbitrate%{var_index} | Convertido em string |
| post.media.video_info.variants.content_type | about.resource.attribute.labels.post_media_video_info_variants_contenttype%{var_index} | Valor copiado diretamente |
| post.media.video_info.variants.url | about.resource.attribute.labels.post_media_video_info_variantsurl%{var_index} | Valor copiado diretamente |
| post.media.type | about.resource.resource_subtype | Valor copiado diretamente se index != 0 |
| post.translatedText | target.labels.post_translatedText | Valor copiado diretamente |
| post.text | target.labels.post_text | Valor copiado diretamente |
| post.timestamp | target.resource.attribute.creation_time | Convertido de ms de época para carimbo de data/hora |
| publisherCategory.color | target.labels.publisherCategory_color | Valor copiado diretamente |
| publisherCategory.name | target.labels.publisherCategory_name | Valor copiado diretamente |
| publisherCategory.shortName | target.labels.publisherCategory_shortName | Valor copiado diretamente |
| relatedTerms.url | principal.labels.relatedTerms_%{terms.text} | Valor copiado diretamente |
| relatedTermsQueryURL | principal.labels.relatedTermsQueryURL | Valor copiado diretamente |
| sect.id | about.labels.sectors_id | Valor copiado diretamente |
| sect.idStr | about.labels.sectors_idStr | Valor copiado diretamente |
| sect.name | about.labels.sectors_name | Valor copiado diretamente |
| sect.retired | about.labels.sectors_retired | Convertido em string |
| sect.topicType | about.labels.sectors_topicType | Valor copiado diretamente |
| source.channels.0 | principal.application | Valor copiado diretamente |
| source.displayName | principal.user.user_display_name | Valor copiado diretamente |
| source.link | principal.url | Valor copiado diretamente |
| source.verified | principal.labels.source_verified | Convertido em string |
| subCaption.bullets.content | about.labels.subCaption_bullets_content | Valor copiado diretamente |
| subCaption.bullets.media | about.labels.subCaption_bullets_media | Valor copiado diretamente |
| subCaption.bullets.source | about.labels.subCaption_bullets_source | Valor copiado diretamente |
| watchlist.id | about.labels.watchlistsMatchedByType_id | Valor copiado diretamente |
| watchlist.externalTopicIds | about.labels.watchlistsMatchedByType_externalTopicIds | Unido de matriz com separador de vírgulas |
| watchlist.name | about.labels.watchlistsMatchedByType_name | Valor copiado diretamente |
| watchlist.type | about.labels.watchlistsMatchedByType_type | Valor copiado diretamente |
| watchlist.userProperties.omnilist | about.labels.watchlistsMatchedByType_userProperties_omnilist | Valor copiado diretamente |
| watchlist.userProperties.uiListType | about.labels.watchlistsMatchedByType_userProperties_uiListType | Valor copiado diretamente |
| watchlist.userProperties.watchlistColor | about.labels.watchlistsMatchedByType_userProperties_watchlistColor | Valor copiado diretamente |
| watchlist.locationGroups.locations.id | about.labels.watchlistsMatchedByTypelocationGroups%{lg_i}_locationsid%{loc_i} | Valor copiado diretamente |
| watchlist.locationGroups.locations.lng | about.labels.watchlistsMatchedByTypelocationGroups%{lg_i}_locationslng%{loc_i} | Convertido em string se lg_i != 0 ou loc_i != 0 |
| watchlist.locationGroups.locations.lat | about.labels.watchlistsMatchedByTypelocationGroups%{lg_i}_locationslat%{loc_i} | Convertido em string se lg_i != 0 ou loc_i != 0 |
| watchlist.locationGroups.locations.name | about.labels.watchlistsMatchedByTypelocationGroups%{lg_i}_locationsname%{loc_i} | O valor é copiado diretamente se lg_i != 0 ou loc_i != 0 |
| watchlist.locationGroups.id | about.labels.watchlistsMatchedByType_locationGroupsid%{lg_i} | Valor copiado diretamente |
| watchlist.locationGroups.name | about.labels.watchlistsMatchedByType_locationGroupsname%{lg_i} | Valor copiado diretamente |
| watchlist.locationGroups.locations.lng | about.location.region_coordinates.longitude | O valor é copiado diretamente se lg_i == 0 e loc_i == 0 |
| watchlist.locationGroups.locations.lat | about.location.region_coordinates.latitude | O valor é copiado diretamente se lg_i == 0 e loc_i == 0 |
| watchlist.locationGroups.locations.name | about.location.name | O valor é copiado diretamente se lg_i == 0 e loc_i == 0 |
| source.entityName | principal.hostname | Valor copiado diretamente |
| metadata.event_type | Definido como "GENERIC_EVENT"; mudado para "SCAN_HOST" se principal_ip ou principal.hostname não estiverem vazios |
Precisa de mais ajuda? Receba respostas de membros da comunidade e profissionais do Google SecOps.