BeyondTrust Endpoint Privilege Management-Logs erfassen
In diesem Dokument wird beschrieben, wie Sie BeyondTrust Endpoint Privilege Management-Logs (EPM) mit AWS S3 in Google Security Operations aufnehmen. Der Parser konzentriert sich auf die Umwandlung von JSON-Logrohdaten von BeyondTrust Endpoint in ein strukturiertes Format, das dem Unified Data Model (UDM) entspricht. Zuerst werden Standardwerte für verschiedene Felder initialisiert. Anschließend wird die JSON-Nutzlast geparst und bestimmte Felder aus dem Rohlog werden den entsprechenden UDM-Feldern im event.idm.read_only_udm
-Objekt zugeordnet.
Hinweise
Prüfen Sie, ob folgende Voraussetzungen erfüllt sind:
- Google SecOps-Instanz
- Privilegierter Zugriff auf AWS
- Privilegierter Zugriff auf BeyondTrust Endpoint Privilege Management
AWS IAM für die Google SecOps-Aufnahme konfigurieren
- 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 und wählen Sie sie aus.
- Klicken Sie auf Weiter.
- Klicken Sie auf Berechtigungen hinzufügen.
BeyondTrust EPM für den API-Zugriff konfigurieren
- Melden Sie sich als Administrator in der Webkonsole von BeyondTrust Privilege Management an.
- Gehen Sie zu Systemkonfiguration > REST API > Tokens.
- Klicken Sie auf Token hinzufügen.
- Geben Sie die folgenden Konfigurationsdetails an:
- Name: Geben Sie
Google SecOps Collector
ein. - Bereiche: Wählen Sie Audit:Read und andere Bereiche nach Bedarf aus.
- Name: Geben Sie
- Speichern und Kopieren Sie den Tokenwert (dies ist Ihr BPT_API_TOKEN).
- Kopieren Sie die API-Basis-URL. Sie ist in der Regel
https://<your-epm-server>/api/v3
oder/api/v2
, je nach Ihrer Version. Sie verwenden sie als BPT_API_URL.
AWS S3-Bucket erstellen
- Melden Sie sich bei der AWS Management Console an.
- Rufen Sie die AWS Console > Services > S3 > Create bucket auf.
- Geben Sie die folgenden Konfigurationsdetails an:
- Bucket-Name:
my-beyondtrust-logs
. - Region: [Ihre Auswahl] > Erstellen.
- Bucket-Name:
IAM-Rolle für EC2 erstellen
- Melden Sie sich bei der AWS Management Console an.
- Rufen Sie die AWS-Konsole > Dienste > IAM > Rollen > Rolle erstellen auf.
- Geben Sie die folgenden Konfigurationsdetails an:
- Vertrauenswürdige Identität: AWS-Dienst > EC2 > Weiter.
- Berechtigung anhängen: AmazonS3FullAccess (oder eine Richtlinie mit eingeschränktem Umfang für Ihren Bucket) > Weiter.
- Rollenname:
EC2-S3-BPT-Writer
> Rolle erstellen.
Optional: EC2 Collector-VM starten und konfigurieren
- Melden Sie sich in der AWS Management Console an.
- Rufen Sie Dienste auf.
- Geben Sie in der Suchleiste „EC2“ ein und wählen Sie das Ergebnis aus.
- Klicken Sie im EC2-Dashboard auf Instances (Instanzen).
- Klicken Sie auf Instanzen starten.
- Geben Sie die folgenden Konfigurationsdetails an:
- Name: Geben Sie
BPT-Log-Collector
ein. - AMI: Wählen Sie Ubuntu Server 22.04 LTS aus.
- Instanztyp: t3.micro (oder größer). Klicken Sie dann auf Weiter.
- Netzwerk: Die Netzwerkeinstellung muss auf Ihre Standard-VPC festgelegt sein.
- IAM-Rolle: Wählen Sie im Menü die IAM-Rolle EC2-S3-BPT-Writer aus.
- Öffentliche IP automatisch zuweisen: Aktivieren (oder dafür sorgen, dass Sie sie über VPN erreichen können) > Weiter.
- Speicher hinzufügen: Behalten Sie die Standardspeicherkonfiguration (8 GiB) bei und klicken Sie auf Weiter.
- Wählen Sie Neue Sicherheitsgruppe erstellen aus.
- Regel für eingehenden Traffic: Klicken Sie auf Regel hinzufügen.
- Typ: Wählen Sie SSH aus.
- Port: 22
- Quelle: Ihre IP-Adresse
- Klicken Sie auf Überprüfen und starten.
- Wählen Sie ein Schlüsselpaar aus oder erstellen Sie eines.
- Klicken Sie auf Schlüsselpaar herunterladen.
- Speichern Sie die heruntergeladene PEM-Datei. Sie benötigen diese Datei, um eine SSH-Verbindung zu Ihrer Instanz herzustellen.
- Name: Geben Sie
Stellen Sie über SSH eine Verbindung zu Ihrer VM her:
chmod 400 ~/Downloads/your-key.pem ssh -i ~/Downloads/your-key.pem ubuntu@<EC2_PUBLIC_IP>
Erforderliche Komponenten für Collector installieren
Führen Sie dazu diesen Befehl aus:
# Update OS sudo apt update && sudo apt upgrade -y # Install Python, Git sudo apt install -y python3 python3-venv python3-pip git # Create & activate virtualenv python3 -m venv ~/bpt-venv source ~/bpt-venv/bin/activate # Install libraries pip install requests boto3
Verzeichnis und Statusdatei erstellen:
sudo mkdir -p /var/lib/bpt-collector sudo touch /var/lib/bpt-collector/last_run.txt sudo chown ubuntu:ubuntu /var/lib/bpt-collector/last_run.txt
Initialisieren Sie sie (z. B. auf vor einer Stunde):
echo "$(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZ)" > /var/lib/bpt-collector/last_run.txt
Armis Collector-Skript bereitstellen
Projektordner erstellen:
mkdir ~/bpt-collector && cd ~/bpt-collector
Exportieren Sie die erforderlichen Umgebungsvariablen (z. B. in
~/.bashrc
):export BPT_API_URL="https://<your-subdomain>-services.pm.beyondtrustcloud.com" export BPT_CLIENT_ID="your-client-id" export BPT_CLIENT_SECRET="your-client-secret" export S3_BUCKET="my-bpt-logs" export S3_PREFIX="bpt/" export STATE_FILE="/var/lib/bpt-collector/last_run.txt" export PAGE_SIZE="100"
Erstellen Sie
collector_bpt.py
und geben Sie den folgenden Code ein:#!/usr/bin/env python3 import os, sys, json, boto3, requests from datetime import datetime, timezone, timedelta # ── UTILS ───────────────────────────────────────────────────────────────── def must_env(var): val = os.getenv(var) if not val: print(f"ERROR: environment variable {var} is required", file=sys.stderr) sys.exit(1) return val def ensure_state_file(path): d = os.path.dirname(path) if not os.path.isdir(d): os.makedirs(d, exist_ok=True) if not os.path.isfile(path): ts = (datetime.now(timezone.utc) - timedelta(hours=1))\ .strftime("%Y-%m-%dT%H:%M:%SZ") with open(path, "w") as f: f.write(ts) # ── CONFIG ───────────────────────────────────────────────────────────────── BPT_API_URL = must_env("BPT_API_URL") # for example, https://subdomain-services.pm.beyondtrustcloud.com CLIENT_ID = must_env("BPT_CLIENT_ID") CLIENT_SECRET = must_env("BPT_CLIENT_SECRET") S3_BUCKET = must_env("S3_BUCKET") S3_PREFIX = os.getenv("S3_PREFIX", "") # for example, "bpt/" STATE_FILE = os.getenv("STATE_FILE", "/var/lib/bpt-collector/last_run.txt") PAGE_SIZE = int(os.getenv("PAGE_SIZE", "100")) # ── END CONFIG ───────────────────────────────────────────────────────────── ensure_state_file(STATE_FILE) def read_last_run(): with open(STATE_FILE, "r") as f: ts = f.read().strip() return datetime.fromisoformat(ts.replace("Z", "+00:00")) def write_last_run(dt): with open(STATE_FILE, "w") as f: f.write(dt.strftime("%Y-%m-%dT%H:%M:%SZ")) def get_oauth_token(): resp = requests.post( f"{BPT_API_URL}/oauth/connect/token", headers={"Content-Type": "application/x-www-form-urlencoded"}, data={ "grant_type": "client_credentials", "client_id": CLIENT_ID, "client_secret": CLIENT_SECRET } ) resp.raise_for_status() return resp.json()["access_token"] def fetch_events(token, start, end): headers = {"Authorization": f"Bearer {token}"} offset = 0 while True: params = { "startTime": start, "endTime": end, "limit": PAGE_SIZE, "offset": offset } resp = requests.get( f"{BPT_API_URL}/management-api/v1/Audit/Events", headers=headers, params=params ) resp.raise_for_status() events = resp.json().get("events", []) if not events: break for e in events: yield e offset += PAGE_SIZE def upload_to_s3(obj, key): boto3.client("s3").put_object( Bucket=S3_BUCKET, Key=key, Body=json.dumps(obj).encode("utf-8") ) def main(): # 1) determine window start_dt = read_last_run() end_dt = datetime.now(timezone.utc) START = start_dt.strftime("%Y-%m-%dT%H:%M:%SZ") END = end_dt.strftime("%Y-%m-%dT%H:%M:%SZ") print(f"Fetching events from {START} to {END}") # 2) authenticate and fetch token = get_oauth_token() count = 0 for idx, evt in enumerate(fetch_events(token, START, END), start=1): key = f"{S3_PREFIX}{end_dt.strftime('%Y/%m/%d')}/evt_{int(end_dt.timestamp())}_{idx}.json" upload_to_s3(evt, key) count += 1 print(f"Uploaded {count} events") # 3) persist state write_last_run(end_dt) if __name__ == "__main__": main()
Machen Sie es ausführbar:
chmod +x collector_bpt.py
Tägliche Ausführung mit Cron planen
Führen Sie dazu diesen Befehl aus:
crontab -e
Fügen Sie den täglichen Job um Mitternacht UTC hinzu:
0 0 * * * cd ~/bpt-collector && source ~/bpt-venv/bin/activate && ./collector_bpt.py >> ~/bpt-collector/bpt.log 2>&1
Feeds einrichten
So konfigurieren Sie einen Feed:
- Rufen Sie die SIEM-Einstellungen > Feeds auf.
- Klicken Sie auf Neuen Feed hinzufügen.
- Klicken Sie auf der nächsten Seite auf Einen einzelnen Feed konfigurieren.
- Geben Sie im Feld Feed name (Feedname) einen Namen für den Feed ein, z. B. BeyondTrust EPM Logs.
- Wählen Sie Amazon S3 V2 als Quelltyp aus.
- Wählen Sie Beyondtrust Endpoint Privilege Management als Logtyp aus.
- Klicken Sie auf Weiter.
Geben Sie Werte für die folgenden Eingabeparameter an:
- S3-URI: Der Bucket-URI (das Format sollte
s3://your-log-bucket-name/
sein). Ersetzen Sie Folgendes:your-log-bucket-name
: der Name des Buckets.
- Optionen zum Löschen der Quelle: Wählen Sie die gewünschte Option aus.
- S3-URI: Der Bucket-URI (das Format sollte
Klicken Sie auf Weiter.
Prüfen Sie die neue Feedkonfiguration auf dem Bildschirm Abschließen und klicken Sie dann auf Senden.
UDM-Zuordnungstabelle
Logfeld | UDM-Zuordnung | Logik |
---|---|---|
agent.id | principal.asset.attribute.labels.value | Der Wert wird aus dem Feld agent.id im Rohlog übernommen und einem Label mit dem Schlüssel agent_id im principal.asset.attribute.labels -Array im UDM zugeordnet. |
agent.version | principal.asset.attribute.labels.value | Der Wert wird aus dem Feld agent.version im Rohlog übernommen und einem Label mit dem Schlüssel agent_version im principal.asset.attribute.labels -Array im UDM zugeordnet. |
ecs.version | principal.asset.attribute.labels.value | Der Wert wird aus dem Feld ecs.version im Rohlog übernommen und einem Label mit dem Schlüssel ecs_version im principal.asset.attribute.labels -Array im UDM zugeordnet. |
event_data.reason | metadata.description | Der Wert wird aus dem Feld event_data.reason im Rohlog übernommen und dem Feld description im metadata -Objekt im UDM zugeordnet. |
event_datas.ActionId | metadata.product_log_id | Der Wert wird aus dem Feld event_datas.ActionId im Rohlog übernommen und dem Feld product_log_id im metadata -Objekt im UDM zugeordnet. |
file.path | principal.file.full_path | Der Wert wird aus dem Feld file.path im Rohlog übernommen und dem Feld full_path im principal.file -Objekt im UDM zugeordnet. |
headers.content_length | additional.fields.value.string_value | Der Wert wird aus dem Feld headers.content_length im Rohlog übernommen und einem Label mit dem Schlüssel content_length im additional.fields -Array im UDM zugeordnet. |
headers.content_type | additional.fields.value.string_value | Der Wert wird aus dem Feld headers.content_type im Rohlog übernommen und einem Label mit dem Schlüssel content_type im additional.fields -Array im UDM zugeordnet. |
headers.http_host | additional.fields.value.string_value | Der Wert wird aus dem Feld headers.http_host im Rohlog übernommen und einem Label mit dem Schlüssel http_host im additional.fields -Array im UDM zugeordnet. |
headers.http_version | network.application_protocol_version | Der Wert wird aus dem Feld headers.http_version im Rohlog übernommen und dem Feld application_protocol_version im network -Objekt im UDM zugeordnet. |
headers.request_method | network.http.method | Der Wert wird aus dem Feld headers.request_method im Rohlog übernommen und dem Feld method im network.http -Objekt im UDM zugeordnet. |
host.hostname | principal.hostname | Der Wert wird aus dem Feld host.hostname im Rohlog übernommen und dem Feld hostname im principal -Objekt im UDM zugeordnet. |
host.hostname | principal.asset.hostname | Der Wert wird aus dem Feld host.hostname im Rohlog übernommen und dem Feld hostname im principal.asset -Objekt im UDM zugeordnet. |
host.ip | principal.asset.ip | Der Wert wird aus dem Feld host.ip im Rohlog übernommen und dem Array ip im Objekt principal.asset im UDM hinzugefügt. |
host.ip | principal.ip | Der Wert wird aus dem Feld host.ip im Rohlog übernommen und dem Array ip im Objekt principal im UDM hinzugefügt. |
host.mac | principal.mac | Der Wert wird aus dem Feld host.mac im Rohlog übernommen und dem Array mac im Objekt principal im UDM hinzugefügt. |
host.os.platform | principal.platform | Der Wert wird auf MAC gesetzt, wenn das Feld host.os.platform im Rohlog macOS entspricht. |
host.os.version | principal.platform_version | Der Wert wird aus dem Feld host.os.version im Rohlog übernommen und dem Feld platform_version im principal -Objekt im UDM zugeordnet. |
labels.related_item_id | metadata.product_log_id | Der Wert wird aus dem Feld labels.related_item_id im Rohlog übernommen und dem Feld product_log_id im metadata -Objekt im UDM zugeordnet. |
process.command_line | principal.process.command_line | Der Wert wird aus dem Feld process.command_line im Rohlog übernommen und dem Feld command_line im principal.process -Objekt im UDM zugeordnet. |
process.name | additional.fields.value.string_value | Der Wert wird aus dem Feld process.name im Rohlog übernommen und einem Label mit dem Schlüssel process_name im additional.fields -Array im UDM zugeordnet. |
process.parent.name | additional.fields.value.string_value | Der Wert wird aus dem Feld process.parent.name im Rohlog übernommen und einem Label mit dem Schlüssel process_parent_name im additional.fields -Array im UDM zugeordnet. |
process.parent.pid | principal.process.parent_process.pid | Der Wert wird aus dem Feld process.parent.pid im Rohlog übernommen, in einen String konvertiert und dem Feld pid im Objekt principal.process.parent_process im UDM zugeordnet. |
process.pid | principal.process.pid | Der Wert wird aus dem Feld process.pid im Rohlog übernommen, in einen String konvertiert und dem Feld pid im Objekt principal.process im UDM zugeordnet. |
user.id | principal.user.userid | Der Wert wird aus dem Feld user.id im Rohlog übernommen und dem Feld userid im principal.user -Objekt im UDM zugeordnet. |
nutzer.name | principal.user.user_display_name | Der Wert wird aus dem Feld user.name im Rohlog übernommen und dem Feld user_display_name im principal.user -Objekt im UDM zugeordnet. |
– | metadata.event_timestamp | Der Ereigniszeitstempel wird auf den Zeitstempel des Logeintrags gesetzt. |
– | metadata.event_type | Der Ereignistyp wird auf GENERIC_EVENT gesetzt, wenn kein Prinzipal gefunden wird. Andernfalls wird er auf STATUS_UPDATE gesetzt. |
– | network.application_protocol | Das Anwendungsprotokoll wird auf HTTP gesetzt, wenn das Feld headers.http_version im Rohlog HTTP enthält. |
Benötigen Sie weitere Hilfe? Antworten von Community-Mitgliedern und Google SecOps-Experten erhalten