# GCP - AppEngine Privesc

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

## App Engine

Vir meer inligting oor App Engine, sien:

{{#ref}}
../gcp-services/gcp-app-engine-enum.md
{{#endref}}

### `appengine.applications.get`, `appengine.instances.get`, `appengine.instances.list`, `appengine.operations.get`, `appengine.operations.list`, `appengine.services.get`, `appengine.services.list`, `appengine.versions.create`, `appengine.versions.get`, `appengine.versions.list`, `cloudbuild.builds.get`,`iam.serviceAccounts.actAs`, `resourcemanager.projects.get`, `storage.objects.create`, `storage.objects.list`

Dit is die nodige permissies om 'n App met die `gcloud` cli te ontplooi. Miskien kan die **`get`** en **`list`** permissies **vermyd** word.

Jy kan python-kodevoorbeelde vind by [https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/appengine](https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/appengine)

Standaard sal die naam van die App-diens **`default`** wees, en daar kan slegs 1 instansie met dieselfde naam wees.\
Om dit te verander en 'n tweede App te skep, verander in **`app.yaml`** die waarde van die root-sleutel na iets soos **`service: my-second-app`**
```bash
cd python-docs-samples/appengine/flexible/hello_world
gcloud app deploy #Upload and start application inside the folder
```
Gee dit minstens 10–15 minute; as dit nie werk nie, probeer **deploy nog 'n paar keer** en wag 'n paar minute.

> [!NOTE]
> Dit is **moontlik om die Service Account aan te dui wat gebruik moet word**, maar standaard word die App Engine default SA gebruik.

Die URL van die toepassing is iets soos `https://<proj-name>.oa.r.appspot.com/` of `https://<service_name>-dot-<proj-name>.oa.r.appspot.com`

### Werk ekwivalente toestemmings by

Jy mag genoeg toestemmings hê om 'n AppEngine op te dateer, maar nie om 'n nuwe een te skep nie. In daardie geval is dit hoe jy die huidige App Engine kan opdateer:
```bash
# Find the code of the App Engine in the buckets
gsutil ls

# Download code
mkdir /tmp/appengine2
cd /tmp/appengine2
## In this case it was found in this custom bucket but you could also use the
## buckets generated when the App Engine is created
gsutil cp gs://appengine-lab-1-gcp-labs-4t04m0i6-3a97003354979ef6/labs_appengine_1_premissions_privesc.zip .
unzip labs_appengine_1_premissions_privesc.zip

## Now modify the code..

## If you don't have an app.yaml, create one like:
cat >> app.yaml <<EOF
runtime: python312

entrypoint: gunicorn -b :\$PORT main:app

env_variables:
A_VARIABLE: "value"
EOF

# Deploy the changes
gcloud app deploy

# Update the SA if you need it (and if you have actas permissions)
gcloud app update --service-account=<sa>@$PROJECT_ID.iam.gserviceaccount.com
```
As jy **reeds 'n AppEngine gekompromitteer het** en jy het die toestemming **`appengine.applications.update`** en **actAs** oor die service account wat gebruik word, kan jy die service account wat deur AppEngine gebruik word wysig met:
```bash
gcloud app update --service-account=<sa>@$PROJECT_ID.iam.gserviceaccount.com
```
### `appengine.instances.enableDebug`, `appengine.instances.get`, `appengine.instances.list`, `appengine.operations.get`, `appengine.services.get`, `appengine.services.list`, `appengine.versions.get`, `appengine.versions.list`, `compute.projects.get`

Met hierdie toestemmings is dit moontlik om **login via ssh in App Engine instances** van die tipe **flexible** (nie standard nie). Sommige van die **`list`** en **`get`** toestemmings mag nie werklik nodig wees nie.
```bash
gcloud app instances ssh --service <app-name> --version <version-id> <ID>
```
### `appengine.applications.update`, `appengine.operations.get`

Ek dink dit verander net die agtergrond-SA wat google sal gebruik om die toepassings op te stel, so ek dink nie jy kan dit misbruik om die service account te steel nie.
```bash
gcloud app update --service-account=<sa_email>
```
### `appengine.versions.getFileContents`, `appengine.versions.update`

Ek is nie seker hoe om hierdie toestemmings te gebruik of of hulle nuttig is nie (let wel: wanneer jy die kode verander word 'n nuwe weergawe geskep, so ek weet nie of jy net die kode kan opdateer of die IAM-rol van een kan verander nie; maar ek vermoed dit behoort moontlik te wees — dalk deur die kode binne die bucket te verander??).

### `bigquery.tables.delete`, `bigquery.datasets.delete` & `bigquery.models.delete` (`bigquery.models.getMetadata`)

Om tabelle, datastelle of modelle te verwyder:
```bash
# Table removal
bq rm -f -t <PROJECT_ID>.<DATASET>.<TABLE_NAME>

# Dataset removal
bq rm -r -f <PROJECT_ID>:<DATASET>

# Model removal
bq rm -m <PROJECT_ID>:<DATASET_NAME>.<MODEL_NAME>
```
### Misbruik van Scheduled Queries

Met die `bigquery.datasets.get`, `bigquery.jobs.create`, en `iam.serviceAccounts.actAs` toestemmings kan 'n identiteit dataset-metadata navraag doen, BigQuery-jobs begin, en dit uitvoer met 'n Service Account met hoër bevoegdhede.

Hierdie aanval maak kwaadwillige gebruik van Scheduled Queries moontlik om navrae te outomatiseer (uitgevoer onder die gekose Service Account), wat byvoorbeeld kan lei tot sensitiewe data wat gelees en in 'n ander tabel of dataset geskryf word waartoe die aanvaller wel toegang het — wat indirekte en voortdurende exfiltration vergemaklik sonder om die data ekstern te hoef te onttrek.

Sodra die aanvaller weet watter Service Account die nodige toestemmings het om die gewenste navraag uit te voer, kan hulle 'n Scheduled Query-konfigurasie skep wat met daardie Service Account loop en periodiek die resultate in 'n dataset skryf van hul keuse.
```bash
bq mk \
--transfer_config \
--project_id=<PROJECT_ID> \
--location=US \
--data_source=scheduled_query \
--target_dataset=<DEST_DATASET> \
--display_name="Generic Scheduled Query" \
--service_account_name="<SERVICE_ACCOUNT>@<PROJECT_ID>.iam.gserviceaccount.com" \
--schedule="every 10 minutes" \
--params='{
"query": "SELECT * FROM `<PROJECT_ID>.<SOURCE_DATASET>.<source_table>`;",
"destination_table_name_template": "<destination_table>",
"write_disposition": "WRITE_TRUNCATE"
}'

```
### Skryf toegang oor die buckets

Soos vermeld genereer die appengine versions sekere data binne 'n bucket met die formaatnaam: `staging.<project-id>.appspot.com`. Neem kennis dat dit nie moontlik is om hierdie bucket vooraf oor te neem nie omdat GCP-gebruikers nie gemagtig is om buckets te genereer met die domeinnaam `appspot.com` nie.

Echter, met read & write toegang tot hierdie bucket is dit moontlik om privilegies op te skaal na die SA attached to the AppEngine version deur die bucket te monitor en, enige keer as 'n verandering uitgevoer word, die code so vinnig as moontlik te wysig. Op hierdie manier sal die container wat uit hierdie code geskep word **execute the backdoored code**.

Vir meer inligting en 'n **PoC check the relevant information from this page**:

{{#ref}}
gcp-storage-privesc.md
{{#endref}}

### Skryf toegang oor die Artifact Registry

Alhoewel App Engine docker images binne Artifact Registry skep. Dit is getoets dat **even if you modify the image inside this service** en die App Engine instance verwyder (so 'n nuwe een is deployed) die **code executed doesn't change**.\ It might be possible that performing a **Race Condition attack like with the buckets it might be possible to overwrite the executed code**, maar dit is nie getoets nie.

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