Recolha registos de IOCs do MISP

Compatível com:

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

  1. Inicie sessão na IU Web do MISP como administrador.
  2. Aceda a Administração > Listar chaves de autorização.
  3. Clique em Adicionar chave de autenticação.
  4. 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

  1. Inicie sessão na sua instância do MISP através do SSH.
  2. Instale o PyMISP com o seguinte comando:

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

Obtenha o ficheiro de autenticação de carregamento do Google SecOps

  1. Inicie sessão na consola Google SecOps.
  2. Aceda a Definições do SIEM > Agentes de recolha.
  3. 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

  1. Inicie sessão na consola Google SecOps.
  2. Aceda a Definições do SIEM > Perfil.
  3. 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

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

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

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.