GCP - AppEngine Privesc

Apoya a HackTricks

App Engine

Para más información sobre App Engine revisa:

GCP - App Engine Enum

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

Esos son los permisos necesarios para desplegar una App usando gcloud cli. Tal vez los permisos get y list podrían ser evitados.

Puedes encontrar ejemplos de código en python en https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/appengine

Por defecto, el nombre del servicio de la App será default, y solo puede haber 1 instancia con el mismo nombre. Para cambiarlo y crear una segunda App, en app.yaml, cambia el valor de la clave raíz a algo como service: my-second-app

cd python-docs-samples/appengine/flexible/hello_world
gcloud app deploy #Upload and start application inside the folder

Dale al menos 10-15 minutos, si no funciona llama a deploy another of times y espera unos minutos.

Es posible indicar la Service Account a usar pero por defecto, se usa la App Engine default SA.

La URL de la aplicación es algo como https://<proj-name>.oa.r.appspot.com/ o https://<service_name>-dot-<proj-name>.oa.r.appspot.com

Actualizar permisos equivalentes

Podrías tener suficientes permisos para actualizar un AppEngine pero no para crear uno nuevo. En ese caso, así es como podrías actualizar el App Engine actual:

# 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 ya has comprometido un AppEngine y tienes el permiso appengine.applications.update y actAs sobre la cuenta de servicio que deseas usar, podrías modificar la cuenta de servicio utilizada por 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 estos permisos, es posible iniciar sesión vía ssh en instancias de App Engine de tipo flexible (no estándar). Algunas de las permisos list y get podrían no ser realmente necesarios.

gcloud app instances ssh --service <app-name> --version <version-id> <ID>

appengine.applications.update, appengine.operations.get

Creo que esto solo cambia la cuenta de servicio de fondo que Google usará para configurar las aplicaciones, así que no creo que puedas abusar de esto para robar la cuenta de servicio.

gcloud app update --service-account=<sa_email>

appengine.versions.getFileContents, appengine.versions.update

No estoy seguro de cómo usar estos permisos o si son útiles (ten en cuenta que cuando cambias el código se crea una nueva versión, así que no sé si puedes simplemente actualizar el código o el rol de IAM de uno, pero supongo que deberías poder, ¿tal vez cambiando el código dentro del bucket?).

Acceso de escritura sobre los buckets

Incluso con acceso de escritura sobre los buckets donde se encuentra el código fuente NO FUE posible ejecutar código arbitrario modificando el código fuente y el manifest.json. ¿Tal vez si estás monitoreando el bucket y detectas el momento en que se crea una nueva versión y se sube el código fuente y el manifiesto, podría ser posible cambiarlos para que la nueva versión use los que tienen puerta trasera?

También parece que las capas de contenedores se almacenan en el bucket, ¿tal vez cambiando esas?

Apoya a HackTricks

Last updated