ZeroFox-Plattform-Logs erfassen
In diesem Dokument wird beschrieben, wie Sie ZeroFox Platform-Logs mit Amazon S3 in Google Security Operations aufnehmen.
Hinweise
Prüfen Sie, ob folgende Voraussetzungen erfüllt sind:
- Eine Google SecOps-Instanz.
- Privilegierter Zugriff auf den ZeroFox Platform-Mandanten.
- Privilegierter Zugriff auf AWS (S3, Identity and Access Management (IAM), Lambda, EventBridge).
Voraussetzungen für ZeroFox
- Melden Sie sich unter
https://cloud.zerofox.com
in der ZeroFox-Plattform an. - Rufen Sie Data Connectors > API-Datenfeeds auf.
- Direkte URL (nach der Anmeldung):
https://cloud.zerofox.com/data_connectors/api
- Wenn Sie dieses Menüelement nicht sehen, wenden Sie sich an Ihren ZeroFox-Administrator, um Zugriff zu erhalten.
- Direkte URL (nach der Anmeldung):
- Klicken Sie auf Token generieren oder Persönliches Zugriffstoken erstellen.
- Geben Sie die folgenden Konfigurationsdetails an:
- Name: Geben Sie einen aussagekräftigen Namen ein, z. B.
Google SecOps S3 Ingestion
. - Ablauf: Wählen Sie einen Rotationszeitraum entsprechend der Sicherheitsrichtlinie Ihrer Organisation aus.
- Berechtigungen/Feeds: Wählen Sie Leseberechtigungen für
Alerts
,CTI feeds
und andere Datentypen aus, die Sie exportieren möchten.
- Name: Geben Sie einen aussagekräftigen Namen ein, z. B.
- Klicken Sie auf Erstellen.
- Kopieren und speichern Sie das generierte persönliche Zugriffstoken an einem sicheren Ort. Sie können es nicht noch einmal aufrufen.
- Speichern Sie die ZEROFOX_BASE_URL:
https://api.zerofox.com
(Standard für die meisten Mandanten).
AWS S3-Bucket und IAM für Google SecOps konfigurieren
- Erstellen Sie einen Amazon S3-Bucket. Folgen Sie dazu der Anleitung unter Bucket erstellen.
- Speichern Sie den Namen und die Region des Buckets zur späteren Verwendung (z. B.
zerofox-platform-logs
). - Erstellen Sie einen Nutzer gemäß dieser Anleitung: IAM-Nutzer erstellen.
- Wählen Sie den erstellten Nutzer aus.
- Wählen Sie den Tab Sicherheitsanmeldedaten aus.
- Klicken Sie im Abschnitt Zugriffsschlüssel auf Zugriffsschlüssel erstellen.
- Wählen Sie Drittanbieterdienst als Anwendungsfall aus.
- Klicken Sie auf Weiter.
- Optional: Fügen Sie ein Beschreibungstag hinzu.
- Klicken Sie auf Zugriffsschlüssel erstellen.
- Klicken Sie auf CSV-Datei herunterladen, um den Access Key (Zugriffsschlüssel) und den Secret Access Key (geheimer Zugriffsschlüssel) für die zukünftige Verwendung zu speichern.
- Klicken Sie auf Fertig.
- Wählen Sie den Tab Berechtigungen aus.
- Klicken Sie im Bereich Berechtigungsrichtlinien auf Berechtigungen hinzufügen.
- Wählen Sie Berechtigungen hinzufügen aus.
- Wählen Sie Richtlinien direkt anhängen aus.
- Suchen Sie nach der Richtlinie AmazonS3FullAccess.
- Wählen Sie die Richtlinie aus.
- Klicken Sie auf Weiter.
- Klicken Sie auf Berechtigungen hinzufügen.
IAM-Richtlinie und ‑Rolle für S3-Uploads konfigurieren
- Rufen Sie in der AWS-Konsole IAM > Richtlinien auf.
- Klicken Sie auf Richtlinie erstellen> Tab „JSON“.
- Kopieren Sie die folgende Richtlinie und fügen Sie sie ein.
Policy JSON (ersetzen Sie
zerofox-platform-logs
, wenn Sie einen anderen Bucket-Namen eingegeben haben):{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowPutObjects", "Effect": "Allow", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::zerofox-platform-logs/*" }, { "Sid": "AllowGetStateObject", "Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::zerofox-platform-logs/zerofox/platform/state.json" } ] }
Klicken Sie auf Weiter > Richtlinie erstellen.
Rufen Sie IAM > Rollen > Rolle erstellen > AWS-Service > Lambda auf.
Hängen Sie die neu erstellte Richtlinie an.
Geben Sie der Rolle den Namen
ZeroFoxPlatformToS3Role
und klicken Sie auf Rolle erstellen.
Lambda-Funktion erstellen
- Rufen Sie in der AWS Console Lambda > Funktionen > Funktion erstellen auf.
- Klicken Sie auf Von Grund auf erstellen.
Geben Sie die folgenden Konfigurationsdetails an:
Einstellung Wert Name zerofox_platform_to_s3
Laufzeit Python 3.13 Architektur x86_64 Ausführungsrolle ZeroFoxPlatformToS3Role
Nachdem die Funktion erstellt wurde, öffnen Sie den Tab Code, löschen Sie den Stub und fügen Sie den folgenden Code (
zerofox_platform_to_s3.py
) ein.#!/usr/bin/env python3 # Lambda: Pull ZeroFox Platform data (alerts/incidents/logs) to S3 (no transform) import os, json, time, urllib.parse from urllib.request import Request, urlopen from urllib.error import HTTPError, URLError import boto3 S3_BUCKET = os.environ["S3_BUCKET"] S3_PREFIX = os.environ.get("S3_PREFIX", "zerofox/platform/") STATE_KEY = os.environ.get("STATE_KEY", "zerofox/platform/state.json") LOOKBACK_SEC = int(os.environ.get("LOOKBACK_SECONDS", "3600")) PAGE_SIZE = int(os.environ.get("PAGE_SIZE", "200")) MAX_PAGES = int(os.environ.get("MAX_PAGES", "20")) HTTP_TIMEOUT = int(os.environ.get("HTTP_TIMEOUT", "60")) HTTP_RETRIES = int(os.environ.get("HTTP_RETRIES", "3")) URL_TEMPLATE = os.environ.get("URL_TEMPLATE", "") AUTH_HEADER = os.environ.get("AUTH_HEADER", "") # e.g. "Authorization: Bearer <token>" ZEROFOX_BASE_URL = os.environ.get("ZEROFOX_BASE_URL", "https://api.zerofox.com") ZEROFOX_API_TOKEN = os.environ.get("ZEROFOX_API_TOKEN", "") s3 = boto3.client("s3") def _iso(ts: float) -> str: return time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(ts)) def _load_state() -> dict: try: obj = s3.get_object(Bucket=S3_BUCKET, Key=STATE_KEY) b = obj["Body"].read() return json.loads(b) if b else {} except Exception: return {"last_since": _iso(time.time() - LOOKBACK_SEC)} def _save_state(st: dict) -> None: s3.put_object( Bucket=S3_BUCKET, Key=STATE_KEY, Body=json.dumps(st, separators=(",", ":")).encode("utf-8"), ContentType="application/json", ) def _headers() -> dict: hdrs = {"Accept": "application/json", "Content-Type": "application/json"} if AUTH_HEADER: try: k, v = AUTH_HEADER.split(":", 1) hdrs[k.strip()] = v.strip() except ValueError: hdrs["Authorization"] = AUTH_HEADER.strip() elif ZEROFOX_API_TOKEN: hdrs["Authorization"] = f"Bearer {ZEROFOX_API_TOKEN}" return hdrs def _http_get(url: str) -> dict: attempt = 0 while True: try: req = Request(url, method="GET") for k, v in _headers().items(): req.add_header(k, v) with urlopen(req, timeout=HTTP_TIMEOUT) as r: body = r.read() try: return json.loads(body.decode("utf-8")) except json.JSONDecodeError: return {"raw": body.decode("utf-8", errors="replace")} except HTTPError as e: if e.code in (429, 500, 502, 503, 504) and attempt < HTTP_RETRIES: retry_after = int(e.headers.get("Retry-After", 1 + attempt)) time.sleep(max(1, retry_after)) attempt += 1 continue raise except URLError: if attempt < HTTP_RETRIES: time.sleep(1 + attempt) attempt += 1 continue raise def _put_json(obj: dict, label: str) -> str: ts = time.gmtime() key = f"{S3_PREFIX}/{time.strftime('%Y/%m/%d/%H%M%S', ts)}-zerofox-{label}.json" s3.put_object( Bucket=S3_BUCKET, Key=key, Body=json.dumps(obj, separators=(",", ":")).encode("utf-8"), ContentType="application/json", ) return key def _extract_next_token(payload: dict): next_token = (payload.get("next") or payload.get("next_token") or payload.get("nextPageToken") or payload.get("next_page_token")) if isinstance(next_token, dict): return next_token.get("token") or next_token.get("cursor") or next_token.get("value") return next_token def _extract_items(payload: dict) -> list: for key in ("results", "data", "alerts", "items", "logs", "events"): if isinstance(payload.get(key), list): return payload[key] return [] def _extract_newest_timestamp(items: list, current: str) -> str: newest = current for item in items: timestamp = (item.get("timestamp") or item.get("created_at") or item.get("last_modified") or item.get("event_time") or item.get("log_time") or item.get("updated_at")) if isinstance(timestamp, str) and timestamp > newest: newest = timestamp return newest def lambda_handler(event=None, context=None): st = _load_state() since = st.get("last_since") or _iso(time.time() - LOOKBACK_SEC) # Use URL_TEMPLATE if provided, otherwise construct default alerts endpoint if URL_TEMPLATE: base_url = URL_TEMPLATE.replace("{SINCE}", urllib.parse.quote(since)) else: base_url = f"{ZEROFOX_BASE_URL}/v1/alerts?since={urllib.parse.quote(since)}" page_token = "" pages = 0 total_items = 0 newest_since = since while pages < MAX_PAGES: # Construct URL with pagination if URL_TEMPLATE: url = (base_url .replace("{PAGE_TOKEN}", urllib.parse.quote(page_token)) .replace("{PAGE_SIZE}", str(PAGE_SIZE))) else: url = f"{base_url}&limit={PAGE_SIZE}" if page_token: url += f"&page_token={urllib.parse.quote(page_token)}" payload = _http_get(url) _put_json(payload, f"page-{pages:05d}") items = _extract_items(payload) total_items += len(items) newest_since = _extract_newest_timestamp(items, newest_since) pages += 1 next_token = _extract_next_token(payload) if not next_token: break page_token = str(next_token) if newest_since and newest_since != st.get("last_since"): st["last_since"] = newest_since _save_state(st) return {"ok": True, "pages": pages, "items": total_items, "since": since, "new_since": newest_since} if __name__ == "__main__": print(lambda_handler())
Rufen Sie Konfiguration > Umgebungsvariablen auf.
Klicken Sie auf Bearbeiten> Neue Umgebungsvariable hinzufügen.
Geben Sie die in der folgenden Tabelle angegebenen Umgebungsvariablen ein und ersetzen Sie die Beispielwerte durch Ihre Werte.
Umgebungsvariablen
Schlüssel Beispielwert S3_BUCKET
zerofox-platform-logs
S3_PREFIX
zerofox/platform/
STATE_KEY
zerofox/platform/state.json
ZEROFOX_BASE_URL
https://api.zerofox.com
ZEROFOX_API_TOKEN
your-zerofox-personal-access-token
LOOKBACK_SECONDS
3600
PAGE_SIZE
200
MAX_PAGES
20
HTTP_TIMEOUT
60
HTTP_RETRIES
3
URL_TEMPLATE
(optional) Benutzerdefinierte URL-Vorlage mit {SINCE}
,{PAGE_TOKEN}
,{PAGE_SIZE}
AUTH_HEADER
(optional) Authorization: Bearer <token>
für benutzerdefinierte AuthentifizierungBleiben Sie nach dem Erstellen der Funktion auf der zugehörigen Seite oder öffnen Sie Lambda > Funktionen > Ihre Funktion.
Wählen Sie den Tab Konfiguration aus.
Klicken Sie im Bereich Allgemeine Konfiguration auf Bearbeiten.
Ändern Sie Zeitlimit in 5 Minuten (300 Sekunden) und klicken Sie auf Speichern.
EventBridge-Zeitplan erstellen
- Gehen Sie zu Amazon EventBridge > Scheduler > Create schedule (Amazon EventBridge > Scheduler > Zeitplan erstellen).
- Geben Sie die folgenden Konfigurationsdetails an:
- Wiederkehrender Zeitplan: Preis (
1 hour
). - Ziel: Ihre Lambda-Funktion
zerofox_platform_to_s3
. - Name:
zerofox-platform-1h
.
- Wiederkehrender Zeitplan: Preis (
- Klicken Sie auf Zeitplan erstellen.
(Optional) IAM-Nutzer mit Lesezugriff und Schlüssel für Google SecOps erstellen
- Rufen Sie die AWS-Konsole > IAM > Nutzer auf.
- Klicken Sie auf Add users (Nutzer hinzufügen).
- Geben Sie die folgenden Konfigurationsdetails an:
- Nutzer: Geben Sie
secops-reader
ein. - Zugriffstyp: Wählen Sie Zugriffsschlüssel – programmatischer Zugriff aus.
- Nutzer: Geben Sie
- Klicken Sie auf Nutzer erstellen.
- Minimale Leseberechtigung (benutzerdefiniert) anhängen: Nutzer > secops-reader > Berechtigungen > Berechtigungen hinzufügen > Richtlinien direkt anhängen > Richtlinie erstellen.
JSON:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["s3:GetObject"], "Resource": "arn:aws:s3:::zerofox-platform-logs/*" }, { "Effect": "Allow", "Action": ["s3:ListBucket"], "Resource": "arn:aws:s3:::zerofox-platform-logs" } ] }
Name =
secops-reader-policy
.Klicken Sie auf Richtlinie erstellen> suchen/auswählen> Weiter> Berechtigungen hinzufügen.
Erstellen Sie einen Zugriffsschlüssel für
secops-reader
: Sicherheitsanmeldedaten > Zugriffsschlüssel.Klicken Sie auf Zugriffsschlüssel erstellen.
Laden Sie die Datei
.CSV
herunter. Sie fügen diese Werte in den Feed ein.
Feed in Google SecOps konfigurieren, um ZeroFox Platform-Logs aufzunehmen
- Rufen Sie die SIEM-Einstellungen > Feeds auf.
- Klicken Sie auf + Neuen Feed hinzufügen.
- Geben Sie im Feld Feedname einen Namen für den Feed ein, z. B.
ZeroFox Platform Logs
. - Wählen Sie Amazon S3 V2 als Quelltyp aus.
- Wählen Sie ZeroFox Platform als Logtyp aus.
- Klicken Sie auf Weiter.
- Geben Sie Werte für die folgenden Eingabeparameter an:
- S3-URI:
s3://zerofox-platform-logs/zerofox/platform/
- Optionen zum Löschen der Quelle: Wählen Sie die gewünschte Option zum Löschen aus.
- Maximales Dateialter: Dateien einschließen, die in den letzten Tagen geändert wurden. Der Standardwert ist 180 Tage.
- Zugriffsschlüssel-ID: Nutzerzugriffsschlüssel mit Zugriff auf den S3-Bucket.
- Geheimer Zugriffsschlüssel: Der geheime Schlüssel des Nutzers mit Zugriff auf den S3-Bucket.
- Asset-Namespace: Der Asset-Namespace.
- Aufnahmelabels: Das Label, das auf die Ereignisse aus diesem Feed angewendet wird.
- S3-URI:
- Klicken Sie auf Weiter.
- Prüfen Sie die neue Feedkonfiguration auf dem Bildschirm Abschließen und klicken Sie dann auf Senden.
Benötigen Sie weitere Hilfe? Antworten von Community-Mitgliedern und Google SecOps-Experten erhalten