Raccogliere i log di Cisco AMP for Endpoints

Supportato in:

Questo documento spiega come importare i log di Cisco AMP for Endpoints in Google Security Operations utilizzando Amazon S3. Il parser trasforma i log non elaborati in formato JSON in un formato strutturato conforme a UDM di Chronicle. Estrae i campi dagli oggetti JSON nidificati, li mappa allo schema UDM, identifica le categorie di eventi, assegna i livelli di gravità e, infine, genera un output di eventi unificato, segnalando gli avvisi di sicurezza quando vengono soddisfatte condizioni specifiche.

Prima di iniziare

  • Un'istanza Google SecOps
  • Accesso con privilegi alla console Cisco AMP for Endpoints
  • Accesso privilegiato ad AWS (S3, IAM, Lambda, EventBridge)

Raccogli i prerequisiti di Cisco AMP for Endpoints (ID, chiavi API, ID organizzazione, token)

  1. Accedi alla console Cisco AMP for Endpoints.
  2. Vai ad Account > Credenziali API.
  3. Fai clic su Nuova credenziale API per creare una nuova chiave API e un nuovo ID client.
  4. Fornisci i seguenti dettagli di configurazione:
    • Nome applicazione: inserisci un nome (ad esempio, Chronicle SecOps Integration).
    • Ambito: seleziona Sola lettura per il polling di base degli eventi oppure Lettura e scrittura se prevedi di creare stream di eventi.
  5. Fai clic su Crea.
  6. Copia e salva in una posizione sicura i seguenti dettagli:
    • ID client API di terze parti
    • Chiave API
    • URL di base dell'API: a seconda della regione:
      • Stati Uniti: https://api.amp.cisco.com
      • UE: https://api.eu.amp.cisco.com
      • APJC: https://api.apjc.amp.cisco.com

Configura il bucket AWS S3 e IAM per Google SecOps

  1. Crea un bucket Amazon S3 seguendo questa guida utente: Creazione di un bucket
  2. Salva il nome e la regione del bucket per riferimento futuro (ad esempio, cisco-amp-logs).
  3. Crea un utente seguendo questa guida utente: Creazione di un utente IAM.
  4. Seleziona l'utente creato.
  5. Seleziona la scheda Credenziali di sicurezza.
  6. Fai clic su Crea chiave di accesso nella sezione Chiavi di accesso.
  7. Seleziona Servizio di terze parti come Caso d'uso.
  8. Fai clic su Avanti.
  9. (Facoltativo) Aggiungi un tag di descrizione.
  10. Fai clic su Crea chiave di accesso.
  11. Fai clic su Scarica file CSV per salvare la chiave di accesso e la chiave di accesso segreta per riferimento futuro.
  12. Fai clic su Fine.
  13. Seleziona la scheda Autorizzazioni.
  14. Fai clic su Aggiungi autorizzazioni nella sezione Criteri per le autorizzazioni.
  15. Seleziona Aggiungi autorizzazioni.
  16. Seleziona Allega direttamente i criteri.
  17. Cerca i criteri AmazonS3FullAccess.
  18. Seleziona la policy.
  19. Fai clic su Avanti.
  20. Fai clic su Aggiungi autorizzazioni.

Configura il ruolo e il criterio IAM per i caricamenti S3

  1. Nella console AWS, vai a IAM > Policy.
  2. Fai clic su Crea criterio > scheda JSON.
  3. Inserisci la seguente policy:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "AllowPutObjects",
          "Effect": "Allow",
          "Action": "s3:PutObject",
          "Resource": "arn:aws:s3:::cisco-amp-logs/*"
        },
        {
          "Sid": "AllowGetStateObject",
          "Effect": "Allow",
          "Action": "s3:GetObject",
          "Resource": "arn:aws:s3:::cisco-amp-logs/cisco-amp-events/state.json"
        }
      ]
    }
    
    • Sostituisci cisco-amp-logs se hai inserito un nome bucket diverso.
  4. Fai clic su Avanti > Crea criterio.

  5. Vai a IAM > Ruoli > Crea ruolo > Servizio AWS > Lambda.

  6. Allega il criterio appena creato.

  7. Assegna al ruolo il nome cisco-amp-lambda-role e fai clic su Crea ruolo.

Crea la funzione Lambda

  1. Nella console AWS, vai a Lambda > Funzioni > Crea funzione.
  2. Fai clic su Crea autore da zero.
  3. Fornisci i seguenti dettagli di configurazione:

    Impostazione Valore
    Nome cisco-amp-events-collector
    Tempo di esecuzione Python 3.13
    Architettura x86_64
    Ruolo di esecuzione cisco-amp-lambda-role
  4. Dopo aver creato la funzione, apri la scheda Codice, elimina lo stub e inserisci il seguente codice (cisco-amp-events-collector.py):

    import json
    import boto3
    import urllib3
    import base64
    from datetime import datetime, timedelta
    import os
    import logging
    
    # Configure logging
    logger = logging.getLogger()
    logger.setLevel(logging.INFO)
    
    # AWS S3 client and HTTP pool manager
    s3_client = boto3.client('s3')
    http = urllib3.PoolManager()
    
    def lambda_handler(event, context):
        """
        AWS Lambda handler to fetch Cisco AMP events and store them in S3
        """
    
        try:
            # Get environment variables
            s3_bucket = os.environ['S3_BUCKET']
            s3_prefix = os.environ['S3_PREFIX']
            state_key = os.environ['STATE_KEY']
            api_client_id = os.environ['AMP_CLIENT_ID']
            api_key = os.environ['AMP_API_KEY']
            api_base = os.environ['API_BASE']
    
            # Optional parameters
            page_size = int(os.environ.get('PAGE_SIZE', '500'))
            max_pages = int(os.environ.get('MAX_PAGES', '10'))
    
            logger.info(f"Starting Cisco AMP events collection for bucket: {s3_bucket}")
    
            # Get last run timestamp from state file
            last_timestamp = get_last_timestamp(s3_bucket, state_key)
            if not last_timestamp:
                last_timestamp = (datetime.utcnow() - timedelta(days=1)).isoformat() + 'Z'
    
            # Create Basic Auth header
            auth_header = base64.b64encode(f"{api_client_id}:{api_key}".encode()).decode()
            headers = {
                'Authorization': f'Basic {auth_header}',
                'Accept': 'application/json'
            }
    
            # Build initial API URL
            base_url = f"{api_base}/v1/events"
            next_url = f"{base_url}?limit={page_size}&start_date={last_timestamp}"
    
            all_events = []
            page_count = 0
    
            while next_url and page_count < max_pages:
                logger.info(f"Fetching page {page_count + 1} from: {next_url}")
    
                # Make API request using urllib3
                response = http.request('GET', next_url, headers=headers, timeout=60)
    
                if response.status != 200:
                    raise RuntimeError(f"API request failed: {response.status} {response.data[:256]!r}")
    
                data = json.loads(response.data.decode('utf-8'))
    
                # Extract events from response
                events = data.get('data', [])
                if events:
                    all_events.extend(events)
                    logger.info(f"Collected {len(events)} events from page {page_count + 1}")
    
                    # Check for next page
                    next_url = data.get('metadata', {}).get('links', {}).get('next')
                    page_count += 1
                else:
                    logger.info("No events found on current page")
                    break
    
            logger.info(f"Total events collected: {len(all_events)}")
    
            # Store events in S3 if any were collected
            if all_events:
                timestamp_str = datetime.utcnow().strftime('%Y%m%d_%H%M%S')
                s3_key = f"{s3_prefix}cisco_amp_events_{timestamp_str}.ndjson"
    
                # Convert events to NDJSON format (one JSON object per line)
                ndjson_content = 'n'.join(json.dumps(event) for event in all_events)
    
                # Upload to S3
                s3_client.put_object(
                    Bucket=s3_bucket,
                    Key=s3_key,
                    Body=ndjson_content.encode('utf-8'),
                    ContentType='application/x-ndjson'
                )
    
                logger.info(f"Uploaded {len(all_events)} events to s3://{s3_bucket}/{s3_key}")
    
            # Update state file with current timestamp
            current_timestamp = datetime.utcnow().isoformat() + 'Z'
            update_state(s3_bucket, state_key, current_timestamp)
    
            return {
                'statusCode': 200,
                'body': json.dumps({
                    'message': 'Success',
                    'events_collected': len(all_events),
                    'pages_processed': page_count
                })
            }
    
        except Exception as e:
            logger.error(f"Error in lambda_handler: {str(e)}")
            return {
                'statusCode': 500,
                'body': json.dumps({
                    'error': str(e)
                })
            }
    
    def get_last_timestamp(bucket, state_key):
        """
        Get the last run timestamp from S3 state file
        """
        try:
            response = s3_client.get_object(Bucket=bucket, Key=state_key)
            state_data = json.loads(response['Body'].read().decode('utf-8'))
            return state_data.get('last_timestamp')
        except s3_client.exceptions.NoSuchKey:
            logger.info("No state file found, starting from 24 hours ago")
            return None
        except Exception as e:
            logger.warning(f"Error reading state file: {str(e)}")
            return None
    
    def update_state(bucket, state_key, timestamp):
        """
        Update the state file with the current timestamp
        """
        try:
            state_data = {
                'last_timestamp': timestamp,
                'updated_at': datetime.utcnow().isoformat() + 'Z'
            }
    
            s3_client.put_object(
                Bucket=bucket,
                Key=state_key,
                Body=json.dumps(state_data).encode('utf-8'),
                ContentType='application/json'
            )
    
            logger.info(f"Updated state file with timestamp: {timestamp}")
    
        except Exception as e:
            logger.error(f"Error updating state file: {str(e)}")
    
  5. Vai a Configurazione > Variabili di ambiente.

  6. Fai clic su Modifica > Aggiungi nuova variabile di ambiente.

  7. Inserisci le seguenti variabili di ambiente fornite, sostituendole con i tuoi valori.

    Chiave Valore di esempio
    S3_BUCKET cisco-amp-logs
    S3_PREFIX cisco-amp-events/
    STATE_KEY cisco-amp-events/state.json
    AMP_CLIENT_ID <your-client-id>
    AMP_API_KEY <your-api-key>
    API_BASE https://api.amp.cisco.com (o l'URL della tua regione)
    PAGE_SIZE 500
    MAX_PAGES 10
  8. Dopo aver creato la funzione, rimani sulla relativa pagina (o apri Lambda > Funzioni > cisco-amp-events-collector).

  9. Seleziona la scheda Configurazione.

  10. Nel riquadro Configurazione generale, fai clic su Modifica.

  11. Modifica Timeout impostando 5 minuti (300 secondi) e fai clic su Salva.

Creare una pianificazione EventBridge

  1. Vai a Amazon EventBridge > Scheduler > Crea pianificazione.
  2. Fornisci i seguenti dettagli di configurazione:
    • Programma ricorrente: Tariffa (1 hour).
    • Destinazione: la tua funzione Lambda cisco-amp-events-collector.
    • Nome: cisco-amp-events-collector-1h
  3. Fai clic su Crea pianificazione.

(Facoltativo) Crea chiavi e utenti IAM di sola lettura per Google SecOps

  1. Vai alla console AWS > IAM > Utenti > Aggiungi utenti.
  2. Fai clic su Add users (Aggiungi utenti).
  3. Fornisci i seguenti dettagli di configurazione:
    • Utente: inserisci secops-reader.
    • Tipo di accesso: seleziona Chiave di accesso - Accesso programmatico.
  4. Fai clic su Crea utente.
  5. Collega la criterio per la lettura minima (personalizzata): Utenti > secops-reader > Autorizzazioni > Aggiungi autorizzazioni > Collega le norme direttamente > Crea norma.
  6. Nell'editor JSON, inserisci la seguente policy:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": ["s3:GetObject"],
          "Resource": "arn:aws:s3:::cisco-amp-logs/*"
        },
        {
          "Effect": "Allow",
          "Action": ["s3:ListBucket"],
          "Resource": "arn:aws:s3:::cisco-amp-logs"
        }
      ]
    }
    
  7. Imposta il nome su secops-reader-policy.

  8. Vai a Crea criterio > cerca/seleziona > Avanti > Aggiungi autorizzazioni.

  9. Vai a Credenziali di sicurezza > Chiavi di accesso > Crea chiave di accesso.

  10. Scarica il file CSV (questi valori vengono inseriti nel feed).

Configura un feed in Google SecOps per importare i log di Cisco AMP for Endpoints

  1. Vai a Impostazioni SIEM > Feed.
  2. Fai clic su + Aggiungi nuovo feed.
  3. Nel campo Nome feed, inserisci un nome per il feed (ad esempio, Cisco AMP for Endpoints logs).
  4. Seleziona Amazon S3 V2 come Tipo di origine.
  5. Seleziona Cisco AMP come Tipo di log.
  6. Fai clic su Avanti.
  7. Specifica i valori per i seguenti parametri di input:
    • URI S3: s3://cisco-amp-logs/cisco-amp-events/
    • Opzioni di eliminazione dell'origine: seleziona l'opzione di eliminazione in base alle tue preferenze.
    • Età massima del file: includi i file modificati nell'ultimo numero di giorni. Il valore predefinito è 180 giorni.
    • ID chiave di accesso: chiave di accesso utente con accesso al bucket S3.
    • Chiave di accesso segreta: chiave segreta dell'utente con accesso al bucket S3.
    • Spazio dei nomi dell'asset: lo spazio dei nomi dell'asset.
    • Etichette di importazione: l'etichetta applicata agli eventi di questo feed.
  8. Fai clic su Avanti.
  9. Controlla la nuova configurazione del feed nella schermata Finalizza e poi fai clic su Invia.

Tabella di mappatura UDM

Campo log Mappatura UDM Logic
attivo read_only_udm.principal.asset.active Mappato direttamente da computer.active
connector_guid read_only_udm.principal.asset.uuid Mappato direttamente da computer.connector_guid
data read_only_udm.metadata.event_timestamp.seconds Mappato direttamente da date dopo la conversione in timestamp
Rilevamento read_only_udm.security_result.threat_name Mappato direttamente da detection
detection_id read_only_udm.security_result.detection_fields.value Mappato direttamente da detection_id
disposizione read_only_udm.security_result.description Mappato direttamente da file.disposition
error.error_code read_only_udm.security_result.detection_fields.value Mappato direttamente da error.error_code
error.description read_only_udm.security_result.detection_fields.value Mappato direttamente da error.description
event_type read_only_udm.metadata.product_event_type Mappato direttamente da event_type
event_type_id read_only_udm.metadata.product_log_id Mappato direttamente da event_type_id
external_ip read_only_udm.principal.asset.external_ip Mappato direttamente da computer.external_ip
file.file_name read_only_udm.target.file.names Mappato direttamente da file.file_name
file.file_path read_only_udm.target.file.full_path Mappato direttamente da file.file_path
file.identity.md5 read_only_udm.security_result.about.file.md5 Mappato direttamente da file.identity.md5
file.identity.md5 read_only_udm.target.file.md5 Mappato direttamente da file.identity.md5
file.identity.sha1 read_only_udm.security_result.about.file.sha1 Mappato direttamente da file.identity.sha1
file.identity.sha1 read_only_udm.target.file.sha1 Mappato direttamente da file.identity.sha1
file.identity.sha256 read_only_udm.security_result.about.file.sha256 Mappato direttamente da file.identity.sha256
file.identity.sha256 read_only_udm.target.file.sha256 Mappato direttamente da file.identity.sha256
file.parent.disposition read_only_udm.target.resource.attribute.labels.value Mappato direttamente da file.parent.disposition
file.parent.file_name read_only_udm.target.resource.attribute.labels.value Mappato direttamente da file.parent.file_name
file.parent.identity.md5 read_only_udm.target.resource.attribute.labels.value Mappato direttamente da file.parent.identity.md5
file.parent.identity.sha1 read_only_udm.target.resource.attribute.labels.value Mappato direttamente da file.parent.identity.sha1
file.parent.identity.sha256 read_only_udm.target.resource.attribute.labels.value Mappato direttamente da file.parent.identity.sha256
file.parent.process_id read_only_udm.security_result.about.process.parent_process.pid Mappato direttamente da file.parent.process_id
file.parent.process_id read_only_udm.target.process.parent_process.pid Mappato direttamente da file.parent.process_id
nome host read_only_udm.principal.asset.hostname Mappato direttamente da computer.hostname
nome host read_only_udm.target.hostname Mappato direttamente da computer.hostname
nome host read_only_udm.target.asset.hostname Mappato direttamente da computer.hostname
ip read_only_udm.principal.asset.ip Mappato direttamente da computer.network_addresses.ip
ip read_only_udm.principal.ip Mappato direttamente da computer.network_addresses.ip
ip read_only_udm.security_result.about.ip Mappato direttamente da computer.network_addresses.ip
mac read_only_udm.principal.mac Mappato direttamente da computer.network_addresses.mac
mac read_only_udm.security_result.about.mac Mappato direttamente da computer.network_addresses.mac
gravità read_only_udm.security_result.severity Mappato da severity in base alla seguente logica:
- "Medio" -> "MEDIUM"
- "Alto" o "Critico" -> "HIGH"
- "Basso" -> "LOW"
- Altrimenti -> "UNKNOWN_SEVERITY"
timestamp read_only_udm.metadata.event_timestamp.seconds Mappato direttamente da timestamp
utente read_only_udm.security_result.about.user.user_display_name Mappato direttamente da computer.user
utente read_only_udm.target.user.user_display_name Mappato direttamente da computer.user
vulnerabilities.cve read_only_udm.extensions.vulns.vulnerabilities.cve_id Mappato direttamente da vulnerabilities.cve
vulnerabilities.name read_only_udm.extensions.vulns.vulnerabilities.name Mappato direttamente da vulnerabilities.name
vulnerabilities.score read_only_udm.extensions.vulns.vulnerabilities.cvss_base_score Mappato direttamente da vulnerabilities.score dopo la conversione in float
vulnerabilities.url read_only_udm.extensions.vulns.vulnerabilities.vendor_knowledge_base_article_id Mappato direttamente da vulnerabilities.url
vulnerabilities.version read_only_udm.extensions.vulns.vulnerabilities.cvss_version Mappato direttamente da vulnerabilities.version
is_alert Imposta su true se event_type è uno dei seguenti valori: "Threat Detected" (Minaccia rilevata), "Exploit Prevention" (Prevenzione di exploit), "Executed malware" (Malware eseguito), "Potential Dropper Infection" (Potenziale infezione da dropper), "Multiple Infected Files" (Più file infetti), "Vulnerable Application Detected" (Applicazione vulnerabile rilevata) o se security_result.severity è "HIGH" (ALTO)
is_significant Imposta su true se event_type è uno dei seguenti valori: "Threat Detected" (Minaccia rilevata), "Exploit Prevention" (Prevenzione di exploit), "Executed malware" (Malware eseguito), "Potential Dropper Infection" (Potenziale infezione da dropper), "Multiple Infected Files" (Più file infetti), "Vulnerable Application Detected" (Applicazione vulnerabile rilevata) o se security_result.severity è "HIGH" (ALTO)
read_only_udm.metadata.event_type Determinato in base ai valori event_type e security_result.severity.
: se event_type è uno dei seguenti valori: "Malware eseguito", "Minaccia rilevata", "Potenziale infezione da dropper", "Rilevamento di Cloud Recall", "Rilevamento di attività dannosa", "Prevenzione di exploit", "Più file infetti", "Cloud IOC", "Protezione dei processi di sistema", "Applicazione vulnerabile rilevata", "Minaccia messa in quarantena", "Esecuzione bloccata", "Quarantena di Cloud Recall riuscita", "Ripristino dalla quarantena di Cloud Recall non riuscito", "Tentativo di quarantena di Cloud Recall non riuscito", "Errore di quarantena", il tipo di evento è impostato su "SCAN_FILE".
: se security_result.severity è "HIGH", il tipo di evento è impostato su "SCAN_FILE".
: se sia has_principal che has_target sono true, il tipo di evento è impostato su "SCAN_UNCATEGORIZED".
- In caso contrario, il tipo di evento è impostato su "GENERIC_EVENT".
read_only_udm.metadata.log_type Imposta su "CISCO_AMP"
read_only_udm.metadata.vendor_name Imposta su "CISCO_AMP"
read_only_udm.security_result.about.file.full_path Mappato direttamente da file.file_path
read_only_udm.security_result.about.hostname Mappato direttamente da computer.hostname
read_only_udm.security_result.about.user.user_display_name Mappato direttamente da computer.user
read_only_udm.security_result.detection_fields.key Imposta "ID rilevamento" per detection_id, "Codice errore" per error.error_code, "Descrizione errore" per error.description, "Disposizione principale" per file.parent.disposition, "Nome file principale" per file.parent.file_name, "MD5 principale" per file.parent.identity.md5, "SHA1 principale" per file.parent.identity.sha1 e "SHA256 principale" per file.parent.identity.sha256
read_only_udm.security_result.summary Imposta su event_type se event_type è uno dei seguenti: "Minaccia rilevata", "Prevenzione exploit", "Malware eseguito", "Potenziale infezione da dropper", "Più file infetti", "Applicazione vulnerabile rilevata" o se security_result.severity è "ALTO"
read_only_udm.target.asset.ip Mappato direttamente da computer.network_addresses.ip
read_only_udm.target.resource.attribute.labels.key Imposta "Disposizione principale" per file.parent.disposition, "Nome file principale" per file.parent.file_name, "MD5 principale" per file.parent.identity.md5, "SHA1 principale" per file.parent.identity.sha1 e "SHA256 principale" per file.parent.identity.sha256
timestamp.seconds Mappato direttamente da date dopo la conversione in timestamp

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