Raccogliere i log IOC di MISP
Questa guida descrive i passaggi per importare i log IOC (Indicatori di compromissione) di MISP (Malware Information Sharing Platform) in Google Security Operations utilizzando Bindplane. Il parser estrae gli IOC dai dati MISP formattati come JSON o CSV. Analizza l'input, mappa i campi nel modello UDM (Unified Data Model), gestisce vari tipi di indicatori di compromissione (ad esempio hash di IP, domini e file) e arricchisce i dati con il contesto di intelligence sulle minacce, come confidenza e gravità. Il parser esegue anche una logica specifica per diversi formati di dati e gestisce i casi con campi mancanti o non supportati.
Prima di iniziare
Assicurati di soddisfare i seguenti prerequisiti:
- Istanza Google SecOps
- Host Linux con
systemd
- Se l'esecuzione avviene tramite un proxy, le porte del firewall sono aperte
- Accesso con privilegi al server MISP
Recuperare la chiave API MISP
- Accedi all'interfaccia utente web MISP come amministratore.
- Vai ad Amministrazione > Elenca chiavi di autenticazione.
- Fai clic su Aggiungi chiave di autenticazione.
- Fornisci la seguente configurazione della chiave:
- Utente: seleziona l'account utente associato alla chiave.
- IP consentiti: se vuoi, puoi specificare gli indirizzi IP consentiti per la chiave.
- Copia e salva la chiave in un luogo sicuro.
- Fai clic su Ho annotato la mia chiave.
Configura l'esportazione dei log MISP
- Accedi all'istanza MISP utilizzando SSH.
Installa PyMISP utilizzando il seguente comando:
pip3 install pymisp
Modifica lo script di esportazione
get_csv.py
utilizzando quanto segue:#!/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)
Modifica il file
keys.py
per includere le credenziali e l'URL dell'API MISP, come segue:misp_url = 'https://<MISP_URL>' misp_key = '<MISP_API_KEY>' misp_verifycert = False misp_client_cert = ''
- Sostituisci
<MISP_URL>
con l'IP o il nome host di MISP. - Sostituisci
<MISP_API_KEY
con la chiave API effettiva generata in precedenza.
- Sostituisci
Apri crontab utilizzando il comando
crontab -e
e inserisci quanto segue: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
- Aggiorna
<YOUR_EXPORT_SCRIPT_PATH>
in base alla posizione effettiva dello script di esportazione.
- Aggiorna
Recuperare il file di autenticazione importazione di Google SecOps
- Accedi alla console Google SecOps.
- Vai a Impostazioni SIEM > Agenti di raccolta.
- Scarica il file di autenticazione importazione. Salva il file in modo sicuro sul sistema in cui verrà installato Bindplane.
Recuperare l'ID cliente Google SecOps
- Accedi alla console Google SecOps.
- Vai a Impostazioni SIEM > Profilo.
- Copia e salva l'ID cliente dalla sezione Dettagli dell'organizzazione.
Installa l'agente Bindplane sul server MISP
Installazione di Linux
- Apri un terminale con privilegi di root o sudo.
Esegui questo comando:
sudo sh -c "$(curl -fsSlL https://github.com/observiq/bindplane-agent/releases/latest/download/install_unix.sh)" install_unix.sh
Risorse aggiuntive per l'installazione
Per ulteriori opzioni di installazione, consulta la guida all'installazione.
Configura l'agente Bindplane per importare i file di log MISP e inviarli a Google SecOps
- Accedi al file di configurazione:
- Individua il file
config.yaml
. In genere si trova nella directory/etc/bindplane-agent/
su Linux. - Apri il file utilizzando un editor di testo (ad esempio
nano
,vi
o Blocco note).
- Individua il file
Modifica il file
config.yaml
come segue: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
- Sostituisci la porta e l'indirizzo IP in base alle esigenze della tua infrastruttura.
- Sostituisci
<customer_id>
con l'ID cliente effettivo. - Aggiorna
/path/to/ingestion-authentication-file.json
al percorso in cui è stato salvato il file di autenticazione nella sezione Recupera il file di autenticazione per l'importazione di Google SecOps.
Riavvia l'agente Bindplane per applicare le modifiche
Per riavviare l'agente Bindplane in Linux, esegui questo comando:
sudo systemctl restart bindplane-agent
Tabella di mappatura UDM
Campo log | Mappatura UDM | Logic |
---|---|---|
Attribute.category |
event.idm.entity.metadata.threat.category_details |
Mappato direttamente da Attribute.category nell'oggetto JSON nidificato all'interno del campo "data". Utilizzato nel percorso di analisi JSON. |
Attribute.comment |
event.idm.entity.metadata.threat.summary |
Mappato direttamente da Attribute.comment nell'oggetto JSON nidificato all'interno del campo "data". Utilizzato nel percorso di analisi JSON. |
Attribute.deleted |
event.idm.entity.metadata.threat.detection_fields.value |
Mappato direttamente da Attribute.deleted e aggiunto come campo di rilevamento con la chiave "Attributo eliminato". Utilizzato nel percorso di analisi JSON. |
Attribute.event_id |
event.idm.entity.metadata.threat.detection_fields.value |
Mappato direttamente da Attribute.event_id e aggiunto come campo di rilevamento con la chiave "Attribute event_id". Utilizzato nel percorso di analisi JSON. |
Attribute.first_seen |
event.idm.entity.metadata.threat.detection_fields.value |
Mappato direttamente da Attribute.first_seen e aggiunto come campo di rilevamento con la chiave "Attribute first_seen". Utilizzato nel percorso di analisi JSON. |
Attribute.id |
event.idm.entity.metadata.threat.detection_fields.value |
Mappato direttamente da Attribute.id e aggiunto come campo di rilevamento con la chiave "ID attributo" o "ID attributo $$" a seconda del percorso di analisi. Utilizzato sia nei percorsi di analisi CSV che JSON. |
Attribute.timestamp |
event.idm.entity.metadata.threat.detection_fields.value |
Mappato direttamente da Attribute.timestamp e aggiunto come campo di rilevamento con la chiave "Timestamp attributo". Utilizzato nel percorso di analisi JSON. |
Attribute.to_ids |
event.idm.entity.metadata.threat.detection_fields.value |
Mappato direttamente da Attribute.to_ids e aggiunto come campo di rilevamento con la chiave "Attribute to_ids". Utilizzato nel percorso di analisi JSON. |
Attribute.type |
log_type |
Mappato direttamente da Attribute.type nell'oggetto JSON nidificato all'interno del campo "data". Utilizzato come campo provvisorio e successivamente per compilare altri campi UDM. Utilizzato nel percorso di analisi JSON. |
Attribute.uuid |
event.idm.entity.metadata.product_entity_id |
Mappato direttamente da Attribute.uuid nell'oggetto JSON nidificato all'interno del campo "data". Utilizzato nel percorso di analisi JSON. |
Attribute.value |
Multiplo | Il valore di questo campo viene utilizzato per compilare diversi campi UDM a seconda di Attribute.type (o log_type se derivato da Attribute.type ):- event.idm.entity.entity.hostname se type è "domain".- event.idm.entity.entity.file.md5 se type è "md5".- event.idm.entity.entity.file.sha1 se type è "sha1".- event.idm.entity.entity.file.sha256 se type è "sha256".- event.idm.entity.entity.resource.name se type è "mutex".- event.idm.entity.entity.registry.registry_key se type è "regkey".- event.idm.entity.entity.user.email_addresses se type è "threat-actor".- event.idm.entity.entity.url se type è uri o url .- event.idm.entity.entity.file.full_path se type è "filename".: analizzato per IP e porta se type è "ip-dst|port", "ip-dst" o "ip-src". Utilizzato nel percorso di analisi JSON. |
column1 |
event.idm.entity.metadata.product_entity_id |
Mappato direttamente da column1 nel percorso di analisi CSV. |
column14 |
Parte di event.idm.entity.metadata.threat.description |
Concatenato con description per formare la descrizione finale nei metadati della minaccia. Utilizzato nel percorso di analisi CSV. |
column16 |
event.idm.entity.metadata.threat.threat_feed_name , event.ioc.feed_name |
Mappato direttamente da column16 . Utilizzato nel percorso di analisi CSV. |
column18 |
event.idm.entity.metadata.threat.severity_details , event.ioc.raw_severity |
Mappato direttamente da column18 . Utilizzato nel percorso di analisi CSV. |
column21 |
Parte di event.idm.entity.metadata.threat.description , event.ioc.description |
Utilizzato come base per la descrizione, successivamente concatenato con event_info . Utilizzato nel percorso di analisi CSV. |
column3 |
Parte di event.ioc.categorization |
Mappato direttamente da column3 e concatenato con "IOC" per formare la classificazione finale. Utilizzato nel percorso di analisi CSV. |
column4 |
event.idm.entity.metadata.description |
Mappato direttamente da column4 . Utilizzato nel percorso di analisi CSV. |
column5 |
Multiplo | Il valore di questo campo viene utilizzato per compilare diversi campi UDM a seconda del campo column4 (che corrisponde a type ):- event.idm.entity.entity.hostname se type è "domain".: analizzato per IP e porta se type è "ip-dst|port", "ip-dst" o "ip-src".- event.idm.entity.entity.file.md5 se type è "md5".- event.idm.entity.entity.file.sha1 se type è "sha1".- event.idm.entity.entity.file.sha256 se type è "sha256".- event.idm.entity.entity.resource.name se type è "mutex".- event.idm.entity.entity.registry.registry_key se type è "regkey".- event.idm.entity.entity.user.email_addresses se type è "threat-actor".- event.idm.entity.entity.url se type è uri o url .- event.idm.entity.entity.file.full_path se type è "filename". Utilizzato nel percorso di analisi CSV. |
column6 |
event.idm.entity.metadata.threat.summary |
Mappato direttamente da column6 . Utilizzato nel percorso di analisi CSV. |
column8 |
event.ioc.active_timerange.start , event.idm.entity.metadata.interval.start_time |
Analizzato come timestamp UNIX. Utilizzato nel percorso di analisi CSV. |
date description |
event.idm.entity.metadata.threat.description |
Mappato direttamente da description nell'oggetto JSON nidificato all'interno del campo "data". Utilizzato nel percorso di analisi JSON. |
event_creator_email |
event.idm.entity.entity.labels.value |
Mappato direttamente da event_creator_email e aggiunto come etichetta con la chiave "event_creator_email". Utilizzato nel percorso di analisi JSON. |
event_id Feed.publish |
event.idm.entity.metadata.threat.detection_fields.value |
Mappato direttamente da Feed.publish e aggiunto come campo di rilevamento con la chiave "Pubblica feed". Utilizzato nel percorso di analisi JSON. |
first_seen |
event.ioc.active_timerange.start , event.idm.entity.metadata.interval.start_time |
Analizzato come timestamp nel formato "aaaa-MM-ggTHH:mm:ssZZ". Utilizzato nel percorso di analisi JSON. |
id info |
event.idm.entity.metadata.description |
Mappato direttamente da info nell'oggetto JSON nidificato all'interno del campo "data". Utilizzato nel percorso di analisi JSON. |
last_seen |
event.ioc.active_timerange.end |
Analizzato come timestamp nel formato "aaaa-MM-ggTHH:mm:ssZZ". Utilizzato nel percorso di analisi JSON. |
Org.name |
event.idm.entity.metadata.threat.detection_fields.value |
Mappato direttamente da Org.name e aggiunto come campo di rilevamento con la chiave "Nome organizzazione". Utilizzato nel percorso di analisi JSON. |
published |
event.idm.entity.metadata.threat.detection_fields.value |
Mappato direttamente da published e aggiunto come campo di rilevamento con la chiave "published". Utilizzato nel percorso di analisi JSON. |
Tag.colour |
event.idm.entity.metadata.threat.detection_fields.value |
Mappato direttamente da Tag.colour e aggiunto come campo di rilevamento con la chiave "Colore tag". Utilizzato nel percorso di analisi JSON. |
Tag.exportable |
event.idm.entity.metadata.threat.detection_fields.value |
Mappato direttamente da Tag.exportable e aggiunto come campo di rilevamento con la chiave "tag esportabile". Utilizzato nel percorso di analisi JSON. |
Tag.hide_tag |
event.idm.entity.metadata.threat.detection_fields.value |
Mappato direttamente da Tag.hide_tag e aggiunto come campo di rilevamento con la chiave "tag hide_tag". Utilizzato nel percorso di analisi JSON. |
Tag.id |
event.idm.entity.metadata.threat.detection_fields.value |
Mappato direttamente da Tag.id e aggiunto come campo di rilevamento con la chiave "ID tag". Utilizzato nel percorso di analisi JSON. |
Tag.is_custom_galaxy |
event.idm.entity.metadata.threat.detection_fields.value |
Mappato direttamente da Tag.is_custom_galaxy e aggiunto come campo di rilevamento con la chiave "tag is_custom_galaxy". Utilizzato nel percorso di analisi JSON. |
Tag.is_galaxy |
event.idm.entity.metadata.threat.detection_fields.value |
Mappato direttamente da Tag.is_galaxy e aggiunto come campo di rilevamento con la chiave "tag is_galaxy". Utilizzato nel percorso di analisi JSON. |
Tag.isinherited |
event.idm.entity.metadata.threat.detection_fields.value |
Mappato direttamente da Tag.isinherited e aggiunto come campo di rilevamento con la chiave "tag isinherited". Utilizzato nel percorso di analisi JSON. |
Tag.name |
event.idm.entity.metadata.threat.detection_fields.value |
Mappato direttamente da Tag.name e aggiunto come campo di rilevamento con la chiave "nome tag". Utilizzato nel percorso di analisi JSON. |
Tag.numerical_value |
event.idm.entity.metadata.threat.detection_fields.value |
Mappato direttamente da Tag.numerical_value e aggiunto come campo di rilevamento con la chiave "tag numerical_value". Utilizzato nel percorso di analisi JSON. |
Tag.user_id |
event.idm.entity.metadata.threat.detection_fields.value |
Mappato direttamente da Tag.user_id e aggiunto come campo di rilevamento con la chiave "tag user_id". Utilizzato nel percorso di analisi JSON. |
threat_level_id |
event.idm.entity.entity.labels.value |
Mappato direttamente da threat_level_id e aggiunto come etichetta con la chiave "threat_level_id". Utilizzato nel percorso di analisi JSON. |
timestamp |
event.idm.entity.metadata.collected_timestamp , event.idm.entity.metadata.interval.start_time |
Analizzato come timestamp UNIX. Utilizzato nel percorso di analisi CSV. |
uuid |
event.idm.entity.metadata.vendor_name |
Impostato su "MISP" dal parser. Impostato su "MISP" dal parser. Imposta un valore predefinito molto lontano nel futuro (253402300799 secondi dall'epoca). Determinato dal parser in base al campo type o log_type . Può essere "FILE", "DOMAIN_NAME", "IP_ADDRESS", "MUTEX", "RESOURCE" o "USER". Può essere derivato da Attribute.comment o Attribute.value a seconda di Attribute.type . Analizzato da Attribute.value o column5 se il tipo è correlato all'IP. Analizzato da Attribute.value o column5 se il tipo è "ip-dst|port". Derivato da column3 nell'analisi CSV o da Attribute.category nell'analisi JSON. Derivato da column21 e column14 nell'analisi del file CSV. Derivato da column8 o first_seen . Derivato da last_seen . Derivato da description utilizzando un pattern grok. Derivato da column16 o impostato su "MISP". Derivato da column18 . Analizzato da Attribute.value o column5 se il tipo è correlato all'IP. Analizzato da Attribute.value o column5 se il tipo è "ip-dst|port". Derivato da Attribute.value o column5 se il tipo è "dominio". Derivato dal campo confidence , che viene estratto dal campo description . I valori possono essere "HIGH_CONFIDENCE", "MEDIUM_CONFIDENCE", "LOW_CONFIDENCE" o "UNKNOWN_CONFIDENCE". Mappato direttamente dal campo confidence , che viene estratto dal campo description . Mappato direttamente dal campo threat_level , derivato da column18 nel percorso di analisi del file CSV. Mappato direttamente dal campo feed_name , derivato da column16 nel percorso di analisi del file CSV. Derivato da column21 e column14 nell'analisi del file CSV. Derivato da column6 nell'analisi CSV o da Attribute.comment nell'analisi JSON. Vengono aggiunti diversi campi come campi di rilevamento con le relative chiavi. Diversi campi vengono aggiunti come etichette con le relative chiavi. Copiato dal campo timestamp di primo livello nel log non elaborato. |
Hai bisogno di ulteriore assistenza? Ricevi risposte dai membri della community e dai professionisti di Google SecOps.