GCP - AppEngine Privesc

Support HackTricks

App Engine

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

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 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, mude 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 aguarde alguns minutos.

É possível indicar a Conta de Serviço a ser usada mas, por padrão, a SA padrão do App Engine é utilizada.

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 que você poderia 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

Eu acho que isso apenas muda a SA de fundo que o Google usará para configurar as aplicações, então eu 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 o papel IAM de um, mas eu suponho que você deveria ser capaz de, talvez mudando o código dentro do bucket??).

Acesso de Escrita sobre os buckets

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

No entanto, com acesso de leitura e escrita sobre esse bucket, é possível escalar privilégios para o SA anexado à versão do AppEngine monitorando o bucket e, a qualquer momento que uma alteração for realizada, modificar o código o mais rápido possível. Dessa forma, o contêiner que é criado a partir desse código executará o código com backdoor.

Para mais informações e um PoC, verifique as informações relevantes desta página:

Acesso de Escrita sobre o Artifact Registry

Embora o App Engine crie imagens docker dentro do Artifact Registry. Foi testado que mesmo que você modifique a imagem dentro deste serviço e remova a instância do App Engine (para que uma nova seja implantada), o código executado não muda. Pode ser possível que, realizando um ataque de Condição de Corrida como com os buckets, pode ser possível sobrescrever o código executado, mas isso não foi testado.

Support HackTricks

Last updated