GCP - Storage Privesc

Support HackTricks

Storage

Podstawowe informacje:

storage.objects.get

To uprawnienie pozwala na pobieranie plików przechowywanych w Cloud Storage. Może to potencjalnie umożliwić eskalację uprawnień, ponieważ w niektórych przypadkach przechowywane są tam wrażliwe informacje. Ponadto, niektóre usługi GCP przechowują swoje informacje w bucketach:

  • GCP Composer: Gdy tworzysz środowisko Composer, kod wszystkich DAG-ów będzie zapisany w buckecie. Te zadania mogą zawierać interesujące informacje w swoim kodzie.

  • GCR (Container Registry): Obraz kontenerów jest przechowywany w bucketach, co oznacza, że jeśli możesz czytać buckety, będziesz mógł pobrać obrazy i szukać wycieków i/lub kodu źródłowego.

storage.objects.setIamPolicy

Możesz przyznać sobie uprawnienia do wykorzystania dowolnego z wcześniejszych scenariuszy tej sekcji.

storage.buckets.setIamPolicy

Aby zobaczyć przykład, jak zmodyfikować uprawnienia za pomocą tego uprawnienia, sprawdź tę stronę:

storage.hmacKeys.create

Funkcja "interoperacyjności" Cloud Storage, zaprojektowana do interakcji między chmurami jak z AWS S3, obejmuje tworzenie kluczy HMAC dla kont serwisowych i użytkowników. Atakujący może to wykorzystać, generując klucz HMAC dla konta serwisowego z podwyższonymi uprawnieniami, co pozwala na eskalację uprawnień w Cloud Storage. Podczas gdy klucze HMAC powiązane z użytkownikami są dostępne tylko za pośrednictwem konsoli internetowej, zarówno klucze dostępu, jak i tajne pozostają wiecznie dostępne, co umożliwia potencjalny dostęp do przechowywania kopii zapasowych. Z drugiej strony, klucze HMAC powiązane z kontem serwisowym są dostępne przez API, ale ich klucze dostępu i tajne nie są dostępne po utworzeniu, co dodaje warstwę złożoności dla ciągłego dostępu.

# 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

Inny skrypt exploitacyjny dla tej metody można znaleźć tutaj.

storage.objects.create, storage.objects.delete = Uprawnienia do zapisu w Storage

Aby utworzyć nowy obiekt w obrębie bucketu, potrzebujesz storage.objects.create, a zgodnie z dokumentacją, potrzebujesz również storage.objects.delete, aby zmodyfikować istniejący obiekt.

Bardzo częstym wykorzystaniem bucketów, w których można pisać w chmurze, jest sytuacja, gdy bucket przechowuje pliki serwera WWW, możesz być w stanie przechować nowy kod, który będzie używany przez aplikację internetową.

Composer

Composer to Apache Airflow zarządzany w GCP. Ma kilka interesujących funkcji:

  • Działa w obrębie klastra GKE, więc SA, którego używa klaster, jest dostępny przez kod działający w Composer

  • Wszystkie komponenty środowisk composera (kod DAGów, wtyczki i dane) są przechowywane w obrębie bucketu GCP. Jeśli atakujący ma uprawnienia do odczytu i zapisu, może monitorować bucket i za każdym razem, gdy DAG jest tworzony lub aktualizowany, przesłać wersję z backdoorem, aby środowisko composera pobrało z storage wersję z backdoorem.

Możesz znaleźć PoC tego ataku w repozytorium: https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs

Cloud Functions

  • Kod Cloud Functions jest przechowywany w Storage, a za każdym razem, gdy tworzona jest nowa wersja, kod jest przesyłany do bucketu, a następnie nowy kontener jest budowany z tego kodu. Dlatego nadpisanie kodu przed zbudowaniem nowej wersji umożliwia wykonanie dowolnego kodu przez funkcję chmurową.

Możesz znaleźć PoC tego ataku w repozytorium: https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions

App Engine

Wersje AppEngine generują pewne dane w obrębie bucketu w formacie nazwy: staging.<project-id>.appspot.com. W tym bucketcie można znaleźć folder o nazwie ae, który będzie zawierał folder dla każdej wersji aplikacji AppEngine, a w tych folderach będzie można znaleźć plik manifest.json. Plik ten zawiera json z wszystkimi plikami, które muszą być użyte do stworzenia konkretnej wersji. Co więcej, można znaleźć prawdziwe nazwy plików, URL do nich w obrębie bucketu GCP (pliki w bucketcie zmieniły swoją nazwę na ich sha1 hash) oraz sha1 hash każdego pliku.

Należy zauważyć, że nie jest możliwe wcześniejsze przejęcie tego bucketu, ponieważ użytkownicy GCP nie są uprawnieni do generowania bucketów przy użyciu nazwy domeny appspot.com.

Jednakże, mając dostęp do odczytu i zapisu w tym bucketcie, można eskalować uprawnienia do SA przypisanego do wersji App Engine, monitorując bucket i za każdym razem, gdy dokonana zostanie zmiana (nowa wersja), modyfikując nową wersję tak szybko, jak to możliwe. W ten sposób kontener, który zostanie stworzony z tego kodu, wykona kod z backdoorem.

Wspomniany atak można przeprowadzić na wiele różnych sposobów, wszystkie zaczynają się od monitorowania bucketu staging.<project-id>.appspot.com:

  • Prześlij kompletny nowy kod wersji AppEngine do innego dostępnego bucketu i przygotuj plik manifest.json z nową nazwą bucketu i sha1 hashami. Następnie, gdy nowa wersja zostanie utworzona w obrębie bucketu, wystarczy zmodyfikować plik manifest.json i przesłać złośliwy.

  • Prześlij zmodyfikowaną wersję requirements.txt, która będzie używać złośliwego kodu zależności i zaktualizuj plik manifest.json z nową nazwą pliku, URL i jego hashem.

  • Prześlij zmodyfikowany plik main.py lub app.yaml, który wykona złośliwy kod i zaktualizuj plik manifest.json z nową nazwą pliku, URL i jego hashem.

Możesz znaleźć PoC tego ataku w repozytorium: https://github.com/carlospolop/Monitor-Backdoor-AppEngine

GCR

  • Google Container Registry przechowuje obrazy w obrębie bucketów, jeśli możesz zapisać te buckety, możesz być w stanie przesunąć się lateralnie do miejsca, w którym te buckety są uruchamiane.

  • Bucket używany przez GCR będzie miał URL podobny do gs://<eu/usa/asia/nothing>.artifacts.<project>.appspot.com (Najwyższe subdomeny są określone tutaj).

Ta usługa jest przestarzała, więc ten atak nie jest już użyteczny. Co więcej, Artifact Registry, usługa, która zastępuje tę, nie przechowuje obrazów w bucketach.

Referencje

Wsparcie dla HackTricks

Last updated