Collecter les journaux des services IDP CrowdStrike
Ce document explique comment ingérer les journaux des services CrowdStrike Identity Protection (IDP) dans Google Security Operations à l'aide d'Amazon S3. L'intégration utilise l'API CrowdStrike Unified Alerts pour collecter les événements Identity Protection et les stocke au format NDJSON pour qu'ils soient traités par l'analyseur CS_IDP intégré.
Avant de commencer
Assurez-vous de remplir les conditions suivantes :
- Une instance Google SecOps.
- Accès privilégié à la console CrowdStrike Falcon et gestion des clés API.
- Accès privilégié à AWS (S3, Identity and Access Management (IAM), Lambda, EventBridge).
Obtenir les prérequis de CrowdStrike Identity Protection
- Connectez-vous à la console CrowdStrike Falcon.
- Accédez à Assistance et ressources> Clients et clés API.
- Cliquez sur Ajouter un client API.
- Fournissez les informations de configuration suivantes :
- Nom du client : saisissez
Google SecOps IDP Integration. - Description : saisissez
API client for Google SecOps integration. - Champs d'application : sélectionnez le champ d'application Alertes : LECTURE (
alerts:read) (qui inclut les alertes Identity Protection).
- Nom du client : saisissez
- Cliquez sur Ajouter.
- Copiez et enregistrez les informations suivantes dans un emplacement sécurisé :
- ID client
- Code secret du client (affiché une seule fois)
- URL de base (exemples :
api.crowdstrike.compour US-1,api.us-2.crowdstrike.compour US-2,api.eu-1.crowdstrike.compour EU-1)
Configurer un bucket AWS S3 et IAM pour Google SecOps
- Créez un bucket Amazon S3 en suivant ce guide de l'utilisateur : Créer un bucket.
- Enregistrez le Nom et la Région du bucket pour référence ultérieure (par exemple,
crowdstrike-idp-logs-bucket). - Créez un utilisateur en suivant ce guide de l'utilisateur : Créer un utilisateur IAM.
- Sélectionnez l'utilisateur créé.
- Sélectionnez l'onglet Informations d'identification de sécurité.
- Cliquez sur Créer une clé d'accès dans la section Clés d'accès.
- Sélectionnez Service tiers comme Cas d'utilisation.
- Cliquez sur Suivant.
- Facultatif : Ajoutez une balise de description.
- Cliquez sur Créer une clé d'accès.
- Cliquez sur Télécharger le fichier CSV pour enregistrer la clé d'accès et la clé d'accès secrète pour référence ultérieure.
- Cliquez sur OK.
- Sélectionnez l'onglet Autorisations.
- Cliquez sur Ajouter des autorisations dans la section Règles relatives aux autorisations.
- Sélectionnez Ajouter des autorisations.
- Sélectionnez Joindre directement des règles.
- Recherchez la règle AmazonS3FullAccess.
- Sélectionnez la règle.
- Cliquez sur Suivant.
- Cliquez sur Ajouter des autorisations.
Configurer la stratégie et le rôle IAM pour les importations S3
- Dans la console AWS, accédez à IAM > Stratégies.
- Cliquez sur Créer une règle > onglet JSON.
- Copiez et collez le règlement suivant.
JSON de la règle (remplacez
crowdstrike-idp-logs-bucketsi vous avez saisi un autre nom de bucket) :{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowPutObjects", "Effect": "Allow", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::crowdstrike-idp-logs-bucket/*" }, { "Sid": "AllowGetStateObject", "Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::crowdstrike-idp-logs-bucket/crowdstrike-idp/state.json" } ] }Cliquez sur Suivant > Créer une règle.
Accédez à IAM > Rôles > Créer un rôle > Service AWS > Lambda.
Associez la règle que vous venez de créer.
Nommez le rôle
CrowdStrike-IDP-Lambda-Role, puis cliquez sur Créer un rôle.
Créer la fonction Lambda
- Dans la console AWS, accédez à Lambda > Fonctions > Créer une fonction.
- Cliquez sur Créer à partir de zéro.
Fournissez les informations de configuration suivantes :
Paramètre Valeur Nom CrowdStrike-IDP-CollectorDurée d'exécution Python 3.13 Architecture x86_64 Rôle d'exécution CrowdStrike-IDP-Lambda-RoleUne fois la fonction créée, ouvrez l'onglet Code, supprimez le stub et collez le code suivant :
import json import boto3 import urllib3 import os from datetime import datetime, timezone from urllib.parse import urlencode HTTP = urllib3.PoolManager() def lambda_handler(event, context): """ Fetch CrowdStrike Identity Protection alerts (Unified Alerts API) and store RAW JSON (NDJSON) to S3 for the CS_IDP parser. No transformation is performed. """ # Environment variables s3_bucket = os.environ['S3_BUCKET'] s3_prefix = os.environ['S3_PREFIX'] state_key = os.environ['STATE_KEY'] client_id = os.environ['CROWDSTRIKE_CLIENT_ID'] client_secret = os.environ['CROWDSTRIKE_CLIENT_SECRET'] api_base = os.environ['API_BASE'] s3 = boto3.client('s3') token = get_token(client_id, client_secret, api_base) last_ts = get_last_timestamp(s3, s3_bucket, state_key) # FQL filter for Identity Protection alerts only, newer than checkpoint fql_filter = f"product:'idp'+updated_timestamp:>'{last_ts}'" sort = 'updated_timestamp.asc' # Step 1: Get list of alert IDs all_ids = [] per_page = int(os.environ.get('ALERTS_LIMIT', '1000')) # up to 10000 per SDK docs offset = 0 while True: page_ids = query_alert_ids(api_base, token, fql_filter, sort, per_page, offset) if not page_ids: break all_ids.extend(page_ids) if len(page_ids) < per_page: break offset += per_page if not all_ids: return {'statusCode': 200, 'body': 'No new Identity Protection alerts.'} # Step 2: Get alert details in batches (max 1000 IDs per request) details = [] max_batch = 1000 for i in range(0, len(all_ids), max_batch): batch = all_ids[i:i+max_batch] details.extend(fetch_alert_details(api_base, token, batch)) if details: details.sort(key=lambda d: d.get('updated_timestamp', d.get('created_timestamp', ''))) latest = details[-1].get('updated_timestamp') or details[-1].get('created_timestamp') key = f"{s3_prefix}cs_idp_{datetime.now(timezone.utc).strftime('%Y%m%d_%H%M%S')}.json" body = '\n'.join(json.dumps(d, separators=(',', ':')) for d in details) s3.put_object( Bucket=s3_bucket, Key=key, Body=body.encode('utf-8'), ContentType='application/x-ndjson' ) update_state(s3, s3_bucket, state_key, latest) return {'statusCode': 200, 'body': f'Wrote {len(details)} alerts to S3.'} def get_token(client_id, client_secret, api_base): """Get OAuth2 token from CrowdStrike API""" url = f"https://{api_base}/oauth2/token" data = f"client_id={client_id}&client_secret={client_secret}&grant_type=client_credentials" headers = {'Content-Type': 'application/x-www-form-urlencoded'} r = HTTP.request('POST', url, body=data, headers=headers) if r.status != 200: raise Exception(f'Auth failed: {r.status} {r.data}') return json.loads(r.data.decode('utf-8'))['access_token'] def query_alert_ids(api_base, token, fql_filter, sort, limit, offset): """Query alert IDs using filters""" url = f"https://{api_base}/alerts/queries/alerts/v2" params = {'filter': fql_filter, 'sort': sort, 'limit': str(limit), 'offset': str(offset)} qs = urlencode(params) r = HTTP.request('GET', f"{url}?{qs}", headers={'Authorization': f'Bearer {token}'}) if r.status != 200: raise Exception(f'Query alerts failed: {r.status} {r.data}') resp = json.loads(r.data.decode('utf-8')) return resp.get('resources', []) def fetch_alert_details(api_base, token, composite_ids): """Fetch detailed alert data by composite IDs""" url = f"https://{api_base}/alerts/entities/alerts/v2" body = {'composite_ids': composite_ids} headers = {'Authorization': f'Bearer {token}', 'Content-Type': 'application/json'} r = HTTP.request('POST', url, body=json.dumps(body).encode('utf-8'), headers=headers) if r.status != 200: raise Exception(f'Fetch alert details failed: {r.status} {r.data}') resp = json.loads(r.data.decode('utf-8')) return resp.get('resources', []) def get_last_timestamp(s3, bucket, key, default='2023-01-01T00:00:00Z'): """Get last processed timestamp from S3 state file""" try: obj = s3.get_object(Bucket=bucket, Key=key) state = json.loads(obj['Body'].read().decode('utf-8')) return state.get('last_timestamp', default) except s3.exceptions.NoSuchKey: return default def update_state(s3, bucket, key, ts): """Update last processed timestamp in S3 state file""" state = {'last_timestamp': ts, 'updated': datetime.now(timezone.utc).isoformat()} s3.put_object(Bucket=bucket, Key=key, Body=json.dumps(state).encode('utf-8'), ContentType='application/json')Accédez à Configuration > Variables d'environnement.
Cliquez sur Modifier > Ajouter une variable d'environnement.
Saisissez les variables d'environnement fournies dans le tableau suivant, en remplaçant les exemples de valeurs par les vôtres.
Variables d'environnement
Clé Exemple de valeur S3_BUCKETcrowdstrike-idp-logs-bucketS3_PREFIXcrowdstrike-idp/STATE_KEYcrowdstrike-idp/state.jsonCROWDSTRIKE_CLIENT_ID<your-client-id>CROWDSTRIKE_CLIENT_SECRET<your-client-secret>API_BASEapi.crowdstrike.com(US-1),api.us-2.crowdstrike.com(US-2),api.eu-1.crowdstrike.com(EU-1)ALERTS_LIMIT1000(facultatif, 10 000 maximum par page)Une fois la fonction créée, restez sur sa page (ou ouvrez Lambda > Fonctions > votre-fonction).
Accédez à l'onglet Configuration.
Dans le panneau Configuration générale, cliquez sur Modifier.
Définissez le délai avant expiration sur 5 minutes (300 secondes), puis cliquez sur Enregistrer.
Créer une programmation EventBridge
- Accédez à Amazon EventBridge> Scheduler> Create schedule.
- Fournissez les informations de configuration suivantes :
- Planning récurrent : Tarif (
15 minutes). - Cible : votre fonction Lambda
CrowdStrike-IDP-Collector. - Nom :
CrowdStrike-IDP-Collector-15m.
- Planning récurrent : Tarif (
- Cliquez sur Créer la programmation.
(Facultatif) Créez un utilisateur et des clés IAM en lecture seule pour Google SecOps
- Accédez à Console AWS > IAM > Utilisateurs.
- Cliquez sur Add users (Ajouter des utilisateurs).
- Fournissez les informations de configuration suivantes :
- Utilisateur : saisissez
secops-reader. - Type d'accès : sélectionnez Clé d'accès – Accès programmatique.
- Utilisateur : saisissez
- Cliquez sur Créer un utilisateur.
- Associez une stratégie de lecture minimale (personnalisée) : Utilisateurs > secops-reader > Autorisations > Ajouter des autorisations > Associer des stratégies directement > Créer une stratégie.
JSON :
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["s3:GetObject"], "Resource": "arn:aws:s3:::crowdstrike-idp-logs-bucket/*" }, { "Effect": "Allow", "Action": ["s3:ListBucket"], "Resource": "arn:aws:s3:::crowdstrike-idp-logs-bucket" } ] }Nom =
secops-reader-policy.Cliquez sur Créer une règle> recherchez/sélectionnez > Suivant> Ajouter des autorisations.
Créez une clé d'accès pour
secops-reader: Identifiants de sécurité > Clés d'accès.Cliquez sur Créer une clé d'accès.
Téléchargez le fichier
.CSV. (Vous collerez ces valeurs dans le flux.)
Configurer un flux dans Google SecOps pour ingérer les journaux des services CrowdStrike Identity Protection
- Accédez à Paramètres SIEM> Flux.
- Cliquez sur + Ajouter un flux.
- Dans le champ Nom du flux, saisissez un nom pour le flux (par exemple,
CrowdStrike Identity Protection Services logs). - Sélectionnez Amazon S3 V2 comme type de source.
- Sélectionnez Services Crowdstrike Identity Protection comme Type de journal.
- Cliquez sur Suivant.
- Spécifiez les valeurs des paramètres d'entrée suivants :
- URI S3 :
s3://crowdstrike-idp-logs-bucket/crowdstrike-idp/ - Options de suppression de la source : sélectionnez l'option de suppression de votre choix.
- Âge maximal des fichiers : incluez les fichiers modifiés au cours des derniers jours. La valeur par défaut est de 180 jours.
- ID de clé d'accès : clé d'accès utilisateur ayant accès au bucket S3.
- Clé d'accès secrète : clé secrète de l'utilisateur ayant accès au bucket S3.
- Espace de noms de l'élément : espace de noms de l'élément.
- Libellés d'ingestion : libellé appliqué aux événements de ce flux.
- URI S3 :
- Cliquez sur Suivant.
- Vérifiez la configuration de votre nouveau flux sur l'écran Finaliser, puis cliquez sur Envoyer.
Vous avez encore besoin d'aide ? Obtenez des réponses de membres de la communauté et de professionnels Google SecOps.