Exfiltration aus GCS und BigQuery: Spuren in Audit-Logs
Datendiebstahl aus Cloud Storage und BigQuery belegen oder ausschließen: massenhaftes storage.objects.get, öffentliche Buckets, HMAC-Schlüssel, Kopien, Images.
Kurz gesagt. Datendiebstahl aus Google Cloud zeigt sich an vier Stellen: Lesezugriffe (Wellen von storage.objects.get, nur mit Data-Access-Logs), Exposition (allUsers zur Richtlinie eines Buckets oder Datasets hinzugefügt, immer protokolliert), Kopien in ein anderes Projekt (BigQuery-Jobs mit fremdem Ziel, freigegebene Images und Snapshots) und Anmeldedaten durch die Hintertür (HMAC-Schlüssel). Bestimmen Sie das Expositionszeitfenster aus den Admin-Activity-Logs, auch wenn Lesezugriffe unsichtbar sind, und halten Sie das im Bericht ausdrücklich fest.
„Wurden Daten abgezogen?“ ist die Frage, die Rechtsabteilung und Geschäftsleitung zuerst stellen, und die, die Audit-Logs am unvollständigsten beantworten. Hier steht, was jedes Log belegen kann und was nicht.
Lesezugriffe: storage.objects.get
Jeder Objekt-Download über die JSON- oder XML-API von Cloud Storage ist ein Aufruf von storage.objects.get, erfasst als Data-Access-Audit-Log (DATA_READ), sofern das Data-Access-Logging für Cloud Storage aktiviert war (Audit-Logging in Cloud Storage). Der Eintrag nennt das Objekt in resourceName (projects/_/buckets/BUCKET/objects/NAME), die Identität, die Aufrufer-IP und den User-Agent.
logName:"cloudaudit.googleapis.com%2Fdata_access"
protoPayload.methodName="storage.objects.get"
resource.labels.bucket_name="BUCKET"
Was Sie herausziehen sollten:
- Volumen und Rate je Identität: hundert Objekte in wenigen Minuten durch eine Identität, die normalerweise vier am Tag liest.
- Objektnamen: Sie verraten, was abgeflossen ist (
customers/…,backups/…). - Die Identität: ein privates Konto, ein Dienstkontoschlüssel von einer unbekannten IP oder ein Dienst-Agent, der seine normale Arbeit tut.
- Außerdem
storage.objects.list(Erkundung vor dem Download) und, wenn der Angreifer kopiert statt herunterlädt,storage.objects.create/ rewrite in einem Ziel-Bucket unter seiner Kontrolle.
Das entspricht T1530, Data from Cloud Storage. Die Einschränkung wiegt schwer: Data-Access-Logs sind standardmäßig deaktiviert, und Google weist darauf hin, dass ihre Aktivierung für Cloud Storage in manchen Fällen authentifizierte Downloads im Browser scheitern lässt (Data-Access-Audit-Logs konfigurieren); deshalb schalten viele Projekte sie nie ein. Siehe Grenzen der Data-Access-Logs.
Exposition: allUsers und allAuthenticatedUsers
Einen Bucket öffentlich zu machen ist eine Richtlinienänderung, also Admin Activity, also immer protokolliert. Bei Buckets lautet die Methode storage.setIamPermissions; das Delta steht in serviceData.policyDelta.bindingDeltas:
{ "action": "ADD", "role": "roles/storage.objectViewer", "member": "allUsers" }
Sobald allUsers einen Bucket lesen kann, sind anonyme Downloads möglich, und Sie werden sie nicht sehen: Laut Google erfassen Cloud Audit Logs keine Zugriffe auf öffentliche Objekte (Audit-Logging in Cloud Storage). Nur die Nutzungslogs von Cloud Storage erfassen diesen Verkehr, sofern sie konfiguriert waren. Die ehrliche Schlussfolgerung ist ein Expositionszeitfenster: Vom ADD bis zum REMOVE (oder bis jetzt) war der Inhalt für jeden verfügbar, der den Bucket-Namen kannte oder erriet. Dieses Zeitfenster und die Liste der Objekte, die in dieser Zeit im Bucket lagen, braucht eine datenschutzrechtliche Bewertung. Googles Seite Daten öffentlich machen erklärt den Mechanismus; die Verhinderung öffentlichen Zugriffs blockiert ihn.
Dieselbe Logik gilt für allUsers bei BigQuery-Datasets, Cloud-Run-Diensten, Cloud Functions oder Images.
Hintertüren: HMAC-Schlüssel
storage.hmacKeys.create erstellt ein Paar aus Zugriffsschlüssel und Secret für die S3-kompatible XML-API. Das ist eher Persistenz als Exfiltration: Der Schlüssel funktioniert weiter, nachdem Sie die übrigen Anmeldedaten des Dienstkontos rotiert haben. Behandeln Sie jeden während des Vorfalls erstellten HMAC-Schlüssel als vom Angreifer kontrolliert (T1098.001).
BigQuery: Kopien in ein anderes Projekt
BigQuery unterscheidet sich in einem nützlichen Punkt: Für einige BigQuery-Dienste sind Data-Access-Audit-Logs standardmäßig aktiviert (Übersicht zu Cloud Audit Logs). Jobs (Abfragen, Kopien, Extraktionen) werden mit ihrer Konfiguration erfasst (BigQuery-Audit-Logs).
Das Signal, nach dem Sie suchen, ist ein Ziel außerhalb des Projekts: ein Kopier- oder Abfragejob, dessen destinationTable zu einer anderen Projekt-ID gehört. Ein Angreifer mit Lesezugriff auf Ihr Dataset und Schreibzugriff auf sein eigenes Projekt kann mit einem einzigen Aufruf eine ganze Tabelle verschieben: T1537, Transfer Data to Cloud Account. Prüfen Sie auch Extraktionsjobs (destinationUris, die auf gs://-Buckets zeigen, die Ihnen nicht gehören) und Änderungen an Dataset-Richtlinien (metadata.datasetChange.bindingDeltas).
Festplatten-Images und Snapshots
Wer ein Festplatten-Image oder einen Snapshot für ein anderes Projekt freigibt, kopiert die ganze Festplatte nach außen, Datenbanken und Anmeldedaten inklusive. Suchen Sie nach setIamPolicy auf compute.images, compute.snapshots, compute.disks und compute.machineImages und prüfen Sie dann, welche Mitglieder hinzugefügt wurden.
Ausgehender Netzwerkverkehr
Daten, die eine kompromittierte VM liest und nach außen sendet, erscheinen überhaupt nicht in den Audit-Logs. VPC Flow Logs sind die einzige Quelle: gesendete Bytes je externer IP.
Was der Analyzer markiert
| Regel | Schweregrad | Bedingung |
|---|---|---|
bulk_object_reads | Hoch | 100 storage.objects.get durch dieselbe Identität innerhalb von 10 Minuten (unabhängig vom Ergebnis) |
public_access_granted | Kritisch | allUsers / allAuthenticatedUsers zu einer beliebigen IAM-Richtlinie hinzugefügt |
bq_foreign_export | Hoch | BigQuery-Kopier- oder -Abfragejob, dessen Zieltabelle in einem anderen Projekt liegt |
image_shared | Mittel | IAM-Richtlinie eines Images, Snapshots, einer Festplatte oder eines Maschinen-Images geändert |
hmac_key_created | Mittel | storage.hmacKeys.create |
flow_large_egress (Analyse) | Mittel | 1 GiB oder mehr von Ihren VMs an eine einzelne öffentliche IP gesendet (VPC Flow Logs) |
Grenzen der aktuellen Regeln: BigQuery-Extraktionsjobs in externe Buckets werden noch nicht markiert, und ein vielbeschäftigtes ETL-Dienstkonto, das stetig liest, kann den Schwellwert für Massenlesezugriffe auslösen. Das Tool warnt außerdem, wenn ein Export keine Data-Access-Logs enthält, da bulk_object_reads ohne sie nicht anschlagen kann.
Der Bericht
Halten Sie für jedes betroffene Dataset und jeden Bucket getrennt fest: was nachweislich gelesen wurde (Objektnamen, Identität, Zeitpunkt), was exponiert war (Zeitfenster, vorhandene Objekte), was kopiert wurde (Zielprojekt, Tabelle, Image) und was sich wegen fehlender Logs nicht wissen lässt. Die Maßnahmenliste im Tool fordert zu dieser Bewertung auf, da Meldepflichten wie die 72-Stunden-Frist der DSGVO davon abhängen können.
Häufige Fragen
Kann ich sehen, welche Dateien aus einem Cloud-Storage-Bucket heruntergeladen wurden?
Nur wenn Data-Access-Audit-Logs (DATA_READ) für Cloud Storage vor dem Download aktiviert waren. Dann erzeugt jeder Lesezugriff einen Eintrag storage.objects.get mit Objektname, Identität und Aufrufer-IP. Ohne sie werden Lesezugriffe nicht in den Audit-Logs erfasst.
Woran erkenne ich, ob ein Bucket öffentlich gemacht wurde?
Suchen Sie nach Admin-Activity-Einträgen (storage.setIamPermissions bei Buckets), deren Policy-Delta allUsers oder allAuthenticatedUsers hinzufügt. Admin-Activity-Logs sind immer aktiv, diese Änderung wird also auch dann erfasst, wenn Lesezugriffe es nicht werden.
Weiterführende Links
- Cloud Audit Logs with Cloud Storage – Dokumentation von Google Cloud.
- BigQuery audit logs overview – Dokumentation von Google Cloud.
- SetIamPolicy-Missbrauch: Owner-Rechte für Externe aufspüren.