GCP - AppEngine Privesc

Tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

App Engine

Para mais informações sobre o App Engine, veja:

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 a CLI gcloud. Talvez as permissões get e list possam ser evitadas.

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

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

Implantar aplicação do App Engine ```bash 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, execute deploy novamente e aguarde alguns minutos.

Note

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

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:

Atualizar aplicação existente do App Engine ```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=@$PROJECT_ID.iam.gserviceaccount.com

</details>

Se você **já comprometeu um AppEngine** e tem a permissão **`appengine.applications.update`** e **actAs** sobre a conta de serviço que vai usar, você poderia modificar a conta de serviço usada pelo AppEngine com:

<details>
<summary>Atualizar conta de serviço do App Engine</summary>
```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

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

SSH em instância do App Engine ```bash gcloud app instances ssh --service --version ```

appengine.applications.update, appengine.operations.get

Acho que isso apenas altera a 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.

Atualizar conta de serviço da aplicação ```bash gcloud app update --service-account= ```

appengine.versions.getFileContents, appengine.versions.update

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

Write Access over the buckets

Como mencionado as versões do AppEngine geram alguns dados dentro de um bucket com o formato de nome: staging.<project-id>.appspot.com. Note que não é possível pre-takeover esse bucket porque usuários GCP não estão autorizados a gerar buckets usando o domínio appspot.com.

No entanto, com acesso de leitura & escrita sobre esse bucket, é possível escalar privilégios para a SA attached to the AppEngine version monitorando o bucket e, toda vez que uma mudança for realizada, modificar o código o mais rápido possível. Desta forma, o container que é criado a partir desse código irá execute the backdoored code.

Para mais informações e um PoC veja as informações relevantes nesta página:

GCP - Storage Privesc

Write Access over the Artifact Registry

Embora o App Engine crie docker images dentro do Artifact Registry, foi testado que mesmo se você modificar a imagem dentro deste serviço e remover a instância do App Engine (então uma nova é implantada) o código executado não muda.
Pode ser possível que, realizando um Race Condition attack, como com os buckets, seja possível sobrescrever o código executado, mas isso não foi testado.

Tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks