Collecter les journaux Qualys Virtual Scanner

Compatible avec :

Cet analyseur transforme les journaux bruts du scanner virtuel Qualys au format JSON en un format structuré conforme à l'UDM Google Security Operations. Il extrait les champs pertinents tels que les informations sur les composants, les détails de l'analyse et les failles détectées, et les mappe aux champs UDM correspondants pour une représentation et une analyse cohérentes.

Avant de commencer

Assurez-vous de remplir les conditions préalables suivantes :

  • Instance Google Security Operations.
  • Accès privilégié à Google Cloud.
  • Accès privilégié à Qualys.

Activez les API requises :

  1. Connectez-vous à la console Google Cloud .
  2. Accédez à API et services > Bibliothèque.
  3. Recherchez les API suivantes et activez-les :
    • API Cloud Functions
    • API Cloud Scheduler
    • Cloud Pub/Sub (requis pour que Cloud Scheduler appelle des fonctions)

Créer un bucket de stockage Google Cloud

  1. Connectez-vous à la console Google Cloud .
  2. Accédez à la page Buckets Cloud Storage.

    Accéder à la page "Buckets"

  3. Cliquez sur Créer.

  4. Configurez le bucket :

    • Name (Nom) : saisissez un nom unique qui répond aux exigences de dénomination des buckets (par exemple, qualys-vscanner-bucket).
    • Choisissez où stocker vos données : sélectionnez un emplacement.
    • Choisir une classe de stockage pour vos données : sélectionnez une classe de stockage par défaut pour le bucket, ou bien classe automatique pour une gestion automatique des classes de stockage.
    • Choisir comment contrôler l'accès aux objets : sélectionnez non pour appliquer la protection contre l'accès public, puis sélectionnez un modèle de contrôle des accès pour les objets de votre bucket.
    • Classe de stockage : choisissez en fonction de vos besoins (par exemple, Standard).
  5. Cliquez sur Créer.

Créer un compte de service Google Cloud

  1. Accédez à IAM et administration > Comptes de service.
  2. Créez un compte de service.
  3. Attribuez-lui un nom descriptif (par exemple, qualys-user).
  4. Attribuez au compte de service le rôle Administrateur des objets de l'espace de stockage sur le bucket Cloud Storage que vous avez créé à l'étape précédente.
  5. Attribuez le rôle Demandeur Cloud Functions au compte de service.
  6. Créez une clé SSH pour le compte de service.
  7. Téléchargez un fichier de clé JSON pour le compte de service. Conservez ce fichier dans un endroit sécurisé.

Facultatif : Créez un utilisateur API dédié dans Qualys

  1. Connectez-vous à la console Qualys.
  2. Accédez à Utilisateurs.
  3. Cliquez sur Nouveau > Utilisateur.
  4. Saisissez les informations générales requises pour l'utilisateur.
  5. Sélectionnez l'onglet Rôle utilisateur.
  6. Assurez-vous que la case Accès API est cochée pour le rôle.
  7. Cliquez sur Enregistrer.

Identifier votre URL d'API Qualys spécifique

Option 1

Identifiez vos URL comme indiqué dans la section Identification de la plate-forme.

Option 2

  1. Connectez-vous à la console Qualys.
  2. Accédez à Aide > À propos.
  3. Faites défiler la page pour afficher ces informations sous "Centre des opérations de sécurité (SOC)".
  4. Copiez l'URL de l'API Qualys.

Configurer la fonction Cloud Functions

  1. Accédez à Cloud Functions dans la console Google Cloud .
  2. Cliquez sur Créer une fonction.
  3. Configurez la fonction :

    • Nom : saisissez le nom de votre fonction (par exemple, fetch-qualys-vscanner).
    • Région : sélectionnez une région proche de votre bucket.
    • Déclencheur : choisissez le déclencheur HTTP si nécessaire ou Cloud Pub/Sub pour une exécution planifiée.
    • Authentification : sécurisé avec authentification.
    • Écrivez le code avec un éditeur intégré :
    ```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
    ```
    
  4. Une fois la configuration terminée, cliquez sur Déployer.

Configurer Cloud Scheduler

  1. Accédez à Cloud Scheduler dans la console Google Cloud .
  2. Cliquez sur Créer une tâche.
  3. Configurez le job :

    • Nom : saisissez le nom de votre job (par exemple, trigger-fetch-qualys-vscanner).
    • Fréquence : utilisez la syntaxe cron pour spécifier la programmation (par exemple, 0 0 * * * pour une exécution quotidienne à minuit).
    • Fuseau horaire : définissez votre fuseau horaire préféré.
    • Type de déclencheur : sélectionnez HTTP.
    • URL du déclencheur : saisissez l'URL de la fonction Cloud (disponible dans les détails de la fonction après le déploiement).
    • Méthode : sélectionnez POST.
  4. Créez le job.

Configurer des flux

Il existe deux points d'entrée différents pour configurer les flux dans la plate-forme Google SecOps :

  • Paramètres SIEM> Flux
  • Plate-forme de contenu > Packs de contenu

Configurer des flux à partir de Paramètres SIEM > Flux

Pour configurer un flux, procédez comme suit :

  1. Accédez à Paramètres SIEM > Flux.
  2. Cliquez sur Add New Feed (Ajouter un flux).
  3. Sur la page suivante, cliquez sur Configurer un seul flux.
  4. Dans le champ Nom du flux, saisissez un nom pour le flux (par exemple, Journaux du scanner virtuel Qualys).
  5. Sélectionnez Google Cloud Storage comme Type de source.
  6. Sélectionnez Qualys Virtual Scanner comme Type de journal.
  7. Cliquez sur Suivant.
  8. Spécifiez les valeurs des paramètres d'entrée suivants :

    • URI du bucket Storage : URI source du bucket Storage Google Cloud .
    • L'URI est un : sélectionnez Fichier unique.
    • Option de suppression de la source : sélectionnez l'option de suppression de votre choix.
  9. Cliquez sur Suivant.

  10. Vérifiez la configuration de votre nouveau flux sur l'écran Finaliser, puis cliquez sur Envoyer.

Configurer des flux depuis le Hub de contenu

Indiquez les valeurs des champs suivants :

  • URI du bucket Storage : URI source du bucket Storage Google Cloud .
  • L'URI est un : sélectionnez Fichier unique.
  • Option de suppression de la source : sélectionnez l'option de suppression de votre choix.

Options avancées

  • Nom du flux : valeur préremplie qui identifie le flux.
  • Type de source : méthode utilisée pour collecter les journaux dans Google SecOps.
  • Espace de noms de l'élément : espace de noms associé au flux.
  • Libellés d'ingestion : libellés appliqués à tous les événements de ce flux.

Table de mappage UDM

Champ de journal Mappage UDM Logique
ASSET_ID entity.entity.asset.asset_id Mappage direct à partir du champ ASSET_ID.
CLOUD_PROVIDER_TAGS.CLOUD_TAG.NAME entity.relations.entity.resource.attribute.labels.key Mappage direct à partir du champ CLOUD_PROVIDER_TAGS.CLOUD_TAG.NAME.
CLOUD_PROVIDER_TAGS.CLOUD_TAG.VALUE entity.relations.entity.resource.attribute.labels.value Mappage direct à partir du champ CLOUD_PROVIDER_TAGS.CLOUD_TAG.VALUE.
CLOUD_RESOURCE_ID entity.relations.entity.resource.id Mappage direct à partir du champ CLOUD_RESOURCE_ID.
DETECTION_LIST.DETECTION.FIRST_FOUND_DATETIME entity.metadata.threat.first_discovered_time Mappage direct à partir du champ DETECTION_LIST.DETECTION.FIRST_FOUND_DATETIME, converti en code temporel.
DETECTION_LIST.DETECTION.FIRST_REOPENED_DATETIME entity.metadata.threat.detection_fields.value Mappage direct à partir du champ DETECTION_LIST.DETECTION.FIRST_REOPENED_DATETIME. La clé est codée en dur sous la forme "FIRST_REOPENED_DATETIME".
DETECTION_LIST.DETECTION.IS_DISABLED entity.metadata.threat.detection_fields.value Mappage direct à partir du champ DETECTION_LIST.DETECTION.IS_DISABLED. La clé est codée en dur sous la forme "IS_DISABLED".
DETECTION_LIST.DETECTION.LAST_FIXED_DATETIME entity.metadata.threat.detection_fields.value Mappage direct à partir du champ DETECTION_LIST.DETECTION.LAST_FIXED_DATETIME. La clé est codée en dur sous la forme "LAST_FIXED_DATETIME".
DETECTION_LIST.DETECTION.LAST_FOUND_DATETIME entity.metadata.threat.detection_fields.value Mappage direct à partir du champ DETECTION_LIST.DETECTION.LAST_FOUND_DATETIME. La clé est codée en dur sous la forme "LAST_FOUND_DATETIME".
DETECTION_LIST.DETECTION.LAST_PROCESSED_DATETIME entity.metadata.threat.detection_fields.value Mappage direct à partir du champ DETECTION_LIST.DETECTION.LAST_PROCESSED_DATETIME. La clé est codée en dur sous la forme "LAST_PROCESSED_DATETIME".
DETECTION_LIST.DETECTION.LAST_REOPENED_DATETIME entity.metadata.threat.detection_fields.value Mappage direct à partir du champ DETECTION_LIST.DETECTION.LAST_REOPENED_DATETIME. La clé est codée en dur sous la forme "LAST_REOPENED_DATETIME".
DETECTION_LIST.DETECTION.LAST_TEST_DATETIME entity.metadata.threat.detection_fields.value Mappage direct à partir du champ DETECTION_LIST.DETECTION.LAST_TEST_DATETIME. La clé est codée en dur sous la forme "LAST_TEST_DATETIME".
DETECTION_LIST.DETECTION.LAST_UPDATE_DATETIME entity.metadata.threat.detection_fields.value Mappage direct à partir du champ DETECTION_LIST.DETECTION.LAST_UPDATE_DATETIME. La clé est codée en dur sous la forme "LAST_UPDATE_DATETIME".
DETECTION_LIST.DETECTION.PORT entity.metadata.threat.detection_fields.value Mappage direct à partir du champ DETECTION_LIST.DETECTION.PORT. La clé est codée en dur sous la forme "PORT".
DETECTION_LIST.DETECTION.PROTOCOL entity.metadata.threat.detection_fields.value Mappage direct à partir du champ DETECTION_LIST.DETECTION.PROTOCOL. La clé est codée en dur sous le nom "PROTOCOL".
DETECTION_LIST.DETECTION.QID entity.metadata.threat.detection_fields.value Mappage direct à partir du champ DETECTION_LIST.DETECTION.QID. La clé est codée en dur sous la forme "QID".
DETECTION_LIST.DETECTION.RESULTS entity.metadata.threat.summary Mappage direct à partir du champ DETECTION_LIST.DETECTION.RESULTS.
DETECTION_LIST.DETECTION.SEVERITY entity.metadata.threat.severity_details Mappage direct à partir du champ DETECTION_LIST.DETECTION.SEVERITY.
DETECTION_LIST.DETECTION.SSL entity.metadata.threat.detection_fields.value Mappage direct à partir du champ DETECTION_LIST.DETECTION.SSL. La clé est codée en dur sous la forme "SSL".
DETECTION_LIST.DETECTION.STATUS entity.metadata.threat.detection_fields.value Mappage direct à partir du champ DETECTION_LIST.DETECTION.STATUS. La clé est codée en dur sous la forme "STATUS".
DETECTION_LIST.DETECTION.TIMES_FOUND entity.metadata.threat.detection_fields.value Mappage direct à partir du champ DETECTION_LIST.DETECTION.TIMES_FOUND. La clé est codée en dur sous la forme "TIMES_FOUND".
DETECTION_LIST.DETECTION.TIMES_REOPENED entity.metadata.threat.detection_fields.value Mappage direct à partir du champ DETECTION_LIST.DETECTION.TIMES_REOPENED. La clé est codée en dur sous la forme "TIMES_REOPENED".
DETECTION_LIST.DETECTION.TYPE entity.metadata.threat.severity Mappé à partir du champ DETECTION_LIST.DETECTION.TYPE. Si la valeur est "info" (non sensible à la casse), elle est mappée sur "INFORMATIONAL". Dans le cas contraire, il est ajouté en tant que champ de détection avec la clé "TYPE".
DETECTION_LIST.DETECTION.UNIQUE_VULN_ID entity.metadata.threat.detection_fields.value Mappage direct à partir du champ DETECTION_LIST.DETECTION.UNIQUE_VULN_ID. La clé est codée en dur sous la forme "UNIQUE_VULN_ID".
DNS entity.entity.asset.hostname Mappé à partir du champ DNS si DNS_DATA.HOSTNAME est vide.
DNS_DATA.HOSTNAME entity.entity.asset.hostname Mappage direct à partir du champ DNS_DATA.HOSTNAME.
EC2_INSTANCE_ID entity.relations.entity.resource.product_object_id Mappage direct à partir du champ EC2_INSTANCE_ID.
ID entity.entity.asset.product_object_id Mappage direct à partir du champ ID.
ID entity.metadata.product_entity_id Mappage direct à partir du champ ID.
IP entity.entity.ip Mappage direct à partir du champ IP.
LAST_SCAN_DATETIME entity.metadata.interval.start_time Mappage direct à partir du champ LAST_SCAN_DATETIME, converti en code temporel.
METADATA.AZURE.ATTRIBUTE.NAME entity.relations.entity.resource.attribute.labels.key Mappage direct à partir du champ METADATA.AZURE.ATTRIBUTE.NAME.
METADATA.AZURE.ATTRIBUTE.VALUE entity.relations.entity.resource.attribute.labels.value Mappage direct à partir du champ METADATA.AZURE.ATTRIBUTE.VALUE.
OS entity.entity.asset.platform_software.platform Mappé à partir du champ OS. Si la valeur contient "windows" (sans tenir compte de la casse), elle est mappée sur "WINDOWS". Si elle contient "Linux" (non sensible à la casse), elle est mappée sur "LINUX".
TAGS.TAG.NAME entity.relations.entity.resource.attribute.labels.key Mappage direct à partir du champ TAGS.TAG.NAME.
TAGS.TAG.TAG_ID entity.relations.entity.resource.attribute.labels.value Mappé à partir du champ TAGS.TAG.TAG_ID. La valeur est précédée de "TAG_ID: ".
entity.metadata.collected_timestamp Code temporel de l'entrée de journal.
entity.metadata.entity_type Déterminé en fonction de la présence du champ IP. Si IP est présent, il est défini sur "IP_ADDRESS". Sinon, la valeur est définie sur "ASSET".
entity.metadata.interval.end_time Codé en dur sur une valeur de code temporel très élevée (253402300799 secondes).
entity.metadata.product_name Codé en dur sur "QUALYS_VIRTUAL_SCANNER".
entity.metadata.vendor_name Codé en dur sur "QUALYS_VIRTUAL_SCANNER".
entity.relations.entity.resource.resource_type Si CLOUD_SERVICE est "VM", la valeur est définie sur "VIRTUAL_MACHINE".
entity.relations.entity_type Codé en dur sur "RESOURCE".
entity.relations.relationship Codé en dur sur "MEMBER".

Vous avez encore besoin d'aide ? Obtenez des réponses de membres de la communauté et de professionnels Google SecOps.