Collecter les journaux d'IOC MISP

Compatible avec :

Ce guide décrit les étapes à suivre pour ingérer les journaux MISP (Malware Information Sharing Platform) IOC (Indicateurs de compromission) dans Google Security Operations à l'aide de Bindplane. L'analyseur extrait les IOC des données MISP au format JSON ou CSV. Il analyse l'entrée, mappe les champs au modèle de données unifié (UDM), gère différents types d'IOC (tels que les adresses IP, les domaines et les hachages de fichiers), et enrichit les données avec le contexte de renseignements sur les menaces, comme la confiance et la gravité. L'analyseur effectue également une logique spécifique pour différents formats de données et gère les cas où des champs sont manquants ou non compatibles.

Avant de commencer

Assurez-vous de remplir les conditions suivantes :

  • Instance Google SecOps
  • Hôte Linux avec systemd
  • Si vous exécutez le programme derrière un proxy, les ports du pare-feu sont ouverts.
  • Accès privilégié à votre serveur MISP

Obtenir une clé API MISP

  1. Connectez-vous à l'interface utilisateur Web MISP en tant qu'administrateur.
  2. Accédez à Administration > Lister les clés d'authentification.
  3. Cliquez sur Ajouter une clé d'authentification.
  4. Fournissez la configuration de clé suivante :
    • Utilisateur : sélectionnez le compte utilisateur associé à la clé.
    • Adresses IP autorisées : vous pouvez éventuellement spécifier les adresses IP autorisées pour la clé.
    • Copiez et enregistrez la clé dans un emplacement sécurisé.
    • Cliquez sur J'ai noté ma clé.

Configurer l'exportation des journaux MISP

  1. Connectez-vous à votre instance MISP à l'aide de SSH.
  2. Installez PyMISP à l'aide de la commande suivante :

    pip3 install pymisp 
    
  3. Modifiez le script d'exportation get_csv.py à l'aide des éléments suivants :

    #!/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. Modifiez le fichier keys.py pour inclure vos identifiants et l'URL de l'API MISP, comme suit :

    misp_url = 'https://<MISP_URL>'
    misp_key = '<MISP_API_KEY>'
    misp_verifycert = False
    misp_client_cert = ''
    
    • Remplacez <MISP_URL> par l'adresse IP ou le nom d'hôte de votre instance MISP.
    • Remplacez <MISP_API_KEY par la clé API réelle générée précédemment.
  5. Ouvrez crontab à l'aide de la commande crontab -e, puis saisissez ce qui suit :

    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
    
    • Mettez à jour <YOUR_EXPORT_SCRIPT_PATH> en fonction de l'emplacement réel du script d'exportation.

Obtenir le fichier d'authentification d'ingestion Google SecOps

  1. Connectez-vous à la console Google SecOps.
  2. Accédez à Paramètres du SIEM > Agents de collecte.
  3. Téléchargez le fichier d'authentification d'ingestion. Enregistrez le fichier de manière sécurisée sur le système sur lequel Bindplane sera installé.

Obtenir l'ID client Google SecOps

  1. Connectez-vous à la console Google SecOps.
  2. Accédez à Paramètres SIEM> Profil.
  3. Copiez et enregistrez le numéro client de la section Informations sur l'organisation.

Installer l'agent Bindplane sur le serveur MISP

Installation de Linux

  1. Ouvrez un terminal avec les droits root ou sudo.
  2. Exécutez la commande suivante :

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

Ressources d'installation supplémentaires

Pour plus d'options d'installation, consultez le guide d'installation.

Configurer l'agent Bindplane pour ingérer les fichiers journaux MISP et les envoyer à Google SecOps

  1. Accédez au fichier de configuration :
    • Recherchez le fichier config.yaml. Il se trouve généralement dans le répertoire /etc/bindplane-agent/ sous Linux.
    • Ouvrez le fichier à l'aide d'un éditeur de texte (par exemple, nano, vi ou le Bloc-notes).
  2. Modifiez le fichier config.yaml comme suit :

    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
    
    • Remplacez le port et l'adresse IP selon les besoins de votre infrastructure.
    • Remplacez <customer_id> par le numéro client réel.
    • Mettez à jour /path/to/ingestion-authentication-file.json en indiquant le chemin d'accès où le fichier d'authentification a été enregistré dans la section Obtenir le fichier d'authentification pour l'ingestion Google SecOps.

Redémarrez l'agent Bindplane pour appliquer les modifications.

Pour redémarrer l'agent Bindplane sous Linux, exécutez la commande suivante :

  sudo systemctl restart bindplane-agent

Table de mappage UDM

Champ de journal Mappage UDM Logique
Attribute.category event.idm.entity.metadata.threat.category_details Mappé directement à partir de Attribute.category dans l'objet JSON imbriqué dans le champ "data". Utilisé dans le chemin d'analyse JSON.
Attribute.comment event.idm.entity.metadata.threat.summary Mappé directement à partir de Attribute.comment dans l'objet JSON imbriqué dans le champ "data". Utilisé dans le chemin d'analyse JSON.
Attribute.deleted event.idm.entity.metadata.threat.detection_fields.value Mappé directement à partir de Attribute.deleted et ajouté en tant que champ de détection avec la clé "Attribute deleted" (Attribut supprimé). Utilisé dans le chemin d'analyse JSON.
Attribute.event_id event.idm.entity.metadata.threat.detection_fields.value Directement mappé à partir de Attribute.event_id et ajouté en tant que champ de détection avec la clé "Attribute event_id". Utilisé dans le chemin d'analyse JSON.
Attribute.first_seen event.idm.entity.metadata.threat.detection_fields.value Mappé directement à partir de Attribute.first_seen et ajouté en tant que champ de détection avec la clé "Attribute first_seen". Utilisé dans le chemin d'analyse JSON.
Attribute.id event.idm.entity.metadata.threat.detection_fields.value Directement mappé à partir de Attribute.id et ajouté en tant que champ de détection avec la clé "Attribute id" ou "Attribute id $$" selon le chemin d'analyse. Utilisé dans les chemins d'analyse CSV et JSON.
Attribute.timestamp event.idm.entity.metadata.threat.detection_fields.value Mappé directement à partir de Attribute.timestamp et ajouté en tant que champ de détection avec la clé "Timestamp de l'attribut". Utilisé dans le chemin d'analyse JSON.
Attribute.to_ids event.idm.entity.metadata.threat.detection_fields.value Mappé directement à partir de Attribute.to_ids et ajouté en tant que champ de détection avec la clé "Attribute to_ids". Utilisé dans le chemin d'analyse JSON.
Attribute.type log_type Mappé directement à partir de Attribute.type dans l'objet JSON imbriqué dans le champ "data". Utilisé comme champ intermédiaire, puis pour remplir d'autres champs UDM. Utilisé dans le chemin d'analyse JSON.
Attribute.uuid event.idm.entity.metadata.product_entity_id Mappé directement à partir de Attribute.uuid dans l'objet JSON imbriqué dans le champ "data". Utilisé dans le chemin d'analyse JSON.
Attribute.value Plusieurs La valeur de ce champ est utilisée pour renseigner plusieurs champs UDM en fonction de Attribute.type (ou log_type s'il est dérivé de Attribute.type) :
- event.idm.entity.entity.hostname si type est "domain".
 – event.idm.entity.entity.file.md5 si type est "md5".
 – event.idm.entity.entity.file.sha1 si type est "sha1".
 – event.idm.entity.entity.file.sha256 si type est "sha256".
 – event.idm.entity.entity.resource.name si type est "mutex".
 – event.idm.entity.entity.registry.registry_key si type est défini sur "regkey".
 – event.idm.entity.entity.user.email_addresses si type est "threat-actor".
 : event.idm.entity.entity.url si type est uri ou url.
 – event.idm.entity.entity.file.full_path si type est "filename".
 : analysé pour l'adresse IP et le port si type est défini sur "ip-dst|port", "ip-dst" ou "ip-src". Utilisé dans le chemin d'analyse JSON.
column1 event.idm.entity.metadata.product_entity_id Mappé directement à partir de column1 dans le chemin d'analyse CSV.
column14 Fait partie de event.idm.entity.metadata.threat.description Concaténé avec description pour former la description finale dans les métadonnées de la menace. Utilisé dans le chemin d'analyse CSV.
column16 event.idm.entity.metadata.threat.threat_feed_name, event.ioc.feed_name Mappé directement à partir de column16. Utilisé dans le chemin d'analyse CSV.
column18 event.idm.entity.metadata.threat.severity_details, event.ioc.raw_severity Mappé directement à partir de column18. Utilisé dans le chemin d'analyse CSV.
column21 Fait partie de event.idm.entity.metadata.threat.description, event.ioc.description Utilisé comme base pour la description, puis concaténé avec event_info. Utilisé dans le chemin d'analyse CSV.
column3 Fait partie de event.ioc.categorization Mappé directement à partir de column3 et concaténé avec " IOC" pour former la catégorisation finale. Utilisé dans le chemin d'analyse CSV.
column4 event.idm.entity.metadata.description Mappé directement à partir de column4. Utilisé dans le chemin d'analyse CSV.
column5 Plusieurs La valeur de ce champ est utilisée pour renseigner plusieurs champs UDM en fonction du champ column4 (qui correspond à type) :
 – event.idm.entity.entity.hostname si type est "domain".
 : analysé pour l'adresse IP et le port si type est défini sur "ip-dst|port", "ip-dst" ou "ip-src".
 – event.idm.entity.entity.file.md5 si type est "md5".
 – event.idm.entity.entity.file.sha1 si type est "sha1".
 – event.idm.entity.entity.file.sha256 si type est "sha256".
 – event.idm.entity.entity.resource.name si type est "mutex".
 – event.idm.entity.entity.registry.registry_key si type est défini sur "regkey".
 – event.idm.entity.entity.user.email_addresses si type est "threat-actor".
 : event.idm.entity.entity.url si type est uri ou url.
 – event.idm.entity.entity.file.full_path si type est "filename". Utilisé dans le chemin d'analyse CSV.
column6 event.idm.entity.metadata.threat.summary Mappé directement à partir de column6. Utilisé dans le chemin d'analyse CSV.
column8 event.ioc.active_timerange.start, event.idm.entity.metadata.interval.start_time Analysé en tant qu'horodatage UNIX. Utilisé dans le chemin d'analyse CSV.
date description event.idm.entity.metadata.threat.description Mappé directement à partir de description dans l'objet JSON imbriqué dans le champ "data". Utilisé dans le chemin d'analyse JSON.
event_creator_email event.idm.entity.entity.labels.value Directement mappé à partir de event_creator_email et ajouté en tant que libellé avec la clé "event_creator_email". Utilisé dans le chemin d'analyse JSON.
event_id Feed.publish event.idm.entity.metadata.threat.detection_fields.value Directement mappé à partir de Feed.publish et ajouté en tant que champ de détection avec la clé "Feed publish". Utilisé dans le chemin d'analyse JSON.
first_seen event.ioc.active_timerange.start, event.idm.entity.metadata.interval.start_time Analysé comme un code temporel au format "aaaa-MM-jjTHH:mm:ssZZ". Utilisé dans le chemin d'analyse JSON.
id info event.idm.entity.metadata.description Mappé directement à partir de info dans l'objet JSON imbriqué dans le champ "data". Utilisé dans le chemin d'analyse JSON.
last_seen event.ioc.active_timerange.end Analysé comme un code temporel au format "aaaa-MM-jjTHH:mm:ssZZ". Utilisé dans le chemin d'analyse JSON.
Org.name event.idm.entity.metadata.threat.detection_fields.value Directement mappé à partir de Org.name et ajouté en tant que champ de détection avec la clé "Nom de l'organisation". Utilisé dans le chemin d'analyse JSON.
published event.idm.entity.metadata.threat.detection_fields.value Mappé directement à partir de published et ajouté en tant que champ de détection avec la clé "published". Utilisé dans le chemin d'analyse JSON.
Tag.colour event.idm.entity.metadata.threat.detection_fields.value Directement mappé à partir de Tag.colour et ajouté en tant que champ de détection avec la clé "tag colour". Utilisé dans le chemin d'analyse JSON.
Tag.exportable event.idm.entity.metadata.threat.detection_fields.value Directement mappé à partir de Tag.exportable et ajouté en tant que champ de détection avec la clé "tag exportable". Utilisé dans le chemin d'analyse JSON.
Tag.hide_tag event.idm.entity.metadata.threat.detection_fields.value Directement mappé à partir de Tag.hide_tag et ajouté en tant que champ de détection avec la clé "tag hide_tag". Utilisé dans le chemin d'analyse JSON.
Tag.id event.idm.entity.metadata.threat.detection_fields.value Directement mappé à partir de Tag.id et ajouté en tant que champ de détection avec la clé "tag id". Utilisé dans le chemin d'analyse JSON.
Tag.is_custom_galaxy event.idm.entity.metadata.threat.detection_fields.value Directement mappé à partir de Tag.is_custom_galaxy et ajouté en tant que champ de détection avec la clé "tag is_custom_galaxy". Utilisé dans le chemin d'analyse JSON.
Tag.is_galaxy event.idm.entity.metadata.threat.detection_fields.value Directement mappé à partir de Tag.is_galaxy et ajouté en tant que champ de détection avec la clé "tag is_galaxy". Utilisé dans le chemin d'analyse JSON.
Tag.isinherited event.idm.entity.metadata.threat.detection_fields.value Directement mappé à partir de Tag.isinherited et ajouté en tant que champ de détection avec la clé "tag isinherited". Utilisé dans le chemin d'analyse JSON.
Tag.name event.idm.entity.metadata.threat.detection_fields.value Directement mappé à partir de Tag.name et ajouté en tant que champ de détection avec la clé "tag name". Utilisé dans le chemin d'analyse JSON.
Tag.numerical_value event.idm.entity.metadata.threat.detection_fields.value Mappé directement à partir de Tag.numerical_value et ajouté en tant que champ de détection avec la clé "tag numerical_value". Utilisé dans le chemin d'analyse JSON.
Tag.user_id event.idm.entity.metadata.threat.detection_fields.value Directement mappé à partir de Tag.user_id et ajouté en tant que champ de détection avec la clé "tag user_id". Utilisé dans le chemin d'analyse JSON.
threat_level_id event.idm.entity.entity.labels.value Directement mappé à partir de threat_level_id et ajouté en tant que libellé avec la clé "threat_level_id". Utilisé dans le chemin d'analyse JSON.
timestamp event.idm.entity.metadata.collected_timestamp, event.idm.entity.metadata.interval.start_time Analysé en tant qu'horodatage UNIX. Utilisé dans le chemin d'analyse CSV.
uuid event.idm.entity.metadata.vendor_name Définie sur "MISP" par l'analyseur. Définie sur "MISP" par l'analyseur. Définissez une valeur par défaut dans un avenir lointain (253402300799 secondes depuis l'epoch). Déterminé par l'analyseur en fonction du champ type ou log_type. Valeurs possibles : "FILE", "DOMAIN_NAME", "IP_ADDRESS", "MUTEX", "RESOURCE" ou "USER". Peut être dérivé de Attribute.comment ou Attribute.value selon le Attribute.type. Analysé à partir de Attribute.value ou column5 si le type est lié à une adresse IP. Analysé à partir de Attribute.value ou column5 si le type est "ip-dst|port". Dérivé de column3 dans l'analyse CSV ou de Attribute.category dans l'analyse JSON. Dérivé de column21 et column14 dans l'analyse CSV. Dérivé de column8 ou first_seen. Dérivé de last_seen. Dérivé de description à l'aide d'un modèle Grok. Dérivé de column16 ou défini sur "MISP". Dérivé de column18. Analysé à partir de Attribute.value ou column5 si le type est lié à une adresse IP. Analysé à partir de Attribute.value ou column5 si le type est "ip-dst|port". Dérivé de Attribute.value ou column5 si le type est "domain". Dérivé du champ confidence, qui est extrait du champ description. Les valeurs possibles sont "HIGH_CONFIDENCE", "MEDIUM_CONFIDENCE", "LOW_CONFIDENCE" ou "UNKNOWN_CONFIDENCE". Mappé directement à partir du champ confidence, qui est extrait du champ description. Mappé directement à partir du champ threat_level, qui est dérivé de column18 dans le chemin d'analyse du fichier CSV. Mappé directement à partir du champ feed_name, qui est dérivé de column16 dans le chemin d'analyse du fichier CSV. Dérivé de column21 et column14 dans l'analyse CSV. Dérivé de column6 dans l'analyse CSV ou de Attribute.comment dans l'analyse JSON. Plusieurs champs sont ajoutés en tant que champs de détection avec leurs clés correspondantes. Plusieurs champs sont ajoutés en tant qu'étiquettes avec leurs clés correspondantes. Copié à partir du champ timestamp de premier niveau dans le journal brut.

Vous avez encore besoin d'aide ? Obtenez des réponses de membres de la communauté et de professionnels Google SecOps.