Recolha registos de IOCs do MISP
Este guia descreve os passos para carregar registos de IOC (Indicadores de comprometimento) da MISP (Malware Information Sharing Platform) para o Google Security Operations através do Bindplane. O analisador extrai IOCs de dados MISP formatados como JSON ou CSV. Analisa a entrada, mapeia os campos para o modelo de dados unificado (UDM), processa vários tipos de IOCs (como hashes de IP, domínio e ficheiros) e enriquece os dados com o contexto de informações sobre ameaças, como a confiança e a gravidade. O analisador também executa uma lógica específica para diferentes formatos de dados e processa casos com campos em falta ou não suportados.
Antes de começar
Certifique-se de que tem os seguintes pré-requisitos:
- Instância do Google SecOps
- Anfitrião Linux com
systemd
- Se estiver a ser executado através de um proxy, as portas da firewall estão abertas
- Acesso privilegiado ao seu servidor MISP
Obtenha a chave da API MISP
- Inicie sessão na IU Web do MISP como administrador.
- Aceda a Administração > Listar chaves de autorização.
- Clique em Adicionar chave de autenticação.
- Faculte a seguinte configuração de chave:
- Utilizador: selecione a conta de utilizador associada à chave.
- IPs permitidos: opcionalmente, pode especificar endereços IP permitidos para a chave.
- Copie e guarde a chave num local seguro.
- Clique em Tomei nota da minha chave.
Configure a exportação de registos do MISP
- Inicie sessão na sua instância do MISP através do SSH.
Instale o PyMISP com o seguinte comando:
pip3 install pymisp
Modifique o script de exportação
get_csv.py
com 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 ficheiro
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 seu IP ou nome de anfitrião do MISP. - Substitua
<MISP_API_KEY
pela chave da API real gerada anteriormente.
- Substitua
Abra o crontab com o comando
crontab -e
e introduza 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 a localização real do script de exportação.
- Atualize
Obtenha o ficheiro de autenticação de carregamento do Google SecOps
- Inicie sessão na consola Google SecOps.
- Aceda a Definições do SIEM > Agentes de recolha.
- Transfira o ficheiro de autenticação de carregamento. Guarde o ficheiro de forma segura no sistema onde o Bindplane vai ser instalado.
Obtenha o ID de cliente do Google SecOps
- Inicie sessão na consola Google SecOps.
- Aceda a Definições do SIEM > Perfil.
- Copie e guarde o ID do cliente da secção Detalhes da organização.
Instale o agente do Bindplane no servidor MISP
Instalação do Linux
- Abra um terminal com privilégios de raiz ou sudo.
Execute o seguinte comando:
sudo sh -c "$(curl -fsSlL https://github.com/observiq/bindplane-agent/releases/latest/download/install_unix.sh)" install_unix.sh
Recursos de instalação adicionais
Para ver opções de instalação adicionais, consulte o guia de instalação.
Configure o agente Bindplane para carregar ficheiros de registo MISP e enviá-los para o Google SecOps
- Aceda ao ficheiro de configuração:
- Localize o ficheiro
config.yaml
. Normalmente, encontra-se no diretório/etc/bindplane-agent/
no Linux. - Abra o ficheiro com um editor de texto (por exemplo,
nano
,vi
ou Bloco de notas).
- Localize o ficheiro
Edite o ficheiro
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 onde o ficheiro de autenticação foi guardado na secção Obtenha o ficheiro de autenticação de carregamento do Google SecOps.
Reinicie o agente do Bindplane para aplicar as alterações
Para reiniciar o agente do Bindplane no Linux, execute o seguinte comando:
sudo systemctl restart bindplane-agent
Tabela de mapeamento do UDM
Campo de registo | Mapeamento de UDM | Lógica |
---|---|---|
Attribute.category |
event.idm.entity.metadata.threat.category_details |
Mapeado diretamente de Attribute.category no objeto JSON aninhado no 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 no campo "data". Usado no caminho de análise JSON. |
Attribute.deleted |
event.idm.entity.metadata.threat.detection_fields.value |
Mapeado diretamente a partir de Attribute.deleted e adicionado como um campo de deteçã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 a partir de Attribute.event_id e adicionado como um campo de deteçã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 a partir de Attribute.first_seen e adicionado como um campo de deteçã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 deteção com a chave "Attribute id" ou "Attribute id $$", consoante o caminho de análise. Usado em caminhos de análise CSV e JSON. |
Attribute.timestamp |
event.idm.entity.metadata.threat.detection_fields.value |
Mapeado diretamente a partir de Attribute.timestamp e adicionado como um campo de deteção com a chave "Attribute timestamp". Usado no caminho de análise JSON. |
Attribute.to_ids |
event.idm.entity.metadata.threat.detection_fields.value |
Mapeado diretamente a partir de Attribute.to_ids e adicionado como um campo de deteçã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 no campo "data". Usado como um campo provisório e, posteriormente, usado para preencher outros campos do 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 no campo "data". Usado no caminho de análise JSON. |
Attribute.value |
Vários | O valor deste campo é usado para preencher vários campos UDM, consoante o 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 CSV. |
column14 |
Parte de event.idm.entity.metadata.threat.description |
Concatenado com description para formar a descrição final nos metadados de ameaças. Usado no caminho de análise CSV. |
column16 |
event.idm.entity.metadata.threat.threat_feed_name , event.ioc.feed_name |
Mapeado diretamente a partir de column16 . Usado no caminho de análise CSV. |
column18 |
event.idm.entity.metadata.threat.severity_details , event.ioc.raw_severity |
Mapeado diretamente a partir de column18 . Usado no caminho de análise 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 CSV. |
column3 |
Parte de event.ioc.categorization |
Mapeado diretamente a partir de column3 e concatenado com "IOCs" para formar a categorização final. Usado no caminho de análise CSV. |
column4 |
event.idm.entity.metadata.description |
Mapeado diretamente a partir de column4 . Usado no caminho de análise CSV. |
column5 |
Vários | O valor deste campo é usado para preencher vários campos UDM, consoante o 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 CSV. |
column6 |
event.idm.entity.metadata.threat.summary |
Mapeado diretamente a partir de column6 . Usado no caminho de análise CSV. |
column8 |
event.ioc.active_timerange.start , event.idm.entity.metadata.interval.start_time |
Analisado como uma data/hora Unix. Usado no caminho de análise CSV. |
date description |
event.idm.entity.metadata.threat.description |
Mapeado diretamente de description no objeto JSON aninhado no campo "data". Usado no caminho de análise JSON. |
event_creator_email |
event.idm.entity.entity.labels.value |
Mapeado diretamente a partir de event_creator_email e adicionado como uma etiqueta 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 a partir de Feed.publish e adicionado como um campo de deteção com a chave "Publicação de feeds". Usado no caminho de análise JSON. |
first_seen |
event.ioc.active_timerange.start , event.idm.entity.metadata.interval.start_time |
Analisado como uma 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 no campo "data". Usado no caminho de análise JSON. |
last_seen |
event.ioc.active_timerange.end |
Analisado como uma 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 a partir de Org.name e adicionado como um campo de deteçã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 a partir de published e adicionado como um campo de deteção com a chave "published". Usado no caminho de análise JSON. |
Tag.colour |
event.idm.entity.metadata.threat.detection_fields.value |
Mapeado diretamente a partir de Tag.colour e adicionado como um campo de deteção com a chave "cor da etiqueta". Usado no caminho de análise JSON. |
Tag.exportable |
event.idm.entity.metadata.threat.detection_fields.value |
Mapeado diretamente a partir de Tag.exportable e adicionado como um campo de deteçã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 a partir de Tag.hide_tag e adicionado como um campo de deteçã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 a partir de Tag.id e adicionado como um campo de deteção com a chave "ID da etiqueta". Usado no caminho de análise JSON. |
Tag.is_custom_galaxy |
event.idm.entity.metadata.threat.detection_fields.value |
Mapeado diretamente a partir de Tag.is_custom_galaxy e adicionado como um campo de deteçã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 a partir de Tag.is_galaxy e adicionado como um campo de deteçã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 a partir de Tag.isinherited e adicionado como um campo de deteçã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 deteção com a chave "nome da etiqueta". Usado no caminho de análise JSON. |
Tag.numerical_value |
event.idm.entity.metadata.threat.detection_fields.value |
Mapeado diretamente a partir de Tag.numerical_value e adicionado como um campo de deteçã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 a partir de Tag.user_id e adicionado como um campo de deteçã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 a partir de threat_level_id e adicionado como uma etiqueta 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 uma data/hora Unix. Usado no caminho de análise CSV. |
uuid |
event.idm.entity.metadata.vendor_name |
Definido como "MISP" pelo analisador. Definido como "MISP" pelo analisador. Definido para um valor predefinido muito no futuro (253402300799 segundos desde epoch). 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 , consoante o Attribute.type . Analisado a partir de Attribute.value ou column5 se o tipo estiver relacionado com o IP. Analisado a partir de Attribute.value ou column5 se o tipo for "ip-dst|port". Derivado de column3 na análise CSV ou Attribute.category na análise JSON. Derivado de column21 e column14 na análise CSV. Derivados de column8 ou first_seen . Derivado de last_seen . Derivada de description através de um padrão grok. Derivado de column16 ou definido como "MISP". Derivado de column18 . Analisado a partir de Attribute.value ou column5 se o tipo estiver relacionado com o IP. Analisado a partir de Attribute.value ou column5 se o tipo for "ip-dst|port". Derivado de Attribute.value ou column5 se o tipo for "domínio". 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 a partir do campo confidence , que é extraído do campo description . Mapeado diretamente a partir do campo threat_level , que é derivado de column18 no caminho de análise CSV. Mapeado diretamente a partir do campo feed_name , que é derivado de column16 no caminho de análise CSV. Derivado de column21 e column14 na análise CSV. Derivado de column6 na análise CSV ou Attribute.comment na análise JSON. São adicionados vários campos como campos de deteção com as respetivas chaves. Vários campos são adicionados como etiquetas com as respetivas chaves. Copiado do campo timestamp de nível superior no registo não processado. |
Precisa de mais ajuda? Receba respostas de membros da comunidade e profissionais da Google SecOps.