GCP - AppEngine Privesc

Support HackTricks

App Engine

Para mais informações sobre App Engine, confira:

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

Essas são as permissões necessárias para implantar um App usando gcloud cli. Talvez as permissões get e list possam ser evitadas.

Você pode encontrar exemplos de código em python em https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/appengine

Por padrão, o nome do serviço do App será default, e só pode haver 1 instância com o mesmo nome. Para alterá-lo e criar um segundo App, no app.yaml, altere o valor da chave raiz para algo como service: my-second-app

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

Dê pelo menos 10-15 minutos, se não funcionar, chame deploy another of times e espere alguns minutos.

É possível indicar a Service Account a ser usada, mas por padrão, a App Engine default SA é usada.

A URL da aplicação é algo como https://<proj-name>.oa.r.appspot.com/ ou https://<service_name>-dot-<proj-name>.oa.r.appspot.com

Atualizar permissões equivalentes

Você pode ter permissões suficientes para atualizar um AppEngine, mas não para criar um novo. Nesse caso, é assim que você poderia atualizar o App Engine atual:

# 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 você já comprometeu um AppEngine e tem a permissão appengine.applications.update e actAs sobre a conta de serviço a ser usada, você pode modificar a conta de serviço usada pelo AppEngine com:

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

Com essas permissões, é possível fazer login via ssh em instâncias do App Engine do tipo flexível (não padrão). Algumas das permissões list e get podem não ser realmente necessárias.

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

appengine.applications.update, appengine.operations.get

Acho que isso apenas altera o SA de fundo que o Google usará para configurar as aplicações, então não acho que você possa abusar disso para roubar a conta de serviço.

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

appengine.versions.getFileContents, appengine.versions.update

Não tenho certeza de como usar essas permissões ou se elas são úteis (note que quando você altera o código, uma nova versão é criada, então não sei se você pode apenas atualizar o código ou a função IAM de uma, mas acho que você deveria ser capaz, talvez alterando o código dentro do bucket??).

Acesso de Escrita sobre os buckets

Mesmo com acesso de escrita sobre os buckets onde o código-fonte está localizado NÃO FOI possível executar código arbitrário modificando o código-fonte e o manifest.json. Talvez se você estiver monitorando o bucket e detectar o momento em que uma nova versão é criada e o código-fonte e o manifesto são carregados, possa ser possível alterá-los para que a nova versão use os que têm backdoor??

Também parece que as camadas do contêiner são armazenadas no bucket, talvez alterando essas?

Support HackTricks

Last updated