GCP - AppEngine Privesc
Reading time: 6 minutes
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
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.
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.
note
É 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 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 acho que você deve 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 Registro de Artefatos
Embora o App Engine crie imagens docker dentro do Registro de Artefatos. 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.
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
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.