Raccogliere i log di Cisco AMP for Endpoints
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)
- Accedi alla console Cisco AMP for Endpoints.
- Vai ad Account > Credenziali API.
- Fai clic su Nuova credenziale API per creare una nuova chiave API e un nuovo ID client.
- 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.
- Nome applicazione: inserisci un nome (ad esempio,
- Fai clic su Crea.
- 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
- Stati Uniti:
Configura il bucket AWS S3 e IAM per Google SecOps
- Crea un bucket Amazon S3 seguendo questa guida utente: Creazione di un bucket
- Salva il nome e la regione del bucket per riferimento futuro (ad esempio,
cisco-amp-logs). - Crea un utente seguendo questa guida utente: Creazione di un utente IAM.
- Seleziona l'utente creato.
- Seleziona la scheda Credenziali di sicurezza.
- Fai clic su Crea chiave di accesso nella sezione Chiavi di accesso.
- Seleziona Servizio di terze parti come Caso d'uso.
- Fai clic su Avanti.
- (Facoltativo) Aggiungi un tag di descrizione.
- Fai clic su Crea chiave di accesso.
- Fai clic su Scarica file CSV per salvare la chiave di accesso e la chiave di accesso segreta per riferimento futuro.
- Fai clic su Fine.
- Seleziona la scheda Autorizzazioni.
- Fai clic su Aggiungi autorizzazioni nella sezione Criteri per le autorizzazioni.
- Seleziona Aggiungi autorizzazioni.
- Seleziona Allega direttamente i criteri.
- Cerca i criteri AmazonS3FullAccess.
- Seleziona la policy.
- Fai clic su Avanti.
- Fai clic su Aggiungi autorizzazioni.
Configura il ruolo e il criterio IAM per i caricamenti S3
- Nella console AWS, vai a IAM > Policy.
- Fai clic su Crea criterio > scheda JSON.
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-logsse hai inserito un nome bucket diverso.
- Sostituisci
Fai clic su Avanti > Crea criterio.
Vai a IAM > Ruoli > Crea ruolo > Servizio AWS > Lambda.
Allega il criterio appena creato.
Assegna al ruolo il nome
cisco-amp-lambda-rolee fai clic su Crea ruolo.
Crea la funzione Lambda
- Nella console AWS, vai a Lambda > Funzioni > Crea funzione.
- Fai clic su Crea autore da zero.
Fornisci i seguenti dettagli di configurazione:
Impostazione Valore Nome cisco-amp-events-collectorTempo di esecuzione Python 3.13 Architettura x86_64 Ruolo di esecuzione cisco-amp-lambda-roleDopo 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)}")Vai a Configurazione > Variabili di ambiente.
Fai clic su Modifica > Aggiungi nuova variabile di ambiente.
Inserisci le seguenti variabili di ambiente fornite, sostituendole con i tuoi valori.
Chiave Valore di esempio S3_BUCKETcisco-amp-logsS3_PREFIXcisco-amp-events/STATE_KEYcisco-amp-events/state.jsonAMP_CLIENT_ID<your-client-id>AMP_API_KEY<your-api-key>API_BASEhttps://api.amp.cisco.com(o l'URL della tua regione)PAGE_SIZE500MAX_PAGES10Dopo aver creato la funzione, rimani sulla relativa pagina (o apri Lambda > Funzioni > cisco-amp-events-collector).
Seleziona la scheda Configurazione.
Nel riquadro Configurazione generale, fai clic su Modifica.
Modifica Timeout impostando 5 minuti (300 secondi) e fai clic su Salva.
Creare una pianificazione EventBridge
- Vai a Amazon EventBridge > Scheduler > Crea pianificazione.
- 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
- Programma ricorrente: Tariffa (
- Fai clic su Crea pianificazione.
(Facoltativo) Crea chiavi e utenti IAM di sola lettura per Google SecOps
- Vai alla console AWS > IAM > Utenti > Aggiungi utenti.
- Fai clic su Add users (Aggiungi utenti).
- Fornisci i seguenti dettagli di configurazione:
- Utente: inserisci
secops-reader. - Tipo di accesso: seleziona Chiave di accesso - Accesso programmatico.
- Utente: inserisci
- Fai clic su Crea utente.
- Collega la criterio per la lettura minima (personalizzata): Utenti > secops-reader > Autorizzazioni > Aggiungi autorizzazioni > Collega le norme direttamente > Crea norma.
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" } ] }Imposta il nome su
secops-reader-policy.Vai a Crea criterio > cerca/seleziona > Avanti > Aggiungi autorizzazioni.
Vai a Credenziali di sicurezza > Chiavi di accesso > Crea chiave di accesso.
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
- Vai a Impostazioni SIEM > Feed.
- Fai clic su + Aggiungi nuovo feed.
- Nel campo Nome feed, inserisci un nome per il feed (ad esempio,
Cisco AMP for Endpoints logs). - Seleziona Amazon S3 V2 come Tipo di origine.
- Seleziona Cisco AMP come Tipo di log.
- Fai clic su Avanti.
- 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.
- URI S3:
- Fai clic su Avanti.
- 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.