Collecter les journaux ESET Threat Intelligence

Compatible avec :

Ce document explique comment ingérer des journaux ESET Threat Intelligence dans Google Security Operations à l'aide de Google Cloud Storage V2, d'une fonction Cloud Run et de Cloud Scheduler.

ESET Threat Intelligence (ETI) fournit des informations basées sur des preuves et des conseils pratiques sur les menaces existantes ou émergentes. Les services ETI vous avertissent des logiciels ou activités malveillants susceptibles de menacer votre organisation ou ses clients. Le service fournit des données de renseignement sur les menaces via des flux TAXII 2.1 au format STIX 2.1, y compris les IoC APT, les cibles et les C&C de botnets, les domaines, adresses IP, URL et fichiers malveillants, les URL de phishing, les ransomwares et les menaces Android.

Avant de commencer

Assurez-vous de remplir les conditions suivantes :

  • Une instance Google SecOps
  • Un projet Google Cloud avec les API suivantes activées :
    • API Cloud Storage
    • API Cloud Run functions
    • API Cloud Scheduler
    • API Cloud Pub/Sub
  • Autorisations permettant de créer et de gérer des buckets Google Cloud Storage, des fonctions Cloud Run, des sujets Pub/Sub et des jobs Cloud Scheduler
  • Autorisations permettant de gérer les stratégies IAM sur les buckets Google Cloud Storage
  • Un abonnement ESET Threat Intelligence actif
  • Accès au portail ESET Threat Intelligence à l'adresse https://eti.eset.com

créer un bucket Google Cloud Storage ;

  1. Accédez à Google Cloud Console.
  2. Sélectionnez votre projet ou créez-en un.
  3. Dans le menu de navigation, accédez à Cloud Storage> Buckets.
  4. Cliquez sur Créer un bucket.
  5. Fournissez les informations de configuration suivantes :

    Paramètre Valeur
    Nommer votre bucket Saisissez un nom unique (par exemple, eset-ti-logs).
    Type d'emplacement Choisissez en fonction de vos besoins (région, birégion ou multirégion).
    Emplacement Sélectionnez l'emplacement (par exemple, us-central1).
    Classe de stockage Standard (recommandé pour les journaux auxquels vous accédez fréquemment)
    Access control (Contrôle des accès) Uniforme (recommandé)
    Outils de protection Facultatif : Activer la gestion des versions des objets ou la règle de conservation
  6. Cliquez sur Créer.

Collecter les identifiants TAXII ESET Threat Intelligence

Pour permettre à la fonction Cloud Run de récupérer des données de renseignements sur les menaces, vous devez activer les flux TAXII et générer des identifiants TAXII à partir du portail ETI.

Activer les flux TAXII

  1. Connectez-vous au portail ESET Threat Intelligence à l'adresse https://eti.eset.com.
  2. Accédez à Flux de données dans le menu principal.
  3. Cliquez sur l'icône à trois points à côté du flux de données que vous souhaitez activer.
  4. Sélectionnez Activer le flux.
  5. Répétez les étapes 3 et 4 pour chaque flux que vous souhaitez ingérer dans Google SecOps.

Générer des identifiants TAXII

  1. Dans le portail ESET Threat Intelligence, accédez à Paramètres d'administration > Identifiants d'accès.
  2. Cliquez sur Generate TAXII Credentials (Générer des identifiants TAXII).
  3. Dans la boîte de dialogue qui s'affiche, copiez et enregistrez les valeurs suivantes :

    • Nom d'utilisateur : votre nom d'utilisateur TAXII
    • Mot de passe : votre mot de passe TAXII

Enregistrer les informations sur le flux TAXII

Après avoir activé les flux et généré les identifiants, enregistrez les informations suivantes pour chaque flux que vous souhaitez ingérer :

  1. Dans le portail ESET Threat Intelligence, accédez à Flux de données.
  2. Cliquez sur l'icône à trois points à côté d'un flux activé.
  3. Sélectionnez Afficher les détails du flux de données.
  4. Dans le panneau latéral, notez les valeurs suivantes :

    • Nom du flux TAXII : identifiant du flux (par exemple, botnet stix 2.1)
    • ID TAXII 2 : ID de la collection (par exemple, 0abb06690b0b47e49cd7794396b76b20)
    • URL du flux TAXII 2 : URL complète de la collection

Flux TAXII disponibles

  • ESET Threat Intelligence fournit les flux TAXII 2.1 suivants :

    Nom du flux Nom du flux TAXII ID de collection
    Flux d'applications Android voleuses d'informations androidinfostealer stix 2.1 9ee501cde0c44d6db4ae995fead1a7c8
    Flux des menaces Android androidthreats stix 2.1 daf3de8fab144552a1cb5af054ed07ee
    IoC APT apt stix 2.1 97e3eb74ae5f46dd9e22f677a6938ee7
    Flux Botnet botnet stix 2.1 0abb06690b0b47e49cd7794396b76b20
    Botnet – C&C botnet.cc stix 2.1 d1923a526e8f400dbb301259240ee3d5
    Botnet : cible botnet.target stix 2.1 61b6e4f9153e411ca7a9982a2c6ae788
    Flux d'escroqueries liées aux cryptomonnaies cryptoscam stix 2.1 2c183ce9551a43338c6cc2ed7c2a704d
    Flux de domaine domain stix 2.1 a34aa0a4f9de419582a883863503f9c4
    Flux d'IoC eCrime ecrime stix 2.1 08059376eac84ec4a076cfd682493f91
    Flux d'adresses IP ip stix 2.1 baaed2a92335418aa753fe944e13c23a
    Pièces jointes malveillantes emailattachments stix 2.1 c0d56cf7f81d482eb97fd46beaa4bae0
    Flux de fichiers malveillants fichier stix 2.1 ee6a153ed77e4ec3ab21e76cc2074b9f
    Flux d'URL d'hameçonnage phishingurl stix 2.1 d0a6c0f962dd4dd2b3eeb96b18612584
    Flux de fichiers d'adware PUA puaadware stix 2.1 d1bfc81202fc4c6599326771ec2da41d
    Flux de fichiers d'applications à double usage PUA puadualapps stix 2.1 970a7d0039ac4668addf058cd9feb953
    Flux de ransomwares ransomware stix 2.1 8d3490d688ce4a989aee9af5c680d8bf
    Flux d'URL d'escroqueries scamurl stix 2.1 2130adc3c67c43f9a3664b187931375e
    Flux de smishing smishing stix 2.1 330ad7d0c736476babe5e49077b96c95
    Flux d'escroqueries par SMS smsscam stix 2.1 6e20217a2e1246b8ab11be29f759f716
    Flux d'URL url stix 2.1 1d3208c143be49da8130f5a66fd3a0fa

Créer un compte de service pour la fonction Cloud Run

  1. Dans la console Google Cloud, accédez à IAM et administration > Comptes de service.
  2. Cliquez sur Créer un compte de service.
  3. Fournissez les informations de configuration suivantes :

    • Nom du compte de service : saisissez eset-ti-collector.
    • Description du compte de service : saisissez Service account for ESET Threat Intelligence Cloud Run function to write STIX objects to GCS.
  4. Cliquez sur Créer et continuer.

  5. Dans la section Autoriser ce compte de service à accéder au projet, ajoutez les rôles suivants :

    1. Cliquez sur Sélectionner un rôle, puis recherchez et sélectionnez Administrateur des objets Storage.
    2. Cliquez sur Ajouter un autre rôle, puis recherchez et sélectionnez Demandeur Cloud Run.
  6. Cliquez sur Continuer.

  7. Cliquez sur OK.

Accorder des autorisations IAM sur le bucket Google Cloud Storage

  1. Accédez à Cloud Storage > Buckets.
  2. Cliquez sur le nom de votre bucket (par exemple, eset-ti-logs).
  3. Accédez à l'onglet Autorisations.
  4. Cliquez sur Accorder l'accès.
  5. Fournissez les informations de configuration suivantes :

    • Ajouter des comptes principaux : saisissez l'adresse e-mail du compte de service (par exemple, eset-ti-collector@PROJECT_ID.iam.gserviceaccount.com).
    • Attribuer des rôles : sélectionnez Administrateur des objets Storage.
  6. Cliquez sur Enregistrer.

Créer un sujet Pub/Sub

Le sujet Pub/Sub déclenche la fonction Cloud Run lorsqu'un message est publié par Cloud Scheduler.

  1. Dans la console Google Cloud, accédez à Pub/Sub > Sujets.
  2. Cliquez sur Créer un sujet.
  3. Fournissez les informations de configuration suivantes :
    • ID du sujet : saisissez eset-ti-trigger.
    • Ajouter un abonnement par défaut : laissez cette option sélectionnée.
  4. Cliquez sur Créer.

Créer la fonction Cloud Run

  1. Dans la console Google Cloud, accédez à Cloud Run Functions.
  2. Cliquez sur Créer une fonction.
  3. Fournissez les informations de configuration suivantes :

    Paramètre Valeur
    Environnement 2e génération
    Nom de la fonction eset-ti-collector
    Région Sélectionnez la même région que votre bucket GCS.
    Type de déclencheur Cloud Pub/Sub
    Sujet Pub/Sub eset-ti-trigger
    Mémoire allouée 512 MiB
    Délai avant expiration 540 secondes
    Compte de service d'exécution eset-ti-collector
  4. Cliquez sur Suivant.

  5. Définissez Environnement d'exécution sur Python 3.12.

  6. Définissez Point d'entrée sur main.

  7. Dans le fichier requirements.txt, ajoutez les dépendances suivantes :

    functions-framework==3.*
    google-cloud-storage==2.*
    urllib3==2.*
    
  8. Dans le fichier main.py, collez le code suivant :

    import functions_framework
    import json
    import os
    import logging
    import time
    import urllib3
    from datetime import datetime, timedelta, timezone
    from google.cloud import storage
    
    logger = logging.getLogger(__name__)
    logger.setLevel(logging.INFO)
    
    HTTP = urllib3.PoolManager(retries=False)
    storage_client = storage.Client()
    
    API_ROOT = "https://taxii.eset.com/taxii2/643f4eb5-f8b7-46a3-a606-6d61d5ce223a"
    TAXII_CONTENT_TYPE = "application/taxii+json;version=2.1"
    
    def _load_state(bucket_name: str, state_key: str, lookback_hours: int) -> str:
        """Return ISO8601 checkpoint (UTC)."""
        try:
            bucket = storage_client.bucket(bucket_name)
            blob = bucket.blob(state_key)
            if blob.exists():
                state_data = blob.download_as_text()
                state = json.loads(state_data)
                ts = state.get("last_poll_time")
                if ts:
                    logger.info(f"Loaded state: {ts}")
                    return ts
        except Exception as e:
            logger.warning(f"State read error: {e}")
        default_ts = (
            datetime.now(timezone.utc) - timedelta(hours=lookback_hours)
        ).strftime("%Y-%m-%dT%H:%M:%S.000Z")
        logger.info(f"No previous state found, using lookback: {default_ts}")
        return default_ts
    
    def _save_state(bucket_name: str, state_key: str, ts: str) -> None:
        """Persist the checkpoint to GCS."""
        bucket = storage_client.bucket(bucket_name)
        blob = bucket.blob(state_key)
        blob.upload_from_string(
            json.dumps({"last_poll_time": ts}),
            content_type="application/json",
        )
        logger.info(f"Saved state: {ts}")
    
    def _fetch_objects(
        username: str,
        password: str,
        collection_id: str,
        added_after: str,
        max_records: int,
    ) -> list:
        """Query TAXII 2.1 collection objects with pagination."""
        url = f"{API_ROOT}/collections/{collection_id}/objects/"
        headers = urllib3.make_headers(basic_auth=f"{username}:{password}")
        headers["Accept"] = TAXII_CONTENT_TYPE
        headers["User-Agent"] = "Chronicle-ESET-TI-GCS/1.0"
    
        all_objects = []
        params = {"added_after": added_after}
    
        while True:
            qs = "&".join(f"{k}={v}" for k, v in params.items())
            request_url = f"{url}?{qs}" if qs else url
    
            for attempt in range(3):
                try:
                    resp = HTTP.request("GET", request_url, headers=headers)
                    break
                except Exception as e:
                    wait = 2 ** (attempt + 1)
                    logger.warning(f"Request error: {e}, retrying in {wait}s")
                    time.sleep(wait)
            else:
                raise RuntimeError("Exceeded retry budget for TAXII API")
    
            if resp.status == 401:
                raise RuntimeError("Authentication failed: check TAXII credentials")
            if resp.status == 404:
                raise RuntimeError(
                    f"Collection not found: {collection_id}"
                )
            if resp.status not in (200, 206):
                raise RuntimeError(
                    f"TAXII API error {resp.status}: {resp.data[:500]}"
                )
    
            body = json.loads(resp.data.decode("utf-8"))
            objects = body.get("objects", [])
            all_objects.extend(objects)
            logger.info(
                f"Fetched {len(objects)} objects (total: {len(all_objects)})"
            )
    
            if len(all_objects) >= max_records:
                logger.info(f"Reached max_records limit: {max_records}")
                all_objects = all_objects[:max_records]
                break
    
            more = body.get("more", False)
            next_param = body.get("next")
            if more and next_param:
                params = {"added_after": added_after, "next": next_param}
            else:
                break
    
        return all_objects
    
    @functions_framework.cloud_event
    def main(cloud_event):
        """Cloud Run function entry point triggered by Pub/Sub."""
        bucket_name = os.environ["GCS_BUCKET"]
        prefix = os.environ.get("GCS_PREFIX", "eset-ti")
        state_key = os.environ.get("STATE_KEY", "eset-ti/state.json")
        username = os.environ["TAXII_USERNAME"]
        password = os.environ["TAXII_PASSWORD"]
        collection_id = os.environ["COLLECTION_ID"]
        max_records = int(os.environ.get("MAX_RECORDS", "10000"))
        lookback_hours = int(os.environ.get("LOOKBACK_HOURS", "48"))
    
        try:
            last_poll = _load_state(bucket_name, state_key, lookback_hours)
            objects = _fetch_objects(
                username, password, collection_id, last_poll, max_records
            )
    
            if not objects:
                logger.info("No new STIX objects found")
                return "No new objects", 200
    
            now_str = datetime.now(timezone.utc).strftime("%Y%m%d_%H%M%S")
            blob_path = (
                f"{prefix}/eset_ti_{collection_id}_{now_str}.json"
            )
            ndjson_body = "\n".join(
                json.dumps(obj, separators=(",", ":")) for obj in objects
            )
    
            bucket = storage_client.bucket(bucket_name)
            blob = bucket.blob(blob_path)
            blob.upload_from_string(
                ndjson_body, content_type="application/x-ndjson"
            )
    
            new_poll_time = datetime.now(timezone.utc).strftime(
                "%Y-%m-%dT%H:%M:%S.000Z"
            )
            _save_state(bucket_name, state_key, new_poll_time)
    
            msg = (
                f"Wrote {len(objects)} STIX objects to "
                f"gs://{bucket_name}/{blob_path}"
            )
            logger.info(msg)
            return msg, 200
    
        except Exception as e:
            logger.error(f"Error collecting ESET TI: {e}")
            raise
    
  9. Cliquez sur Déployer.

  10. Attendez que la fonction soit déployée. Une fois le déploiement terminé, l'état passe à une coche verte.

Configurer les variables d'environnement

  1. Une fois la fonction déployée, accédez à Fonctions Cloud Run > eset-ti-collector.
  2. Cliquez sur Modifier et déployer la nouvelle révision.
  3. Cliquez sur l'onglet Variables et secrets (ou développez Paramètres d'exécution, de compilation, de connexion et de sécurité pour la première génération).
  4. Ajoutez les variables d'environnement suivantes :

    Clé Exemple de valeur
    GCS_BUCKET eset-ti-logs
    GCS_PREFIX eset-ti
    STATE_KEY eset-ti/state.json
    TAXII_USERNAME Votre nom d'utilisateur TAXII sur le portail ETI
    TAXII_PASSWORD Votre mot de passe TAXII sur le portail ETI
    COLLECTION_ID 0abb06690b0b47e49cd7794396b76b20
    MAX_RECORDS 10000
    LOOKBACK_HOURS 48
  5. Cliquez sur Déployer.

Créer une tâche Cloud Scheduler

Cloud Scheduler publie un message sur le sujet Pub/Sub selon une programmation, ce qui déclenche la fonction Cloud Run pour interroger ESET Threat Intelligence et rechercher de nouveaux objets STIX.

  1. Dans la console Google Cloud, accédez à Cloud Scheduler.
  2. Cliquez sur Créer une tâche.
  3. Fournissez les informations de configuration suivantes :

    Paramètre Valeur
    Nom eset-ti-poll
    Région Sélectionnez la même région que votre fonction.
    Fréquence 0 */1 * * * (toutes les heures)
    Fuseau horaire Sélectionnez votre fuseau horaire (par exemple, UTC).
  4. Cliquez sur Continuer.

  5. Dans la section Configurer l'exécution :

    • Type de cible : sélectionnez Pub/Sub.
    • Thème : sélectionnez eset-ti-trigger.
    • Corps du message : saisissez {"poll": true}.
  6. Cliquez sur Créer.

Vérifier la fonction Cloud Run

  1. Dans Cloud Scheduler, recherchez le job eset-ti-poll.
  2. Cliquez sur Forcer l'exécution pour déclencher une exécution immédiate.
  3. Accédez à Cloud Run Functions > eset-ti-collector > Journaux.
  4. Vérifiez que la fonction s'est exécutée correctement en recherchant des entrées de journal telles que :

    Fetched 250 objects (total: 250)
    Wrote 250 STIX objects to gs://eset-ti-logs/eset-ti/eset_ti_0abb06690b0b47e49cd7794396b76b20_20250115_103000.json
    
  5. Accédez à Cloud Storage > Buckets > eset-ti-logs.

  6. Accédez au préfixe eset-ti/.

  7. Vérifiez que des fichiers NDJSON sont créés avec des objets STIX.

Récupérer le compte de service Google SecOps et configurer le flux

Google SecOps utilise un compte de service unique pour lire les données de votre bucket GCS. Vous devez accorder à ce compte de service l'accès à votre bucket.

Obtenir l'adresse e-mail du compte de service

  1. Accédez à Paramètres SIEM> Flux.
  2. Cliquez sur Add New Feed (Ajouter un flux).
  3. Cliquez sur Configurer un flux unique.
  4. Dans le champ Nom du flux, saisissez un nom pour le flux (par exemple, ESET Threat Intelligence - Botnet).
  5. Sélectionnez Google Cloud Storage V2 comme Type de source.
  6. Sélectionnez ESET Threat Intelligence comme type de journal.
  7. Cliquez sur Obtenir un compte de service. Une adresse e-mail unique pour le compte de service s'affiche, par exemple :

    chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.com
    
  8. Copiez cette adresse e-mail pour l'utiliser à l'étape suivante.

  9. Cliquez sur Suivant.

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

    • URL du bucket de stockage : saisissez l'URI du bucket GCS avec le chemin d'accès au préfixe :

      gs://eset-ti-logs/eset-ti/
      
    • Option de suppression de la source : sélectionnez l'option de suppression de votre choix :

      • Jamais : ne supprime jamais aucun fichier après les transferts (recommandé pour les tests).
      • Supprimer les fichiers transférés : supprime les fichiers après un transfert réussi.
      • Supprimer les fichiers transférés et les répertoires vides : supprime les fichiers et les répertoires vides après un transfert réussi.

    • Âge maximal des fichiers : incluez les fichiers modifiés au cours des derniers jours (180 jours par défaut).

    • Espace de noms de l'élément : espace de noms de l'élément

    • Libellés d'ingestion : libellé à appliquer aux événements de ce flux (par exemple, ESET_IOC)

  11. Cliquez sur Suivant.

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

Accorder des autorisations IAM au compte de service Google SecOps

Le compte de service Google SecOps doit disposer du rôle Lecteur des objets Storage sur votre bucket Google Cloud Storage.

  1. Accédez à Cloud Storage > Buckets.
  2. Cliquez sur le nom de votre bucket (par exemple, eset-ti-logs).
  3. Accédez à l'onglet Autorisations.
  4. Cliquez sur Accorder l'accès.
  5. Fournissez les informations de configuration suivantes :
    • Ajouter des comptes principaux : collez l'adresse e-mail du compte de service Google SecOps.
    • Attribuer des rôles : sélectionnez Lecteur des objets de l'espace de stockage.
  6. Cliquez sur Enregistrer.

Table de mappage UDM

Champ de journal Mappage UDM Logique
date metadata.event_timestamp Code temporel de l'événement
metadata.event_type Type d'événement (par exemple, USER_LOGIN, NETWORK_CONNECTION)
messageid metadata.id Identifiant unique de l'événement
protocol network.ip_protocol Protocole IP (par exemple, TCP, UDP)
deviceName principal.hostname Nom d'hôte source
srcAddr principal.ip Adresse IP source de la connexion
srcPort principal.port Numéro de port source
action security_result.action Action effectuée par le produit de sécurité (par exemple, AUTORISER, BLOQUER)
dstAddr target.ip Adresse IP de destination
dstPort target.port Numéro de port de destination
metadata.product_name Nom du produit
metadata.vendor_name Nom du fournisseur/de l'entreprise

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