Raccogliere i log di Qualys Virtual Scanner
Questo parser trasforma i log non elaborati di Qualys Virtual Scanner in formato JSON in un formato strutturato conforme a UDM di Google Security Operations. Estrae i campi pertinenti, come le informazioni sugli asset, i dettagli della scansione e le vulnerabilità rilevate, mappandoli ai campi UDM corrispondenti per una rappresentazione e un'analisi coerenti.
Prima di iniziare
Assicurati di soddisfare i seguenti prerequisiti:
- Istanza Google Security Operations.
- Accesso privilegiato a Google Cloud.
- Accesso con privilegi a Qualys.
Abilita le API richieste:
- Accedi alla Google Cloud console.
- Vai ad API e servizi > Libreria.
- Cerca le seguenti API e attivale:
- API Cloud Functions
- API Cloud Scheduler
- Cloud Pub/Sub (necessario per Cloud Scheduler per richiamare le funzioni)
Crea un Google Cloud bucket di archiviazione
- Accedi alla Google Cloud console.
Vai alla pagina Bucket Cloud Storage.
Fai clic su Crea.
Configura il bucket:
- Nome: inserisci un nome univoco che soddisfi i requisiti per i nomi dei bucket (ad esempio, qualys-vscanner-bucket).
- Scegli dove archiviare i tuoi dati: seleziona una località.
- Scegli una classe di archiviazione per i tuoi dati: seleziona una classe di archiviazione predefinita per il bucket oppure seleziona Autoclass per la gestione automatica della classe di archiviazione.
- Scegli come controllare l'accesso agli oggetti: seleziona no per applicare la prevenzione dell'accesso pubblico e seleziona un modello di controllo dell'accesso per gli oggetti del bucket.
- Classe di archiviazione: scegli in base alle tue esigenze (ad esempio, Standard).
Fai clic su Crea.
Crea un service account Google Cloud
- Vai a IAM e amministrazione > Service Accounts.
- Crea un nuovo account di servizio.
- Assegna un nome descrittivo (ad esempio qualys-user).
- Concedi al account di servizio il ruolo Storage Object Admin nel bucket Cloud Storage che hai creato nel passaggio precedente.
- Concedi al account di servizio il ruolo Invoker di Cloud Functions.
- Crea una chiave SSH per il account di servizio.
- Scarica un file della chiave JSON per il account di servizio. Conserva questo file in modo sicuro.
(Facoltativo) Crea un utente API dedicato in Qualys
- Accedi alla console Qualys.
- Vai a Utenti.
- Fai clic su Nuovo > Utente.
- Inserisci le informazioni generali richieste per l'utente.
- Seleziona la scheda Ruolo utente.
- Assicurati che la casella di controllo Accesso API sia selezionata per il ruolo.
- Fai clic su Salva.
Identificare l'URL API Qualys specifico
Opzione 1
Identifica i tuoi URL come indicato nell'identificazione della piattaforma.
Opzione 2
- Accedi alla console Qualys.
- Vai ad Aiuto > Informazioni.
- Scorri per visualizzare queste informazioni nella sezione Security Operations Center (SOC).
- Copia l'URL dell'API Qualys.
Configura la Cloud Function
- Vai a Cloud Functions nella console Google Cloud .
- Fai clic su Crea funzione.
Configura la funzione:
- Nome: inserisci un nome per la funzione (ad esempio, fetch-qualys-vscanner).
- Regione: seleziona una regione vicina al tuo bucket.
- Trigger: scegli il trigger HTTP, se necessario, o Cloud Pub/Sub per l'esecuzione pianificata.
- Autenticazione: protetto con l'autenticazione.
- Scrivi il codice con un editor incorporato:
```python from google.cloud import storage import requests import base64 import json # Google Cloud Storage Configuration BUCKET_NAME = "<bucket-name>" FILE_NAME = "qualys_virtual_scanners.json" # Qualys API Credentials QUALYS_USERNAME = "qualys-username" QUALYS_PASSWORD = "<qualys-password>" QUALYS_BASE_URL = "https://<qualys_base_url>" # for example, https://qualysapi.qualys.com def fetch_virtual_scanners(): """Fetch Virtual Scanner details from Qualys.""" auth = base64.b64encode(f"{QUALYS_USERNAME}:{QUALYS_PASSWORD}".encode()).decode() headers = { "Authorization": f"Basic {auth}", "Content-Type": "application/xml" } url = f"{QUALYS_BASE_URL}/api/2.0/fo/scanner/" payload = { "action": "list", "scanner_type": "virtual" } response = requests.post(url, headers=headers, data=payload) response.raise_for_status() return response.text # Qualys API returns XML data def upload_to_gcs(data): """Upload data to Google Cloud Storage.""" client = storage.Client() bucket = client.get_bucket(BUCKET_NAME) blob = bucket.blob(FILE_NAME) blob.upload_from_string(data, content_type="application/xml") def main(request): """Cloud Function entry point.""" try: scanners = fetch_virtual_scanners() upload_to_gcs(scanners) return "Qualys Virtual Scanners data uploaded to Cloud Storage successfully!" except Exception as e: return f"An error occurred: {e}", 500 ```
Fai clic su Esegui il deployment dopo aver completato la configurazione.
Configura Cloud Scheduler
- Vai a Cloud Scheduler nella console Google Cloud .
- Fai clic su Crea job.
Configura il job:
- Nome: inserisci un nome per il job (ad esempio, trigger-fetch-qualys-vscanner).
- Frequenza: utilizza la sintassi cron per specificare la pianificazione (ad esempio, 0 0 * * * per tutti i giorni a mezzanotte).
- Fuso orario: imposta il fuso orario che preferisci.
- Tipo di trigger: scegli HTTP.
- URL trigger: inserisci l'URL della Cloud Function (che si trova nei dettagli della funzione dopo il deployment).
- Metodo: scegli POST.
Crea il job.
Configurare i feed
Esistono due diversi punti di accesso per configurare i feed nella piattaforma Google SecOps:
- Impostazioni SIEM > Feed
- Hub dei contenuti > Pacchetti di contenuti
Configura i feed da Impostazioni SIEM > Feed
Per configurare un feed:
- Vai a Impostazioni SIEM > Feed.
- Fai clic su Aggiungi nuovo feed.
- Nella pagina successiva, fai clic su Configura un singolo feed.
- Nel campo Nome feed, inserisci un nome per il feed, ad esempio Qualys Virtual Scanner Logs.
- Seleziona Google Cloud Storage come Tipo di origine.
- Seleziona Qualys Virtual Scanner come Tipo di log.
- Fai clic su Avanti.
Specifica i valori per i seguenti parametri di input:
- URI bucket di archiviazione: l'URI di origine del bucket di archiviazione. Google Cloud
- URI è un: seleziona Singolo file.
- Opzione di eliminazione dell'origine: seleziona l'opzione di eliminazione in base alle tue preferenze.
Fai clic su Avanti.
Controlla la nuova configurazione del feed nella schermata Finalizza e poi fai clic su Invia.
Configurare i feed dall'hub dei contenuti
Specifica i valori per i seguenti campi:
- URI bucket di archiviazione: l'URI di origine del bucket di archiviazione. Google Cloud
- URI è un: seleziona Singolo file.
Opzione di eliminazione dell'origine: seleziona l'opzione di eliminazione in base alle tue preferenze.
Opzioni avanzate
- Nome feed: un valore precompilato che identifica il feed.
- Tipo di origine: metodo utilizzato per raccogliere i log in Google SecOps.
- Spazio dei nomi dell'asset: lo spazio dei nomi associato al feed.
- Etichette di importazione: etichette applicate a tutti gli eventi di questo feed.
Tabella di mappatura UDM
Campo log | Mappatura UDM | Logic |
---|---|---|
ASSET_ID | entity.entity.asset.asset_id | Mappatura diretta dal campo ASSET_ID . |
CLOUD_PROVIDER_TAGS.CLOUD_TAG.NAME | entity.relations.entity.resource.attribute.labels.key | Mappatura diretta dal campo CLOUD_PROVIDER_TAGS.CLOUD_TAG.NAME . |
CLOUD_PROVIDER_TAGS.CLOUD_TAG.VALUE | entity.relations.entity.resource.attribute.labels.value | Mappatura diretta dal campo CLOUD_PROVIDER_TAGS.CLOUD_TAG.VALUE . |
CLOUD_RESOURCE_ID | entity.relations.entity.resource.id | Mappatura diretta dal campo CLOUD_RESOURCE_ID . |
DETECTION_LIST.DETECTION.FIRST_FOUND_DATETIME | entity.metadata.threat.first_discovered_time | Mappatura diretta dal campo DETECTION_LIST.DETECTION.FIRST_FOUND_DATETIME , convertito in timestamp. |
DETECTION_LIST.DETECTION.FIRST_REOPENED_DATETIME | entity.metadata.threat.detection_fields.value | Mappatura diretta dal campo DETECTION_LIST.DETECTION.FIRST_REOPENED_DATETIME . La chiave è hardcoded come "FIRST_REOPENED_DATETIME". |
DETECTION_LIST.DETECTION.IS_DISABLED | entity.metadata.threat.detection_fields.value | Mappatura diretta dal campo DETECTION_LIST.DETECTION.IS_DISABLED . La chiave è codificata come "IS_DISABLED". |
DETECTION_LIST.DETECTION.LAST_FIXED_DATETIME | entity.metadata.threat.detection_fields.value | Mappatura diretta dal campo DETECTION_LIST.DETECTION.LAST_FIXED_DATETIME . La chiave è codificata come "LAST_FIXED_DATETIME". |
DETECTION_LIST.DETECTION.LAST_FOUND_DATETIME | entity.metadata.threat.detection_fields.value | Mappatura diretta dal campo DETECTION_LIST.DETECTION.LAST_FOUND_DATETIME . La chiave è codificata come "LAST_FOUND_DATETIME". |
DETECTION_LIST.DETECTION.LAST_PROCESSED_DATETIME | entity.metadata.threat.detection_fields.value | Mappatura diretta dal campo DETECTION_LIST.DETECTION.LAST_PROCESSED_DATETIME . La chiave è hardcoded come "LAST_PROCESSED_DATETIME". |
DETECTION_LIST.DETECTION.LAST_REOPENED_DATETIME | entity.metadata.threat.detection_fields.value | Mappatura diretta dal campo DETECTION_LIST.DETECTION.LAST_REOPENED_DATETIME . La chiave è codificata come "LAST_REOPENED_DATETIME". |
DETECTION_LIST.DETECTION.LAST_TEST_DATETIME | entity.metadata.threat.detection_fields.value | Mappatura diretta dal campo DETECTION_LIST.DETECTION.LAST_TEST_DATETIME . La chiave è codificata come "LAST_TEST_DATETIME". |
DETECTION_LIST.DETECTION.LAST_UPDATE_DATETIME | entity.metadata.threat.detection_fields.value | Mappatura diretta dal campo DETECTION_LIST.DETECTION.LAST_UPDATE_DATETIME . La chiave è codificata come "LAST_UPDATE_DATETIME". |
DETECTION_LIST.DETECTION.PORT | entity.metadata.threat.detection_fields.value | Mappatura diretta dal campo DETECTION_LIST.DETECTION.PORT . La chiave è codificata come "PORT". |
DETECTION_LIST.DETECTION.PROTOCOL | entity.metadata.threat.detection_fields.value | Mappatura diretta dal campo DETECTION_LIST.DETECTION.PROTOCOL . La chiave è codificata come "PROTOCOL". |
DETECTION_LIST.DETECTION.QID | entity.metadata.threat.detection_fields.value | Mappatura diretta dal campo DETECTION_LIST.DETECTION.QID . La chiave è codificata come "QID". |
DETECTION_LIST.DETECTION.RESULTS | entity.metadata.threat.summary | Mappatura diretta dal campo DETECTION_LIST.DETECTION.RESULTS . |
DETECTION_LIST.DETECTION.SEVERITY | entity.metadata.threat.severity_details | Mappatura diretta dal campo DETECTION_LIST.DETECTION.SEVERITY . |
DETECTION_LIST.DETECTION.SSL | entity.metadata.threat.detection_fields.value | Mappatura diretta dal campo DETECTION_LIST.DETECTION.SSL . La chiave è codificata come "SSL". |
DETECTION_LIST.DETECTION.STATUS | entity.metadata.threat.detection_fields.value | Mappatura diretta dal campo DETECTION_LIST.DETECTION.STATUS . La chiave è codificata come "STATUS". |
DETECTION_LIST.DETECTION.TIMES_FOUND | entity.metadata.threat.detection_fields.value | Mappatura diretta dal campo DETECTION_LIST.DETECTION.TIMES_FOUND . La chiave è codificata come "TIMES_FOUND". |
DETECTION_LIST.DETECTION.TIMES_REOPENED | entity.metadata.threat.detection_fields.value | Mappatura diretta dal campo DETECTION_LIST.DETECTION.TIMES_REOPENED . La chiave è codificata come "TIMES_REOPENED". |
DETECTION_LIST.DETECTION.TYPE | entity.metadata.threat.severity | Mappato dal campo DETECTION_LIST.DETECTION.TYPE . Se il valore è "info" (senza distinzione tra maiuscole e minuscole), viene mappato su "INFORMATIONAL". In caso contrario, viene aggiunto come campo di rilevamento con la chiave "TYPE". |
DETECTION_LIST.DETECTION.UNIQUE_VULN_ID | entity.metadata.threat.detection_fields.value | Mappatura diretta dal campo DETECTION_LIST.DETECTION.UNIQUE_VULN_ID . La chiave è codificata come "UNIQUE_VULN_ID". |
DNS | entity.entity.asset.hostname | Mappato dal campo DNS se DNS_DATA.HOSTNAME è vuoto. |
DNS_DATA.HOSTNAME | entity.entity.asset.hostname | Mappatura diretta dal campo DNS_DATA.HOSTNAME . |
EC2_INSTANCE_ID | entity.relations.entity.resource.product_object_id | Mappatura diretta dal campo EC2_INSTANCE_ID . |
ID | entity.entity.asset.product_object_id | Mappatura diretta dal campo ID . |
ID | entity.metadata.product_entity_id | Mappatura diretta dal campo ID . |
IP | entity.entity.ip | Mappatura diretta dal campo IP . |
LAST_SCAN_DATETIME | entity.metadata.interval.start_time | Mappatura diretta dal campo LAST_SCAN_DATETIME , convertito in timestamp. |
METADATA.AZURE.ATTRIBUTE.NAME | entity.relations.entity.resource.attribute.labels.key | Mappatura diretta dal campo METADATA.AZURE.ATTRIBUTE.NAME . |
METADATA.AZURE.ATTRIBUTE.VALUE | entity.relations.entity.resource.attribute.labels.value | Mappatura diretta dal campo METADATA.AZURE.ATTRIBUTE.VALUE . |
Sistema operativo | entity.entity.asset.platform_software.platform | Mappato dal campo OS . Se il valore contiene "windows" (senza distinzione tra maiuscole e minuscole), viene mappato a "WINDOWS". Se contiene "Linux" (senza distinzione tra maiuscole e minuscole), viene mappato su "LINUX". |
TAGS.TAG.NAME | entity.relations.entity.resource.attribute.labels.key | Mappatura diretta dal campo TAGS.TAG.NAME . |
TAGS.TAG.TAG_ID | entity.relations.entity.resource.attribute.labels.value | Mappato dal campo TAGS.TAG.TAG_ID . Il valore è preceduto da "TAG_ID: ". |
entity.metadata.collected_timestamp | Il timestamp della voce di log. | |
entity.metadata.entity_type | Determinato in base alla presenza del campo IP . Se IP è presente, è impostato su "IP_ADDRESS". In caso contrario, è impostato su "ASSET". |
|
entity.metadata.interval.end_time | Codificato in modo permanente con un valore timestamp molto elevato (253402300799 secondi). | |
entity.metadata.product_name | Codificato in modo permanente su "QUALYS_VIRTUAL_SCANNER". | |
entity.metadata.vendor_name | Codificato in modo permanente su "QUALYS_VIRTUAL_SCANNER". | |
entity.relations.entity.resource.resource_type | Se CLOUD_SERVICE è "VM", è impostato su "VIRTUAL_MACHINE". |
|
entity.relations.entity_type | Codificato come "RESOURCE". | |
entity.relations.relationship | Codificato come "MEMBER". |
Hai bisogno di ulteriore assistenza? Ricevi risposte dai membri della community e dai professionisti di Google SecOps.