Raccogliere i log IOC di MISP

Supportato in:

Questo documento spiega come importare i log IOC (Indicator of Compromise) di MISP (Malware Information Sharing Platform) in Google Security Operations utilizzando Bindplane. Il parser elabora i dati nei formati CSV e JSON. Estrae gli attributi IOC come indirizzi IP, domini, hash e URL, mappandoli a un modello UDM (Unified Data Model) insieme ai dettagli delle minacce come gravità, confidenza e descrizioni. Il parser gestisce voci IOC singole e multiple all'interno dei dati di input, normalizzandole in un output UDM coerente.

Prima di iniziare

Assicurati di soddisfare i seguenti prerequisiti:

  • Un'istanza Google SecOps.
  • Un host Linux con systemd.
  • Se l'agente viene eseguito tramite un proxy, assicurati che le porte del firewall siano aperte in base ai requisiti dell'agente Bindplane.
  • Accesso con privilegi al server MISP.

Recuperare il file di autenticazione importazione di Google SecOps

  1. Accedi alla console Google SecOps.
  2. Vai a Impostazioni SIEM > Agenti di raccolta.
  3. 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

  1. Accedi alla console Google SecOps.
  2. Vai a Impostazioni SIEM*> Profilo.
  3. Copia e salva l'ID cliente dalla sezione Dettagli dell'organizzazione.

Ottenere le credenziali API MISP

  1. Accedi all'interfaccia web di MISP come amministratore.
  2. Vai ad Amministrazione > Elenca chiavi di autenticazione.
  3. Fai clic su Aggiungi chiave di autenticazione.
  4. Fornisci i seguenti dettagli di configurazione:
    • Utente: seleziona l'account utente associato alla chiave.
    • (Facoltativo) IP consentiti: specifica gli indirizzi IP consentiti per la chiave.
    • Scadenza: lascia vuoto per nessuna scadenza o imposta in base alle esigenze.
  5. Fai clic su Invia.
  6. Copia e salva la chiave API in un luogo sicuro.
  7. Fai clic su Ho annotato la mia chiave.

Configura l'esportazione dei dati MISP

  1. Installa PyMISP sul server MISP:

    pip3 install pymisp
    
  2. Crea la directory di esportazione:

    sudo mkdir -p /opt/misp/scripts
    sudo mkdir -p /opt/misp/ioc_export
    
  3. Crea il file delle credenziali /opt/misp/scripts/keys.py:

    misp_url = 'https://<MISP_SERVER_URL>'
    misp_key = '<MISP_API_KEY>'
    misp_verifycert = True
    misp_client_cert = ''
    
    • Sostituisci <MISP_SERVER_URL> con l'URL del server MISP.
    • Sostituisci <MISP_API_KEY> con la chiave API dei prerequisiti.
  4. Crea lo script di esportazione /opt/misp/scripts/misp_export.py:

    #!/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='Export MISP IOCs to CSV format.')
        parser.add_argument("--controller", default='attributes',
                            help="Controller to use for search (events, objects, attributes)")
        parser.add_argument("--event_id",
                            help="Event ID to fetch. Without it, fetches recent data.")
        parser.add_argument("--attributes", nargs='*',
                            help="Requested attributes for CSV export")
        parser.add_argument("--misp_types", nargs='+',
                            help="MISP types to fetch (ip-src, hostname, domain, etc.)")
        parser.add_argument("--context", action='store_true',
                            help="Add event level context (tags, metadata)")
        parser.add_argument("--outfile", required=True,
                            help="Output file to write the CSV data")
        parser.add_argument("--last", required=True,
                            help="Time period: days (d), hours (h), minutes (m) - e.g., 1d, 12h, 30m")
    
        args = parser.parse_args()
    
        api = ExpandedPyMISP(misp_url, misp_key, misp_verifycert, debug=False)
    
        response = api.search(
            controller=args.controller,
            return_format='csv',
            type_attribute=args.misp_types,
            publish_timestamp=args.last,
            include_context=args.context,
            requested_attributes=args.attributes or None
        )
    
        with open(args.outfile, 'w') as response_file:
            response_file.write(response)
    
    1. Rendi eseguibile lo script:
    sudo chmod +x /opt/misp/scripts/misp_export.py
    

    Pianificare le esportazioni di dati MISP

    1. Crea esportazioni programmate utilizzando crontab:
    sudo crontab -e
    
  5. Aggiungi le seguenti voci cron:

    # Export different IOC types daily with context
    0 0 * * * python3 /opt/misp/scripts/misp_export.py --outfile /opt/misp/ioc_export/domains.csv --misp_types domain --last 1d --context --attributes uuid event_id category type value comment to_ids date attribute_tag event_info
    0 1 * * * python3 /opt/misp/scripts/misp_export.py --outfile /opt/misp/ioc_export/ip-src.csv --misp_types ip-src --last 1d --context --attributes uuid event_id category type value comment to_ids date attribute_tag event_info
    0 2 * * * python3 /opt/misp/scripts/misp_export.py --outfile /opt/misp/ioc_export/ip-dst.csv --misp_types ip-dst --last 1d --context --attributes uuid event_id category type value comment to_ids date attribute_tag event_info
    0 3 * * * python3 /opt/misp/scripts/misp_export.py --outfile /opt/misp/ioc_export/urls.csv --misp_types url --last 1d --context --attributes uuid event_id category type value comment to_ids date attribute_tag event_info
    0 4 * * * python3 /opt/misp/scripts/misp_export.py --outfile /opt/misp/ioc_export/sha256.csv --misp_types sha256 --last 1d --context --attributes uuid event_id category type value comment to_ids date attribute_tag event_info
    0 5 * * * python3 /opt/misp/scripts/misp_export.py --outfile /opt/misp/ioc_export/filenames.csv --misp_types filename --last 1d --context --attributes uuid event_id category type value comment to_ids date attribute_tag event_info
    0 6 * * * python3 /opt/misp/scripts/misp_export.py --outfile /opt/misp/ioc_export/registries.csv --misp_types regkey --last 1d --context --attributes uuid event_id category type value comment to_ids date attribute_tag event_info
    0 7 * * * python3 /opt/misp/scripts/misp_export.py --outfile /opt/misp/ioc_export/mutexes.csv --misp_types mutex --last 1d --context --attributes uuid event_id category type value comment to_ids date attribute_tag event_info
    
  6. (Facoltativo) Pianifica un pull dei feed da MISP:

    23 0 * * * curl --insecure --header "Authorization: <MISP_API_KEY>" --header "Accept: application/json" --header "Content-Type: application/json" https://<MISP_SERVER_URL>/feeds/fetchFromAllFeeds
    

Installa l'agente Bindplane

Installa l'agente Bindplane sul sistema operativo Linux seguendo queste istruzioni.

Installazione di Linux

  1. Apri un terminale con privilegi root o sudo.
  2. Esegui questo comando:

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

Risorse aggiuntive per l'installazione

Configura l'agente Bindplane per importare i log MISP e inviarli a Google SecOps

  1. 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).
  2. Modifica il file config.yaml come segue:

    receivers:
        filelog:
            file_path: /opt/misp/ioc_export/*.log
    
    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 <CUSTOMER_ID> con il tuo ID cliente effettivo dai prerequisiti.
    • Aggiorna /path/to/ingestion-authentication-file.json al percorso in cui è stato salvato il file di autenticazione.

Riavvia l'agente Bindplane per applicare le modifiche

  1. Per riavviare l'agente Bindplane in Linux, esegui questo comando:

    sudo systemctl restart observiq-otel-collector
    

Tabella di mappatura UDM

Campo log Mappatura UDM Logic
Attribute.category entity.metadata.threat.category_details Mappatura diretta dal campo category nell'oggetto Attribute.
Attribute.comment entity.metadata.threat.summary Mappatura diretta dal campo comment nell'oggetto Attribute.
Attribute.deleted entity.metadata.threat.detection_fields.value Mappatura diretta dal campo deleted nell'oggetto Attribute. Il tasto è impostato su Attribute deleted.
Attribute.event_id entity.metadata.threat.detection_fields.value Mappatura diretta dal campo event_id nell'oggetto Attribute. Il tasto è impostato su Attribute event_id.
Attribute.first_seen entity.metadata.threat.detection_fields.value Mappatura diretta dal campo first_seen nell'oggetto Attribute. Il tasto è impostato su Attribute first_seen.
Attribute.id entity.metadata.threat.detection_fields.value Mappatura diretta dal campo id nell'oggetto Attribute. La chiave è impostata su Attribute id o Attribute id $$ a seconda del formato del log non elaborato.
Attribute.timestamp entity.metadata.threat.detection_fields.value Mappatura diretta dal campo timestamp nell'oggetto Attribute. Il tasto è impostato su Attribute timestamp.
Attribute.to_ids entity.metadata.threat.detection_fields.value Mappatura diretta dal campo to_ids nell'oggetto Attribute. Il tasto è impostato su Attribute to_ids.
Attribute.type entity.metadata.threat.category_details Mappatura diretta dal campo type nell'oggetto Attribute.
Attribute.type log_type Utilizzato per determinare il tipo di indicatore di compromissione e mapparlo ai campi UDM appropriati.
Attribute.uuid entity.metadata.product_entity_id Mappatura diretta dal campo uuid nell'oggetto Attribute.
Attribute.value entity.entity.file.full_path Mappato se Attribute.type è filename.
Attribute.value entity.entity.file.md5 Mappato se Attribute.type è md5.
Attribute.value entity.entity.file.sha1 Mappato se Attribute.type è sha1.
Attribute.value entity.entity.file.sha256 Mappato se Attribute.type è sha256.
Attribute.value entity.entity.hostname Mappato se Attribute.type è domain.
Attribute.value entity.entity.ip Mappato se Attribute.type è ip-dst, ip-dst|port o ip-src. Il valore viene estratto utilizzando un pattern grok.
Attribute.value entity.entity.resource.name Mappato se Attribute.type è mutex.
Attribute.value entity.entity.registry.registry_key Mappato se Attribute.type è regkey.
Attribute.value entity.entity.url Mappato se Attribute.type è uri o URL.
colonna1 entity.metadata.product_entity_id Mappatura diretta dalla prima colonna dei dati CSV.
column14 event_info Utilizzato per aggiungere informazioni aggiuntive al campo threat_sr.description.
column16 event_source_org Mappatura diretta dalla sedicesima colonna dei dati CSV.
column18 threat_level Mappatura diretta dalla 18ª colonna dei dati CSV.
column21 descrizione Mappatura diretta dalla 21ª colonna dei dati CSV.
colonna3 misp_category Mappatura diretta dalla terza colonna dei dati CSV.
column4 tipo Mappatura diretta dalla quarta colonna dei dati CSV.
column5 valore Mappatura diretta dalla quinta colonna dei dati CSV.
column6 commento Mappatura diretta dalla sesta colonna dei dati CSV.
column8 ts1 Mappatura diretta dall'ottava colonna dei dati CSV.
descrizione ioc.description Il valore viene generato combinando il campo description con il campo event_info, separati da - additional info:.
descrizione entity.metadata.threat.description Mappatura diretta dal campo description.
event_creator_email entity.entity.labels.value Mappatura diretta dal campo event_creator_email. Il tasto è impostato su event_creator_email.
event_source_org ioc.feed_name Mappatura diretta dal campo event_source_org.
event_source_org entity.metadata.threat.threat_feed_name Mappatura diretta dal campo event_source_org.
Feed.publish entity.metadata.threat.detection_fields.value Mappatura diretta dal campo publish nell'oggetto Feed. Il tasto è impostato su Feed publish.
first_seen ioc.active_timerange.start Mappatura diretta dal campo first_seen. Il valore viene analizzato come data.
first_seen entity.metadata.interval.start_time Mappatura diretta dal campo first_seen. Il valore viene analizzato come data.
informazioni entity.metadata.description Mappatura diretta dal campo info.
last_seen ioc.active_timerange.end Mappatura diretta dal campo last_seen. Il valore viene analizzato come data.
log.category ioc.categorization Mappatura diretta dal campo category nell'oggetto log.
log.category entity.metadata.threat.category_details Mappatura diretta dal campo category nell'oggetto log.
log.comment entity.entity.file.full_path Mappato se log.type è filename e il campo comment non è Artifacts dropped.
log.comment entity.metadata.threat.detection_fields.value Mappatura diretta dal campo comment nell'oggetto log. Il tasto è impostato su Attribute comment.
log.comment entity.metadata.threat.summary Mappatura diretta dal campo comment nell'oggetto log.
log.deleted entity.metadata.threat.detection_fields.value Mappatura diretta dal campo deleted nell'oggetto log. Il tasto è impostato su Attribute deleted.
log.event_id entity.metadata.threat.detection_fields.value Mappatura diretta dal campo event_id nell'oggetto log. Il tasto è impostato su Attribute event_id.
log.first_seen entity.metadata.threat.detection_fields.value Mappatura diretta dal campo first_seen nell'oggetto log. Il tasto è impostato su Attribute first_seen.
log.id entity.metadata.threat.detection_fields.value Mappatura diretta dal campo id nell'oggetto log. Il tasto è impostato su Attribute id.
log.timestamp entity.metadata.threat.detection_fields.value Mappatura diretta dal campo timestamp nell'oggetto log. Il tasto è impostato su Attribute timestamp.
log.to_ids entity.metadata.threat.detection_fields.value Mappatura diretta dal campo to_ids nell'oggetto log. Il tasto è impostato su Attribute to_ids.
log.type ioc.categorization Mappatura diretta dal campo type nell'oggetto log.
log.type log_type Utilizzato per determinare il tipo di indicatore di compromissione e mapparlo ai campi UDM appropriati.
log.uuid entity.metadata.product_entity_id Mappatura diretta dal campo uuid nell'oggetto log.
log.value entity.entity.file.full_path Mappato se log.type è filename.
log.value entity.entity.file.md5 Mappato se log.type è md5.
log.value entity.entity.file.sha1 Mappato se log.type è sha1.
log.value entity.entity.file.sha256 Mappato se log.type è sha256.
log.value entity.entity.hostname Mappato se log.type è domain.
log.value entity.entity.ip Mappato se log.type è ip-dst, ip-dst|port o ip-src. Il valore viene estratto utilizzando un pattern grok.
log.value entity.entity.resource.name Mappato se log.type è mutex.
log.value entity.entity.registry.registry_key Mappato se log.type è regkey.
log.value entity.entity.url Mappato se log.type è uri o url.
log.value ioc.domain_and_ports.domain Mappato se log.type è domain.
log.value entity.entity.user.email_addresses Mappato se log.type è threat-actor.
misp_category entity.metadata.threat.category_details Mappatura diretta dal campo misp_category.
Org.name entity.metadata.threat.detection_fields.value Mappatura diretta dal campo name nell'oggetto Org. Il tasto è impostato su Org name.
pubblicato entity.metadata.threat.detection_fields.value Mappatura diretta dal campo published. Il tasto è impostato su published.
Tag.colour entity.metadata.threat.detection_fields.value Mappatura diretta dal campo colour nell'oggetto Tag. Il tasto è impostato su tag colour.
Tag.exportable entity.metadata.threat.detection_fields.value Mappatura diretta dal campo exportable nell'oggetto Tag. Il tasto è impostato su tag exportable.
Tag.hide_tag entity.metadata.threat.detection_fields.value Mappatura diretta dal campo hide_tag nell'oggetto Tag. Il tasto è impostato su tag hide_tag.
Tag.id entity.metadata.threat.detection_fields.value Mappatura diretta dal campo id nell'oggetto Tag. Il tasto è impostato su tag id.
Tag.is_custom_galaxy entity.metadata.threat.detection_fields.value Mappatura diretta dal campo is_custom_galaxy nell'oggetto Tag. Il tasto è impostato su tag is_custom_galaxy.
Tag.is_galaxy entity.metadata.threat.detection_fields.value Mappatura diretta dal campo is_galaxy nell'oggetto Tag. Il tasto è impostato su tag is_galaxy.
Tag.isinherited entity.metadata.threat.detection_fields.value Mappatura diretta dal campo isinherited nell'oggetto Tag. Il tasto è impostato su tag isinherited.
Tag.name entity.metadata.threat.detection_fields.value Mappatura diretta dal campo name nell'oggetto Tag. Il tasto è impostato su tag name.
Tag.numerical_value entity.metadata.threat.detection_fields.value Mappatura diretta dal campo numerical_value nell'oggetto Tag. Il tasto è impostato su tag numerical_value.
Tag.user_id entity.metadata.threat.detection_fields.value Mappatura diretta dal campo user_id nell'oggetto Tag. Il tasto è impostato su tag user_id.
threat_level ioc.raw_severity Mappatura diretta dal campo threat_level.
threat_level entity.metadata.threat.severity_details Mappatura diretta dal campo threat_level.
threat_level_id entity.entity.labels.value Mappatura diretta dal campo threat_level_id. Il tasto è impostato su threat_level_id.
ts1 ioc.active_timerange.start Mappatura diretta dal campo ts1. Il valore viene analizzato come data.
ts1 entity.metadata.interval.start_time Mappatura diretta dal campo ts1. Il valore viene analizzato come data.
entity.entity.file.full_path Mappato se type è filename.
entity.entity.file.md5 Mappato se type è md5.
entity.entity.file.sha1 Mappato se type è sha1.
entity.entity.file.sha256 Mappato se type è sha256.
entity.entity.hostname Mappato se type è domain.
entity.entity.ip Mappato se type è ip-dst, ip-dst|port o ip-src. Il valore viene estratto utilizzando un pattern grok.
entity.entity.port Mappato se il campo port non è vuoto. Il valore viene convertito in un numero intero.
entity.entity.resource.name Mappato se type è mutex.
entity.entity.resource.resource_subtype Mappato se type è regkey. Il valore è impostato su regkey.
entity.entity.resource.resource_type Mappato se type è mutex o regkey. Il valore è impostato rispettivamente su MUTEX o STORAGE_OBJECT.
entity.entity.registry.registry_key Mappato se type è regkey.
entity.entity.url Mappato se type è uri o url.
entity.metadata.collected_timestamp Il valore è impostato sul timestamp della voce di log non elaborata.
entity.metadata.description Il valore è impostato sul campo type se il log non elaborato è in formato CSV. In caso contrario, viene impostato sul campo info.
entity.metadata.entity_type Il valore viene determinato in base al campo type o log_type. Può essere DOMAIN_NAME, FILE, IP_ADDRESS, MUTEX, RESOURCE o URL.
entity.metadata.interval.end_time Il valore è impostato su un valore predefinito di 253402300799 secondi.
entity.metadata.interval.start_time Il valore è impostato sul campo first_seen se non è vuoto. In caso contrario, viene impostato su un valore predefinito di 1 secondo o sul timestamp della voce di log non elaborata.
entity.metadata.product_name Il valore è impostato su MISP.
entity.metadata.threat.confidence Il valore è impostato su UNKNOWN_CONFIDENCE se il campo confidence è vuoto o f. In caso contrario, è impostato su HIGH_CONFIDENCE, MEDIUM_CONFIDENCE o LOW_CONFIDENCE in base al valore del campo confidence.
entity.metadata.threat.confidence_details Mappatura diretta dal campo confidence.
entity.metadata.threat.detection_fields Il valore è un elenco di coppie chiave-valore estratte da vari campi del log non elaborato.
entity.metadata.vendor_name Il valore è impostato su MISP.
ioc.active_timerange.end Il valore è impostato sul campo last_seen se non è vuoto.
ioc.active_timerange.start Il valore è impostato sul campo ts1 o first_seen se non sono vuoti. In caso contrario, viene impostato su un valore predefinito di 1 secondo.
ioc.categorization Il valore è impostato su misp_category IOCs se il log non elaborato è in formato CSV. In caso contrario, viene impostato sul campo category nell'oggetto Attribute o log.
ioc.confidence_score Mappatura diretta dal campo confidence.
ioc.description Il valore viene generato combinando il campo description con il campo event_info, separati da - additional info:.
ioc.domain_and_ports.domain Mappato se type o log_type è domain.
ioc.feed_name Il valore è impostato su MISP se il campo event_source_org è vuoto. In caso contrario, viene impostato sul campo event_source_org.
ioc.ip_and_ports.ip_address Mappato se il campo ip non è vuoto. Il valore viene convertito in un indirizzo IP.
ioc.ip_and_ports.ports Mappato se il campo port non è vuoto. Il valore viene convertito in un numero intero senza segno.
ioc.raw_severity Mappatura diretta dal campo threat_level.
timestamp Il valore è impostato sul timestamp della voce di log non elaborata.

Hai bisogno di ulteriore assistenza? Ricevi risposte dai membri della community e dai professionisti di Google SecOps.