Collecter les journaux de sécurité ServiceNow

Compatible avec :

Ce document explique comment exporter des événements de sécurité ServiceNow vers Google Security Operations à l'aide de webhooks sortants configurés via des règles métier. Une étiquette d'ingestion identifie l'analyseur qui normalise les données de journaux brutes au format UDM structuré.

Architecture d'intégration

  • Cette intégration utilise les règles métier ServiceNow pour transférer les événements de sécurité vers Google SecOps en temps réel :

    ServiceNow Security Tables
        ↓ (Business Rules trigger on insert/update)
    ServiceNow RESTMessageV2 API
        ↓ (HTTP POST)
    Google Security Operations Webhook Endpoint
        ↓ (Parser: SERVICENOW_SECURITY)
    Unified Data Model (UDM)
    

Caractéristiques de l'intégration :

  • Notifications push basées sur les événements : événements envoyés immédiatement lorsqu'ils sont créés ou mis à jour
  • Temps réel : faible latence (en secondes)
  • Exportation sélective : configurez les tables et les événements à exporter.
  • Pas d'exportation groupée : n'envoie pas de données historiques

Avant de commencer

Assurez-vous de remplir les conditions suivantes :

  • Une instance Google SecOps
  • Une instance ServiceNow avec le plug-in Security Incident Response (SIR) installé
  • Un compte utilisateur ServiceNow avec les rôles suivants :
    • admin ou sn_si.admin (pour créer des règles métier)
    • Accès à System Definition > Business Rules (Définition du système > Règles métier)
    • Accès à Définition du système > Inclure des scripts
  • Accès privilégié à la console Google Google Cloud (pour la création de clés API)

Tables ServiceNow Security à exporter

Les tableaux suivants contiennent des données liées à la sécurité pour l'analyse SIEM :

Table Nom d'API Description Priorité
Incident de sécurité sn_si_incident Incidents de sécurité, enquêtes ÉLEVÉE
Observable sn_si_observable IOC : adresses IP, domaines, hachages de fichiers ÉLEVÉE
Journal système syslog Événements d'authentification, échecs de connexion MEDIUM
Audit sys_audit Modifications au niveau des champs, modifications des autorisations MEDIUM
Attribution de rôle utilisateur sys_user_has_role Attributions/Révocations de rôles FAIBLE
Résultat de sécurité sn_si_finding Détections et résultats de sécurité FAIBLE

Ce guide fournit des exemples de règles métier pour les tables de priorité ÉLEVÉE. Vous pouvez étendre l'intégration à d'autres tables en utilisant le même modèle.

Configurer un flux dans Google SecOps pour ingérer les événements de sécurité ServiceNow

Configurer le flux de webhook

  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, ServiceNow Security Events).
  5. Sélectionnez Webhook comme type de source.
  6. Sélectionnez ServiceNow Security comme Type de journal.
  7. Cliquez sur Suivant.

Configurer les paramètres du flux

  1. Spécifiez les valeurs des paramètres d'entrée suivants :

    • Délimiteur de fractionnement : saisissez \n pour séparer les lignes du journal.
    • Espace de noms de l'élément : espace de noms de l'élément.
    • Libellés d'ingestion : libellés appliqués à tous les événements de ce flux.
  2. Cliquez sur Suivant.

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

Générer une clé secrète et récupérer l'URL du point de terminaison

  1. Cliquez sur Générer une clé secrète pour générer une clé secrète permettant d'authentifier ce flux.
  2. Copiez et enregistrez la clé secrète dans un emplacement sécurisé.

  3. Accédez à l'onglet Détails.

  4. Copiez l'URL du point de terminaison du flux depuis le champ Informations sur le point de terminaison.

    • Exemple d'URL de point de terminaison : https://malachiteingestion-pa.googleapis.com/v2/unstructured/projects/PROJECT_ID/locations/LOCATION/instances/INSTANCE_ID/logTypes/SERVICENOW_SECURITY:import
  5. Cliquez sur OK.

Créer une clé API pour l'authentification

  1. Accédez à la page Identifiants de la consoleGoogle Cloud .
  2. Cliquez sur Créer des identifiants, puis sélectionnez Clé API.
  3. Cliquez sur Restreindre la clé.
  4. Sous Restrictions relatives aux API :
    • Sélectionnez Restreindre la clé.
    • Sélectionnez API Google SecOps (API Chronicle).
  5. Cliquez sur Enregistrer.
  6. Copiez la clé API et enregistrez-la dans un endroit sûr.

Configurer les identifiants d'intégration ServiceNow

Stockez les identifiants Google SecOps en tant que propriétés système ServiceNow pour un accès sécurisé.

  1. Dans ServiceNow, accédez à Propriétés système > sys_properties.list.
  2. Cliquez sur New (Nouveau).
  3. Créez la première propriété :
    • Nom : x_chronicle.endpoint_url
    • Valeur : collez l'URL du point de terminaison du flux de l'étape précédente.
    • Type : string
  4. Cliquez sur Envoyer.
  5. Cliquez sur Nouveau pour créer la deuxième propriété :
    • Nom : x_chronicle.api_key
    • Valeur : collez la clé API Google Cloud .
    • Type : password (cette option chiffre la valeur)
  6. Cliquez sur Envoyer.
  7. Cliquez sur Nouveau pour créer la troisième propriété :
    • Nom : x_chronicle.secret_key
    • Valeur : collez la clé secrète du flux Google SecOps.
    • Type : password (cette option chiffre la valeur)
  8. Cliquez sur Envoyer.

Créer un script Include d'utilitaire de webhook réutilisable

Cette inclusion de script fournit une fonction réutilisable permettant d'envoyer des événements à Google SecOps à partir de n'importe quelle règle métier.

  1. Accédez à Définition du système> Inclure les scripts.
  2. Cliquez sur New (Nouveau).
  3. Fournissez les informations de configuration suivantes :
    • Nom : ChronicleWebhookUtil
    • Nom de l'API : ChronicleWebhookUtil
    • Client callable (Appelable par le client) : décochez la case
    • Actif : coché
  4. Dans le champ Script, saisissez le code suivant :

    var ChronicleWebhookUtil = Class.create();
    ChronicleWebhookUtil.prototype = {
        initialize: function() {
            // Read credentials from System Properties
            this.endpointURL = gs.getProperty('x_chronicle.endpoint_url');
            this.apiKey = gs.getProperty('x_chronicle.api_key');
            this.secretKey = gs.getProperty('x_chronicle.secret_key');
        },
    
        sendEvent: function(eventData, eventType) {
            try {
                // Validate credentials
                if (!this.endpointURL || !this.apiKey || !this.secretKey) {
                    gs.error('[Chronicle] Missing configuration. Check System Properties: x_chronicle.*');
                    return false;
                }
    
                // Prepare payload
                var payload = {
                    event_type: eventType,
                    timestamp: new GlideDateTime().getDisplayValue(),
                    data: eventData,
                    source: "ServiceNow",
                    source_instance: gs.getProperty('instance_name')
                };
    
                // Create REST message
                var request = new sn_ws.RESTMessageV2();
                request.setEndpoint(this.endpointURL + '?key=' + this.apiKey);
                request.setHttpMethod('POST');
    
                // Set headers
                request.setRequestHeader('Content-Type', 'application/json');
                request.setRequestHeader('x-chronicle-auth', this.secretKey);
    
                // Set request body
                request.setRequestBody(JSON.stringify(payload));
    
                // Execute request
                var response = request.execute();
                var statusCode = response.getStatusCode();
                var responseBody = response.getBody();
    
                // Check response
                if (statusCode == 200 || statusCode == 201 || statusCode == 204) {
                    gs.info('[Chronicle] Event sent successfully: ' + eventType + ' | Status: ' + statusCode);
                    return true;
                } else {
                    gs.error('[Chronicle] Failed to send event: ' + eventType + ' | Status: ' + statusCode + ' | Response: ' + responseBody);
                    return false;
                }
    
            } catch (ex) {
                gs.error('[Chronicle] Exception sending event: ' + ex.message);
                return false;
            }
        },
    
        type: 'ChronicleWebhookUtil'
    };
    
  5. Cliquez sur Envoyer.

Créer des règles métier pour l'exportation d'événements

Les règles métier se déclenchent automatiquement lorsque des enregistrements sont créés ou mis à jour dans les tables ServiceNow. Créez une règle métier pour chaque table que vous souhaitez exporter vers Google SecOps.

Règle métier : incidents de sécurité

Cette règle métier exporte les événements d'incidents de sécurité vers Google SecOps.

  1. Accédez à Définition du système > Règles métier.
  2. Cliquez sur New (Nouveau).
  3. Fournissez les informations de configuration suivantes :

    Quand exécuter :

    Champ Valeur
    Nom Chronicle - Export Security Incident
    Table Security Incident [sn_si_incident]
    Actif Cochée
    Avancé Cochée
    Quand after
    Insérer Cochée
    Update Cochée
    Delete Facultatif (cochez cette case pour suivre les suppressions)
    Order 100
  4. Cliquez sur l'onglet Avancé, accédez au champ Script, puis saisissez le code suivant :

    (function executeRule(current, previous /*null when async*/) {
    
        // Extract incident data
        var incidentData = {
            sys_id: current.getValue('sys_id'),
            number: current.getValue('number'),
            short_description: current.getValue('short_description'),
            description: current.getValue('description'),
            state: current.getDisplayValue('state'),
            priority: current.getDisplayValue('priority'),
            severity: current.getDisplayValue('severity'),
            risk_score: current.getValue('risk_score'),
            category: current.getDisplayValue('category'),
            subcategory: current.getDisplayValue('subcategory'),
            assigned_to: current.getDisplayValue('assigned_to'),
            assignment_group: current.getDisplayValue('assignment_group'),
            caller: current.getDisplayValue('caller'),
            affected_user: current.getDisplayValue('affected_user'),
            opened_at: current.getValue('opened_at'),
            closed_at: current.getValue('closed_at'),
            resolved_at: current.getValue('resolved_at'),
            sys_created_on: current.getValue('sys_created_on'),
            sys_updated_on: current.getValue('sys_updated_on'),
            sys_created_by: current.getValue('sys_created_by'),
            sys_updated_by: current.getValue('sys_updated_by'),
            work_notes: current.getValue('work_notes'),
            close_notes: current.getValue('close_notes')
        };
    
        // Send to Chronicle
        var chronicleUtil = new ChronicleWebhookUtil();
        chronicleUtil.sendEvent(incidentData, 'security_incident');
    
    })(current, previous);
    
  5. Cliquez sur Envoyer.

Règle métier : observables (IOC)

Cette règle métier exporte les données observables (adresses IP, domaines, hachages de fichiers) vers Google SecOps.

  1. Accédez à Définition du système > Règles métier.
  2. Cliquez sur New (Nouveau).
  3. Fournissez les informations de configuration suivantes :

    Champ Valeur
    Nom Chronicle - Export Observable
    Table Observable [sn_si_observable]
    Actif Cochée
    Avancé Cochée
    Quand after
    Insérer Cochée
    Update Cochée
    Order 100
  4. Cliquez sur l'onglet Avancé, accédez au champ Script, puis saisissez le code suivant :

    (function executeRule(current, previous) {
    
        var observableData = {
            sys_id: current.getValue('sys_id'),
            value: current.getValue('value'),
            type: current.getDisplayValue('type'),
            finding: current.getDisplayValue('finding'),
            sighting_count: current.getValue('sighting_count'),
            notes: current.getValue('notes'),
            security_tags: current.getValue('security_tags'),
            mitre_technique: current.getDisplayValue('mitre_technique'),
            mitre_tactic: current.getDisplayValue('mitre_tactic'),
            mitre_malware: current.getDisplayValue('mitre_malware'),
            sys_created_on: current.getValue('sys_created_on'),
            sys_created_by: current.getValue('sys_created_by')
        };
    
        var chronicleUtil = new ChronicleWebhookUtil();
        chronicleUtil.sendEvent(observableData, 'observable');
    
    })(current, previous);
    
  5. Cliquez sur Envoyer.

Règle métier : événements de connexion au système

Cette règle métier exporte les événements d'authentification et de connexion vers Google SecOps.

  1. Accédez à Définition du système > Règles métier.
  2. Cliquez sur New (Nouveau).
  3. Fournissez les informations de configuration suivantes :

    Champ Valeur
    Nom Chronicle - Export System Log
    Table System Log [syslog]
    Actif Cochée
    Avancé Cochée
    Quand after
    Insérer Cochée
    Order 100
    Condition current.level == "error" || current.source.indexOf("login") != -1
  4. Cliquez sur l'onglet Avancé, accédez au champ Script, puis saisissez le code suivant :

    (function executeRule(current, previous) {
    
        var logData = {
            sys_id: current.getValue('sys_id'),
            level: current.getValue('level'),
            source: current.getValue('source'),
            message: current.getValue('message'),
            sys_created_on: current.getValue('sys_created_on'),
            sys_created_by: current.getValue('sys_created_by')
        };
    
        var chronicleUtil = new ChronicleWebhookUtil();
        chronicleUtil.sendEvent(logData, 'system_log');
    
    })(current, previous);
    
  5. Cliquez sur Envoyer.

Règle métier : piste d'audit (modifications des autorisations)

Cette règle métier exporte les modifications au niveau des champs à des fins d'audit.

  1. Accédez à Définition du système > Règles métier.
  2. Cliquez sur New (Nouveau).
  3. Fournissez les informations de configuration suivantes :

    Champ Valeur
    Nom Chronicle - Export Audit Changes
    Table Audit [sys_audit]
    Actif Cochée
    Avancé Cochée
    Quand after
    Insérer Cochée
    Order 100
    Condition Consultez le script suivant.

    Condition (filtrer uniquement les modifications critiques) :

    ```javascript
    current.tablename == 'sys_user_has_role' || current.tablename == 'sys_user_group_member' || current.tablename == 'sn_si_incident' || current.fieldname == 'active' || current.fieldname == 'locked_out'
    ```
    
  4. Cliquez sur l'onglet Avancé, accédez au champ Script, puis saisissez le code suivant :

    (function executeRule(current, previous) {
    
        var auditData = {
            sys_id: current.getValue('sys_id'),
            tablename: current.getValue('tablename'),
            documentkey: current.getValue('documentkey'),
            fieldname: current.getValue('fieldname'),
            oldvalue: current.getValue('oldvalue'),
            newvalue: current.getValue('newvalue'),
            user: current.getDisplayValue('user'),
            reason: current.getValue('reason'),
            sys_created_on: current.getValue('sys_created_on')
        };
    
        var chronicleUtil = new ChronicleWebhookUtil();
        chronicleUtil.sendEvent(auditData, 'audit_change');
    
    })(current, previous);
    
  5. Cliquez sur Envoyer.

Facultatif : Tables supplémentaires à exporter

Modifications apportées à l'attribution des rôles utilisateur

Exportez les attributions et les révocations de rôles pour l'audit de sécurité.

  • Créez une règle métier sur la table sys_user_has_role :

    (function executeRule(current, previous) {
    
        var roleData = {
            sys_id: current.getValue('sys_id'),
            user: current.getDisplayValue('user'),
            role: current.getDisplayValue('role'),
            granted_by: current.getDisplayValue('granted_by'),
            state: current.getValue('state'),
            sys_created_on: current.getValue('sys_created_on')
        };
    
        var chronicleUtil = new ChronicleWebhookUtil();
        chronicleUtil.sendEvent(roleData, 'role_assignment');
    
    })(current, previous);
    

Résultats de sécurité

Exporter les détections et les résultats de sécurité

  • Créez une règle métier sur la table sn_si_finding :

    (function executeRule(current, previous) {
    
        var findingData = {
            sys_id: current.getValue('sys_id'),
            finding: current.getValue('finding'),
            confidence: current.getValue('confidence'),
            severity: current.getDisplayValue('severity'),
            observable: current.getDisplayValue('observable'),
            sys_created_on: current.getValue('sys_created_on')
        };
    
        var chronicleUtil = new ChronicleWebhookUtil();
        chronicleUtil.sendEvent(findingData, 'finding');
    
    })(current, previous);
    

Pour en savoir plus sur les flux Google SecOps, consultez la documentation sur les flux Google SecOps. Pour en savoir plus sur les exigences associées à chaque type de flux, consultez Configuration des flux par type.

Si vous rencontrez des problèmes lors de la création de flux, contactez l'assistance Google SecOps.

Table de mappage UDM

Champ ServiceNow Mappage UDM Logique
number metadata.product_event_type Numéro d'incident ou d'événement
short_description security_result.summary Brève description de l'événement de sécurité
severity security_result.severity Niveau de gravité de l'événement
priority security_result.priority Priorité de l'événement
caller principal.user.userid Utilisateur ayant signalé ou déclenché l'événement
affected_user target.user.userid Utilisateur concerné par l'événement de sécurité
assigned_to security_result.action_details Analyste attribué à l'incident
sys_created_on metadata.event_timestamp Date et heure de création de l'événement
value (observable) network.ip ou network.dns.questions.name Valeur observable (adresse IP, domaine, hachage)
type (observable) security_result.detection_fields.value Type d'observable (adresse IP, domaine, hachage de fichier)

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