Coletar registros de IOC do MISP
Este guia descreve as etapas para ingerir registros de IOC (indicadores de comprometimento) do MISP (Plataforma de compartilhamento de informações sobre malware) no Google Security Operations usando o Bindplane. O analisador extrai IOCs de dados do MISP formatados como JSON ou CSV. Ele analisa a entrada, mapeia campos para o Modelo Unificado de Dados (UDM, na sigla em inglês), processa vários tipos de IOCs (como hashes de IP, domínio e arquivo) e enriquece os dados com contexto de inteligência de ameaças, como confiança e gravidade. O analisador também executa lógica específica para diferentes formatos de dados e processa casos com campos ausentes ou não compatíveis.
Antes de começar
Verifique se você tem os pré-requisitos a seguir:
- Instância do Google SecOps
- Host Linux com
systemd
- Se estiver executando por trás de um proxy, as portas do firewall estarão abertas.
- Acesso privilegiado ao seu servidor MISP
Receber chave de API do MISP
- Faça login na UI da Web do MISP como administrador.
- Acesse Administração > Listar chaves de autenticação.
- Clique em Adicionar chave de autenticação.
- Forneça a seguinte configuração de chave:
- Usuário: selecione a conta de usuário associada à chave.
- IPs permitidos: se quiser, especifique os endereços IP permitidos para a chave.
- Copie e salve a chave em um local seguro.
- Clique em Anotei minha chave.
Configurar a exportação de registros do MISP
- Faça login na sua instância do MISP usando SSH.
Instale o PyMISP usando o seguinte comando:
pip3 install pymisp
Modifique o script de exportação
get_csv.py
usando o seguinte:#!/usr/bin/env python3 # -*- coding: utf-8 -*- import argparse from pymisp import ExpandedPyMISP from keys import misp_url, misp_key, misp_verifycert if __name__ == '__main__': parser = argparse.ArgumentParser(description='Get MISP data in a CSV format.') parser.add_argument("--controller", default='attributes', help="Attribute to use for the search (events, objects, attributes)") parser.add_argument("-e", "--event_id", help="Event ID to fetch. Without it, it will fetch the whole database.") parser.add_argument("-a", "--attribute", nargs='+', help="Attribute column names") parser.add_argument("-o", "--object_attribute", nargs='+', help="Object attribute column names") parser.add_argument("-t", "--misp_types", nargs='+', help="MISP types to fetch (ip-src, hostname, ...)") parser.add_argument("-c", "--context", action='store_true', help="Add event level context (tags...)") parser.add_argument("-f", "--outfile", help="Output file to write the CSV.") parser.add_argument("-l", "--last", required=True, help="can be defined in days, hours, minutes (for example 5d or 12h or 30m).") args = parser.parse_args() pymisp = ExpandedPyMISP(misp_url, misp_key, misp_verifycert, debug=True) attr = [] if args.attribute: attr += args.attribute if args.object_attribute: attr += args.object_attribute if not attr: attr = None print(args.context) response = pymisp.search(return_format='csv', controller=args.controller, eventid=args.event_id, requested_attributes=attr, publish_timestamp=args.last, type_attribute=args.misp_types, include_context=args.context) if args.outfile: with open(args.outfile, 'w') as f: f.write(response) else: print(response)
Edite o arquivo
keys.py
para incluir as credenciais e o URL da API MISP, da seguinte forma:misp_url = 'https://<MISP_URL>' misp_key = '<MISP_API_KEY>' misp_verifycert = False misp_client_cert = ''
- Substitua
<MISP_URL>
pelo IP ou nome do host do MISP. - Substitua
<MISP_API_KEY
pela chave de API real gerada anteriormente.
- Substitua
Abra o crontab usando o comando
crontab -e
e insira o seguinte:0 20 * * * python3 /opt/misp/<YOUR_EXPORT_SCRIPT_PATH> -f /opt/misp/ioc_export/url.log -t "url" -l 1d -c 0 20 * * * python3 /opt/misp/<YOUR_EXPORT_SCRIPT_PATH> -f /opt/misp/ioc_export/ip-dst.log -t "ip-dst" -l 1d -c 0 20 * * * python3 /opt/misp/<YOUR_EXPORT_SCRIPT_PATH> -f /opt/misp/ioc_export/ip-src.log -t "ip-src" -l 1d -c 0 20 * * * python3 /opt/misp/<YOUR_EXPORT_SCRIPT_PATH> -f /opt/misp/ioc_export/domain.log -t "domain" -l 1d -c 0 20 * * * python3 /opt/misp/<YOUR_EXPORT_SCRIPT_PATH> -f /opt/misp/ioc_export/sha256.log -t "sha256" -l 1d -c 0 20 * * * python3 /opt/misp/<YOUR_EXPORT_SCRIPT_PATH> -f /opt/misp/ioc_export/file.log -t "filename" -l 1d -c 0 20 * * * python3 /opt/misp/<YOUR_EXPORT_SCRIPT_PATH> -f /opt/misp/ioc_export/registry.log -t "registry" -l 1d -c 0 20 * * * python3 /opt/misp/<YOUR_EXPORT_SCRIPT_PATH> -f /opt/misp/ioc_export/mutex.log -t "mutex" -l 1d -c 0 20 * * * python3 /opt/misp/<YOUR_EXPORT_SCRIPT_PATH> -f /opt/misp/ioc_export/threat-actor.log -t "threat-actor" -l 1d -c
- Atualize
<YOUR_EXPORT_SCRIPT_PATH>
de acordo com o local real do script de exportação.
- Atualize
Receber o arquivo de autenticação de ingestão do Google SecOps
- Faça login no console do Google SecOps.
- Acesse Configurações do SIEM > Agentes de coleta.
- Baixe o arquivo de autenticação de ingestão. Salve o arquivo de forma segura no sistema em que o Bindplane será instalado.
Receber o ID do cliente do Google SecOps
- Faça login no console do Google SecOps.
- Acesse Configurações do SIEM > Perfil.
- Copie e salve o ID do cliente na seção Detalhes da organização.
Instalar o agente do Bindplane no servidor MISP
Instalação do Linux
- Abra um terminal com privilégios de root ou sudo.
Execute este comando:
sudo sh -c "$(curl -fsSlL https://github.com/observiq/bindplane-agent/releases/latest/download/install_unix.sh)" install_unix.sh
Outros recursos de instalação
Para mais opções de instalação, consulte o guia de instalação.
Configurar o agente do Bindplane para ingerir arquivos de registro do MISP e enviar para o Google SecOps
- Acesse o arquivo de configuração:
- Localize o arquivo
config.yaml
. Normalmente, ele fica no diretório/etc/bindplane-agent/
no Linux. - Abra o arquivo usando um editor de texto (por exemplo,
nano
,vi
ou Bloco de Notas).
- Localize o arquivo
Edite o arquivo
config.yaml
da seguinte forma:receivers: filelog: file_path: /opt/misp/ioc_export/*.log log_type: 'file' exporters: chronicle/chronicle_w_labels: compression: gzip # Adjust the path to the credentials file you downloaded in Step 1 creds_file_path: '/path/to/ingestion-authentication-file.json' # Replace with your actual customer ID from Step 2 customer_id: <customer_id> endpoint: malachiteingestion-pa.googleapis.com # Add optional ingestion labels for better organization ingestion_labels: log_type: 'MISP_IOC' raw_log_field: body service: pipelines: logs/source0__chronicle_w_labels-0: receivers: - filelog exporters: - chronicle/chronicle_w_labels
- Substitua a porta e o endereço IP conforme necessário na sua infraestrutura.
- Substitua
<customer_id>
pelo ID de cliente real. - Atualize
/path/to/ingestion-authentication-file.json
para o caminho em que o arquivo de autenticação foi salvo na seção Receber arquivo de autenticação de ingestão do Google SecOps.
Reinicie o agente do Bindplane para aplicar as mudanças
Para reiniciar o agente do Bindplane no Linux, execute o seguinte comando:
sudo systemctl restart bindplane-agent
Tabela de mapeamento da UDM
Campo de registro | Mapeamento do UDM | Lógica |
---|---|---|
Attribute.category |
event.idm.entity.metadata.threat.category_details |
Mapeado diretamente de Attribute.category no objeto JSON aninhado dentro do campo "data". Usado no caminho de análise JSON. |
Attribute.comment |
event.idm.entity.metadata.threat.summary |
Mapeado diretamente de Attribute.comment no objeto JSON aninhado dentro do campo "data". Usado no caminho de análise JSON. |
Attribute.deleted |
event.idm.entity.metadata.threat.detection_fields.value |
Mapeado diretamente de Attribute.deleted e adicionado como um campo de detecção com a chave "Attribute deleted". Usado no caminho de análise JSON. |
Attribute.event_id |
event.idm.entity.metadata.threat.detection_fields.value |
Mapeado diretamente de Attribute.event_id e adicionado como um campo de detecção com a chave "Attribute event_id". Usado no caminho de análise JSON. |
Attribute.first_seen |
event.idm.entity.metadata.threat.detection_fields.value |
Mapeado diretamente de Attribute.first_seen e adicionado como um campo de detecção com a chave "Attribute first_seen". Usado no caminho de análise JSON. |
Attribute.id |
event.idm.entity.metadata.threat.detection_fields.value |
Mapeado diretamente de Attribute.id e adicionado como um campo de detecção com a chave "Attribute id" ou "Attribute id $$", dependendo do caminho de análise. Usado nos caminhos de análise CSV e JSON. |
Attribute.timestamp |
event.idm.entity.metadata.threat.detection_fields.value |
Mapeado diretamente de Attribute.timestamp e adicionado como um campo de detecção com a chave "Timestamp do atributo". Usado no caminho de análise JSON. |
Attribute.to_ids |
event.idm.entity.metadata.threat.detection_fields.value |
Mapeado diretamente de Attribute.to_ids e adicionado como um campo de detecção com a chave "Attribute to_ids". Usado no caminho de análise JSON. |
Attribute.type |
log_type |
Mapeado diretamente de Attribute.type no objeto JSON aninhado dentro do campo "data". Usado como um campo provisório e, mais tarde, para preencher outros campos da UDM. Usado no caminho de análise JSON. |
Attribute.uuid |
event.idm.entity.metadata.product_entity_id |
Mapeado diretamente de Attribute.uuid no objeto JSON aninhado dentro do campo "data". Usado no caminho de análise JSON. |
Attribute.value |
Várias | O valor desse campo é usado para preencher vários campos do UDM, dependendo do Attribute.type (ou log_type , se derivado de Attribute.type ):- event.idm.entity.entity.hostname se type for "domain".- event.idm.entity.entity.file.md5 se type for "md5".- event.idm.entity.entity.file.sha1 se type for "sha1".- event.idm.entity.entity.file.sha256 se type for "sha256".- event.idm.entity.entity.resource.name se type for "mutex".- event.idm.entity.entity.registry.registry_key se type for "regkey".- event.idm.entity.entity.user.email_addresses se type for "threat-actor".: event.idm.entity.entity.url se type for uri ou url .- event.idm.entity.entity.file.full_path se type for "filename".: analisado para IP e porta se type for "ip-dst|port", "ip-dst" ou "ip-src". Usado no caminho de análise JSON. |
column1 |
event.idm.entity.metadata.product_entity_id |
Mapeado diretamente de column1 no caminho de análise do CSV. |
column14 |
Parte de event.idm.entity.metadata.threat.description |
Concatenado com description para formar a descrição final nos metadados da ameaça. Usado no caminho de análise de CSV. |
column16 |
event.idm.entity.metadata.threat.threat_feed_name , event.ioc.feed_name |
Mapeado diretamente de column16 . Usado no caminho de análise de CSV. |
column18 |
event.idm.entity.metadata.threat.severity_details , event.ioc.raw_severity |
Mapeado diretamente de column18 . Usado no caminho de análise de CSV. |
column21 |
Parte de event.idm.entity.metadata.threat.description , event.ioc.description |
Usado como base para a descrição, concatenado posteriormente com event_info . Usado no caminho de análise de CSV. |
column3 |
Parte de event.ioc.categorization |
Mapeado diretamente de column3 e concatenado com "IOCs" para formar a categorização final. Usado no caminho de análise de CSV. |
column4 |
event.idm.entity.metadata.description |
Mapeado diretamente de column4 . Usado no caminho de análise de CSV. |
column5 |
Várias | O valor desse campo é usado para preencher vários campos do UDM, dependendo do campo column4 (que é mapeado para type ):- event.idm.entity.entity.hostname se type for "domain".: analisado para IP e porta se type for "ip-dst|port", "ip-dst" ou "ip-src".- event.idm.entity.entity.file.md5 se type for "md5".- event.idm.entity.entity.file.sha1 se type for "sha1".- event.idm.entity.entity.file.sha256 se type for "sha256".- event.idm.entity.entity.resource.name se type for "mutex".- event.idm.entity.entity.registry.registry_key se type for "regkey".- event.idm.entity.entity.user.email_addresses se type for "threat-actor".: event.idm.entity.entity.url se type for uri ou url .- event.idm.entity.entity.file.full_path se type for "filename". Usado no caminho de análise de CSV. |
column6 |
event.idm.entity.metadata.threat.summary |
Mapeado diretamente de column6 . Usado no caminho de análise de CSV. |
column8 |
event.ioc.active_timerange.start , event.idm.entity.metadata.interval.start_time |
Analisado como um carimbo de data/hora UNIX. Usado no caminho de análise de CSV. |
date description |
event.idm.entity.metadata.threat.description |
Mapeado diretamente de description no objeto JSON aninhado dentro do campo "data". Usado no caminho de análise JSON. |
event_creator_email |
event.idm.entity.entity.labels.value |
Mapeado diretamente de event_creator_email e adicionado como um rótulo com a chave "event_creator_email". Usado no caminho de análise JSON. |
event_id Feed.publish |
event.idm.entity.metadata.threat.detection_fields.value |
Mapeado diretamente de Feed.publish e adicionado como um campo de detecção com a chave "Publicação do feed". Usado no caminho de análise JSON. |
first_seen |
event.ioc.active_timerange.start , event.idm.entity.metadata.interval.start_time |
Analisado como um carimbo de data/hora no formato "aaaa-MM-ddTHH:mm:ssZZ". Usado no caminho de análise JSON. |
id info |
event.idm.entity.metadata.description |
Mapeado diretamente de info no objeto JSON aninhado dentro do campo "data". Usado no caminho de análise JSON. |
last_seen |
event.ioc.active_timerange.end |
Analisado como um carimbo de data/hora no formato "aaaa-MM-ddTHH:mm:ssZZ". Usado no caminho de análise JSON. |
Org.name |
event.idm.entity.metadata.threat.detection_fields.value |
Mapeado diretamente de Org.name e adicionado como um campo de detecção com a chave "Nome da organização". Usado no caminho de análise JSON. |
published |
event.idm.entity.metadata.threat.detection_fields.value |
Mapeado diretamente de published e adicionado como um campo de detecção com a chave "published". Usado no caminho de análise JSON. |
Tag.colour |
event.idm.entity.metadata.threat.detection_fields.value |
Mapeado diretamente de Tag.colour e adicionado como um campo de detecção com a chave "tag colour". Usado no caminho de análise JSON. |
Tag.exportable |
event.idm.entity.metadata.threat.detection_fields.value |
Mapeado diretamente de Tag.exportable e adicionado como um campo de detecção com a chave "tag exportable". Usado no caminho de análise JSON. |
Tag.hide_tag |
event.idm.entity.metadata.threat.detection_fields.value |
Mapeado diretamente de Tag.hide_tag e adicionado como um campo de detecção com a chave "tag hide_tag". Usado no caminho de análise JSON. |
Tag.id |
event.idm.entity.metadata.threat.detection_fields.value |
Mapeado diretamente de Tag.id e adicionado como um campo de detecção com a chave "tag id". Usado no caminho de análise JSON. |
Tag.is_custom_galaxy |
event.idm.entity.metadata.threat.detection_fields.value |
Mapeado diretamente de Tag.is_custom_galaxy e adicionado como um campo de detecção com a chave "tag is_custom_galaxy". Usado no caminho de análise JSON. |
Tag.is_galaxy |
event.idm.entity.metadata.threat.detection_fields.value |
Mapeado diretamente de Tag.is_galaxy e adicionado como um campo de detecção com a chave "tag is_galaxy". Usado no caminho de análise JSON. |
Tag.isinherited |
event.idm.entity.metadata.threat.detection_fields.value |
Mapeado diretamente de Tag.isinherited e adicionado como um campo de detecção com a chave "tag isinherited". Usado no caminho de análise JSON. |
Tag.name |
event.idm.entity.metadata.threat.detection_fields.value |
Mapeado diretamente de Tag.name e adicionado como um campo de detecção com a chave "tag name". Usado no caminho de análise JSON. |
Tag.numerical_value |
event.idm.entity.metadata.threat.detection_fields.value |
Mapeado diretamente de Tag.numerical_value e adicionado como um campo de detecção com a chave "tag numerical_value". Usado no caminho de análise JSON. |
Tag.user_id |
event.idm.entity.metadata.threat.detection_fields.value |
Mapeado diretamente de Tag.user_id e adicionado como um campo de detecção com a chave "tag user_id". Usado no caminho de análise JSON. |
threat_level_id |
event.idm.entity.entity.labels.value |
Mapeado diretamente de threat_level_id e adicionado como um rótulo com a chave "threat_level_id". Usado no caminho de análise JSON. |
timestamp |
event.idm.entity.metadata.collected_timestamp , event.idm.entity.metadata.interval.start_time |
Analisado como um carimbo de data/hora UNIX. Usado no caminho de análise de CSV. |
uuid |
event.idm.entity.metadata.vendor_name |
Definido como "MISP" pelo analisador. Definido como "MISP" pelo analisador. Definido como um valor padrão muito no futuro (253402300799 segundos desde a época). Determinado pelo analisador com base no campo type ou log_type . Pode ser "FILE", "DOMAIN_NAME", "IP_ADDRESS", "MUTEX", "RESOURCE" ou "USER". Pode ser derivado de Attribute.comment ou Attribute.value , dependendo do Attribute.type . Analisado de Attribute.value ou column5 se o tipo estiver relacionado a IP. Analisado de Attribute.value ou column5 se o tipo for "ip-dst|port". Derivado de column3 na análise de CSV ou Attribute.category na análise de JSON. Derivado de column21 e column14 na análise de CSV. Derivado de column8 ou first_seen . Derivado de last_seen . Derivado de description usando um padrão grok. Derivado de column16 ou definido como "MISP". Derivado de column18 . Analisado de Attribute.value ou column5 se o tipo estiver relacionado a IP. Analisado de Attribute.value ou column5 se o tipo for "ip-dst|port". Derivado de Attribute.value ou column5 se o tipo for "domain". Derivado do campo confidence , que é extraído do campo description . Os valores podem ser "HIGH_CONFIDENCE", "MEDIUM_CONFIDENCE", "LOW_CONFIDENCE" ou "UNKNOWN_CONFIDENCE". Mapeado diretamente do campo confidence , que é extraído do campo description . Mapeado diretamente do campo threat_level , que é derivado de column18 no caminho de análise do CSV. Mapeado diretamente do campo feed_name , que é derivado de column16 no caminho de análise do CSV. Derivado de column21 e column14 na análise de CSV. Derivado de column6 na análise de CSV ou Attribute.comment na análise de JSON. Vários campos são adicionados como campos de detecção com as chaves correspondentes. Vários campos são adicionados como rótulos com as chaves correspondentes. Copiado do campo timestamp de nível superior no registro bruto. |
Precisa de mais ajuda? Receba respostas de membros da comunidade e profissionais do Google SecOps.