Coletar registros de IOC do MISP

Compatível com:

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

  1. Faça login na UI da Web do MISP como administrador.
  2. Acesse Administração > Listar chaves de autenticação.
  3. Clique em Adicionar chave de autenticação.
  4. 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

  1. Faça login na sua instância do MISP usando SSH.
  2. Instale o PyMISP usando o seguinte comando:

    pip3 install pymisp 
    
  3. 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)
    
  4. 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.
  5. 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.

Receber o arquivo de autenticação de ingestão do Google SecOps

  1. Faça login no console do Google SecOps.
  2. Acesse Configurações do SIEM > Agentes de coleta.
  3. 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

  1. Faça login no console do Google SecOps.
  2. Acesse Configurações do SIEM > Perfil.
  3. 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

  1. Abra um terminal com privilégios de root ou sudo.
  2. 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

  1. 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).
  2. 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.