Recopila registros de IOC de MISP

Compatible con:

En esta guía, se describen los pasos para transferir los registros de IOC (indicadores de compromiso) de MISP (plataforma de intercambio de información sobre software malicioso) a Google Security Operations con Bindplane. El analizador extrae los IOC de los datos de MISP con formato JSON o CSV. Analiza la entrada, asigna campos al modelo de datos unificado (UDM), controla varios tipos de IOC (como IP, dominio y hashes de archivos) y enriquece los datos con el contexto de inteligencia de amenazas, como la confianza y la gravedad. El analizador también realiza una lógica específica para diferentes formatos de datos y controla los casos con campos faltantes o no compatibles.

Antes de comenzar

Asegúrate de cumplir con los siguientes requisitos previos:

  • Instancia de Google SecOps
  • Host de Linux con systemd
  • Si se ejecuta detrás de un proxy, los puertos del firewall están abiertos.
  • Acceso con privilegios a tu servidor de MISP

Obtén la clave de API de MISP

  1. Accede a la IU web de MISP como administrador.
  2. Ve a Administración > List Auth Keys.
  3. Haz clic en Agregar clave de autenticación.
  4. Proporciona la siguiente configuración de claves:
    • Usuario: Selecciona la cuenta de usuario asociada con la clave.
    • IPs permitidas: De forma opcional, puedes especificar las direcciones IP permitidas para la clave.
    • Copia y guarda la clave en una ubicación segura.
    • Haz clic en Anoté mi clave.

Configura la exportación de registros de MISP

  1. Accede a tu instancia de MISP con SSH.
  2. Instala PyMISP con el siguiente comando:

    pip3 install pymisp 
    
  3. Modifica la secuencia de comandos de exportación get_csv.py con lo siguiente:

    #!/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)
    
    1. Edita el archivo keys.py para incluir las credenciales y la URL de la API de MISP:
    misp_url = 'https://<MISP_URL>'
    misp_key = '<MISP_API_KEY>'
    misp_verifycert = False
    misp_client_cert = ''
    
    • Reemplaza <MISP_URL> por la IP o el nombre de host de MISP.
    • Reemplaza <MISP_API_KEY por la clave de API real que se generó antes.
  4. Abre crontab con el comando crontab -e y, luego, ingresa lo siguiente:

    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
    
    • Actualiza <YOUR_EXPORT_SCRIPT_PATH> según la ubicación real de la secuencia de comandos de exportación.

Obtén el archivo de autenticación de transferencia de Google SecOps

  1. Accede a la consola de Google SecOps.
  2. Ve a Configuración de SIEM > Agentes de recopilación.
  3. Descarga el archivo de autenticación de transferencia. Guarda el archivo de forma segura en el sistema en el que se instalará Bindplane.

Obtén el ID de cliente de Google SecOps

  1. Accede a la consola de Google SecOps.
  2. Ve a Configuración de SIEM > Perfil.
  3. Copia y guarda el ID de cliente de la sección Detalles de la organización.

Instala el agente de Bindplane en el servidor de MISP

Instalación de Linux

  1. Abre una terminal con privilegios de raíz o sudo.
  2. Ejecuta el siguiente comando:

    sudo sh -c "$(curl -fsSlL https://github.com/observiq/bindplane-agent/releases/latest/download/install_unix.sh)" install_unix.sh
    

Recursos de instalación adicionales

Para obtener más opciones de instalación, consulta la guía de instalación.

Configura el agente de Bindplane para transferir los archivos de registro de MISP y enviarlos a Google SecOps

  1. Accede al archivo de configuración:
    • Ubica el archivo config.yaml. Por lo general, se encuentra en el directorio /etc/bindplane-agent/ en Linux.
    • Abre el archivo con un editor de texto (por ejemplo, nano, vi o Bloc de notas).
  2. Edita el archivo config.yaml de la siguiente manera:

    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
    
    • Reemplaza el puerto y la dirección IP según sea necesario en tu infraestructura.
    • Reemplaza <customer_id> por el ID de cliente real.
    • Actualiza /path/to/ingestion-authentication-file.json a la ruta de acceso en la que se guardó el archivo de autenticación en la sección Obtén el archivo de autenticación de transferencia de Google SecOps.

Reinicia el agente de Bindplane para aplicar los cambios.

Para reiniciar el agente de Bindplane en Linux, ejecuta el siguiente comando:

  sudo systemctl restart bindplane-agent

Tabla de asignación de la UDM

Campo de registro Asignación de UDM Lógica
Attribute.category event.idm.entity.metadata.threat.category_details Se asigna directamente desde Attribute.category en el objeto JSON anidado dentro del campo "data". Se usa en la ruta de análisis de JSON.
Attribute.comment event.idm.entity.metadata.threat.summary Se asigna directamente desde Attribute.comment en el objeto JSON anidado dentro del campo "data". Se usa en la ruta de análisis de JSON.
Attribute.deleted event.idm.entity.metadata.threat.detection_fields.value Se asignó directamente desde Attribute.deleted y se agregó como un campo de detección con la clave "Attribute deleted". Se usa en la ruta de análisis de JSON.
Attribute.event_id event.idm.entity.metadata.threat.detection_fields.value Se asigna directamente desde Attribute.event_id y se agrega como un campo de detección con la clave "Attribute event_id". Se usa en la ruta de análisis de JSON.
Attribute.first_seen event.idm.entity.metadata.threat.detection_fields.value Se asigna directamente desde Attribute.first_seen y se agrega como un campo de detección con la clave "Attribute first_seen". Se usa en la ruta de análisis de JSON.
Attribute.id event.idm.entity.metadata.threat.detection_fields.value Se asignan directamente desde Attribute.id y se agregan como un campo de detección con la clave "Attribute id" o "Attribute id $$", según la ruta de análisis. Se usa en las rutas de análisis de CSV y JSON.
Attribute.timestamp event.idm.entity.metadata.threat.detection_fields.value Se asigna directamente desde Attribute.timestamp y se agrega como un campo de detección con la clave "Attribute timestamp". Se usa en la ruta de análisis de JSON.
Attribute.to_ids event.idm.entity.metadata.threat.detection_fields.value Se asignó directamente desde Attribute.to_ids y se agregó como un campo de detección con la clave "Attribute to_ids". Se usa en la ruta de análisis de JSON.
Attribute.type log_type Se asigna directamente desde Attribute.type en el objeto JSON anidado dentro del campo "data". Se usa como campo provisional y, más adelante, para propagar otros campos de la AUA. Se usa en la ruta de análisis de JSON.
Attribute.uuid event.idm.entity.metadata.product_entity_id Se asigna directamente desde Attribute.uuid en el objeto JSON anidado dentro del campo "data". Se usa en la ruta de análisis de JSON.
Attribute.value Varias El valor de este campo se usa para propagar varios campos del UDM según el Attribute.type (o log_type si se deriva de Attribute.type):
: event.idm.entity.entity.hostname si type es "domain".
: event.idm.entity.entity.file.md5 si type es "md5".
: event.idm.entity.entity.file.sha1 si type es "sha1".
: event.idm.entity.entity.file.sha256 si type es "sha256".
: event.idm.entity.entity.resource.name si type es "mutex".
: event.idm.entity.entity.registry.registry_key si type es "regkey".
: event.idm.entity.entity.user.email_addresses si type es “threat-actor”.
: event.idm.entity.entity.url si type es uri o url.
: event.idm.entity.entity.file.full_path si type es "filename".
: Se analiza para obtener la IP y el puerto si type es "ip-dst|port", "ip-dst" o "ip-src". Se usa en la ruta de análisis de JSON.
column1 event.idm.entity.metadata.product_entity_id Se asigna directamente desde column1 en la ruta de análisis de CSV.
column14 Parte de event.idm.entity.metadata.threat.description Se concatena con description para formar la descripción final en los metadatos de amenazas. Se usa en la ruta de análisis de CSV.
column16 event.idm.entity.metadata.threat.threat_feed_name, event.ioc.feed_name Se asigna directamente desde column16. Se usa en la ruta de análisis de CSV.
column18 event.idm.entity.metadata.threat.severity_details, event.ioc.raw_severity Se asigna directamente desde column18. Se usa en la ruta de análisis de CSV.
column21 Parte de event.idm.entity.metadata.threat.description, event.ioc.description Se usa como base para la descripción y, luego, se concatena con event_info. Se usa en la ruta de análisis de CSV.
column3 Parte de event.ioc.categorization Se asignan directamente desde column3 y se concatenan con "IOC" para formar la categorización final. Se usa en la ruta de análisis de CSV.
column4 event.idm.entity.metadata.description Se asigna directamente desde column4. Se usa en la ruta de análisis de CSV.
column5 Varias El valor de este campo se usa para propagar varios campos del UDM según el campo column4 (que se asigna a type):
: event.idm.entity.entity.hostname si type es "domain".
: Se analiza para obtener la IP y el puerto si type es "ip-dst|port", "ip-dst" o "ip-src".
: event.idm.entity.entity.file.md5 si type es "md5".
: event.idm.entity.entity.file.sha1 si type es "sha1".
: event.idm.entity.entity.file.sha256 si type es "sha256".
: event.idm.entity.entity.resource.name si type es "mutex".
: event.idm.entity.entity.registry.registry_key si type es "regkey".
: event.idm.entity.entity.user.email_addresses si type es “threat-actor”.
: event.idm.entity.entity.url si type es uri o url.
: event.idm.entity.entity.file.full_path si type es "filename". Se usa en la ruta de análisis de CSV.
column6 event.idm.entity.metadata.threat.summary Se asigna directamente desde column6. Se usa en la ruta de análisis de CSV.
column8 event.ioc.active_timerange.start, event.idm.entity.metadata.interval.start_time Se analiza como una marca de tiempo UNIX. Se usa en la ruta de análisis de CSV.
date description event.idm.entity.metadata.threat.description Se asigna directamente desde description en el objeto JSON anidado dentro del campo "data". Se usa en la ruta de análisis de JSON.
event_creator_email event.idm.entity.entity.labels.value Se asigna directamente desde event_creator_email y se agrega como etiqueta con la clave "event_creator_email". Se usa en la ruta de análisis de JSON.
event_id Feed.publish event.idm.entity.metadata.threat.detection_fields.value Se asigna directamente desde Feed.publish y se agrega como un campo de detección con la clave "Publicación de feeds". Se usa en la ruta de análisis de JSON.
first_seen event.ioc.active_timerange.start, event.idm.entity.metadata.interval.start_time Se analiza como una marca de tiempo en el formato “aaaa-MM-ddThh:mm:ssZZ”. Se usa en la ruta de análisis de JSON.
id info event.idm.entity.metadata.description Se asigna directamente desde info en el objeto JSON anidado dentro del campo "data". Se usa en la ruta de análisis de JSON.
last_seen event.ioc.active_timerange.end Se analiza como una marca de tiempo en el formato “aaaa-MM-ddThh:mm:ssZZ”. Se usa en la ruta de análisis de JSON.
Org.name event.idm.entity.metadata.threat.detection_fields.value Se asignó directamente desde Org.name y se agregó como un campo de detección con la clave "Nombre de la organización". Se usa en la ruta de análisis de JSON.
published event.idm.entity.metadata.threat.detection_fields.value Se asigna directamente desde published y se agrega como un campo de detección con la clave "published". Se usa en la ruta de análisis de JSON.
Tag.colour event.idm.entity.metadata.threat.detection_fields.value Se asignó directamente desde Tag.colour y se agregó como un campo de detección con la clave "tag color". Se usa en la ruta de análisis de JSON.
Tag.exportable event.idm.entity.metadata.threat.detection_fields.value Se asigna directamente desde Tag.exportable y se agrega como un campo de detección con la clave "tag exportable". Se usa en la ruta de análisis de JSON.
Tag.hide_tag event.idm.entity.metadata.threat.detection_fields.value Se asigna directamente desde Tag.hide_tag y se agrega como un campo de detección con la clave "tag hide_tag". Se usa en la ruta de análisis de JSON.
Tag.id event.idm.entity.metadata.threat.detection_fields.value Se asigna directamente desde Tag.id y se agrega como un campo de detección con la clave "tag id". Se usa en la ruta de análisis de JSON.
Tag.is_custom_galaxy event.idm.entity.metadata.threat.detection_fields.value Se asignó directamente desde Tag.is_custom_galaxy y se agregó como un campo de detección con la clave "tag is_custom_galaxy". Se usa en la ruta de análisis de JSON.
Tag.is_galaxy event.idm.entity.metadata.threat.detection_fields.value Se asigna directamente desde Tag.is_galaxy y se agrega como un campo de detección con la clave "tag is_galaxy". Se usa en la ruta de análisis de JSON.
Tag.isinherited event.idm.entity.metadata.threat.detection_fields.value Se asigna directamente desde Tag.isinherited y se agrega como un campo de detección con la clave "tag isinherited". Se usa en la ruta de análisis de JSON.
Tag.name event.idm.entity.metadata.threat.detection_fields.value Se asigna directamente desde Tag.name y se agrega como un campo de detección con la clave "nombre de la etiqueta". Se usa en la ruta de análisis de JSON.
Tag.numerical_value event.idm.entity.metadata.threat.detection_fields.value Se asigna directamente desde Tag.numerical_value y se agrega como un campo de detección con la clave "tag numerical_value". Se usa en la ruta de análisis de JSON.
Tag.user_id event.idm.entity.metadata.threat.detection_fields.value Se asigna directamente desde Tag.user_id y se agrega como un campo de detección con la clave "tag user_id". Se usa en la ruta de análisis de JSON.
threat_level_id event.idm.entity.entity.labels.value Se asigna directamente desde threat_level_id y se agrega como una etiqueta con la clave "threat_level_id". Se usa en la ruta de análisis de JSON.
timestamp event.idm.entity.metadata.collected_timestamp, event.idm.entity.metadata.interval.start_time Se analiza como una marca de tiempo UNIX. Se usa en la ruta de análisis de CSV.
uuid event.idm.entity.metadata.vendor_name El analizador lo establece en “MISP”. El analizador lo establece en “MISP”. Se establece en un valor predeterminado muy lejano en el futuro (253402300799 segundos desde la época). El analizador lo determina en función del campo type o log_type. Puede ser “FILE”, “DOMAIN_NAME”, “IP_ADDRESS”, “MUTEX”, “RESOURCE” o “USER”. Se puede derivar de Attribute.comment o Attribute.value según el Attribute.type. Se analiza a partir de Attribute.value o column5 si el tipo está relacionado con la IP. Se analiza desde Attribute.value o column5 si el tipo es "ip-dst|port". Se deriva de column3 en el análisis de CSV o de Attribute.category en el análisis de JSON. Se deriva de column21 y column14 en el análisis de CSV. Se deriva de column8 o first_seen. Derivado de last_seen. Se deriva de description con un patrón grok. Se deriva de column16 o se establece en "MISP". Derivado de column18. Se analiza a partir de Attribute.value o column5 si el tipo está relacionado con la IP. Se analiza desde Attribute.value o column5 si el tipo es "ip-dst|port". Se deriva de Attribute.value o column5 si el tipo es "domain". Se deriva del campo confidence, que se extrae del campo description. Los valores pueden ser "HIGH_CONFIDENCE", "MEDIUM_CONFIDENCE", "LOW_CONFIDENCE" o "UNKNOWN_CONFIDENCE". Se asigna directamente desde el campo confidence, que se extrae del campo description. Se asigna directamente desde el campo threat_level, que se deriva de column18 en la ruta de análisis de CSV. Se asigna directamente desde el campo feed_name, que se deriva de column16 en la ruta de análisis de CSV. Se deriva de column21 y column14 en el análisis de CSV. Se deriva de column6 en el análisis de CSV o de Attribute.comment en el análisis de JSON. Se agregan varios campos como campos de detección con sus claves correspondientes. Se agregan varios campos como etiquetas con sus claves correspondientes. Se copia del campo timestamp de nivel superior en el registro sin procesar.

¿Necesitas más ayuda? Obtén respuestas de miembros de la comunidad y profesionales de Google SecOps.