Collecter les journaux d'IOC MISP
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
- Connectez-vous à l'interface utilisateur Web MISP en tant qu'administrateur.
- Accédez à Administration > Lister les clés d'authentification.
- Cliquez sur Ajouter une clé d'authentification.
- 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
- Connectez-vous à votre instance MISP à l'aide de SSH.
Installez PyMISP à l'aide de la commande suivante :
pip3 install pymisp
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)
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.
- Remplacez
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.
- Mettez à jour
Obtenir le fichier d'authentification d'ingestion Google SecOps
- Connectez-vous à la console Google SecOps.
- Accédez à Paramètres du SIEM > Agents de collecte.
- 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
- Connectez-vous à la console Google SecOps.
- Accédez à Paramètres SIEM> Profil.
- 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
- Ouvrez un terminal avec les droits root ou sudo.
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
- 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).
- Recherchez le fichier
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.