GCP - Storage Privesc

Support HackTricks

Storage

Informazioni di base:

GCP - Storage Enum

storage.objects.get

Questo permesso ti consente di scaricare file memorizzati all'interno di Cloud Storage. Questo potrebbe potenzialmente consentirti di elevare i privilegi perché in alcune occasioni informazioni sensibili sono salvate lì. Inoltre, alcuni servizi GCP memorizzano le loro informazioni in bucket:

  • GCP Composer: Quando crei un Ambiente Composer, il codice di tutti i DAG sarà salvato all'interno di un bucket. Questi compiti potrebbero contenere informazioni interessanti all'interno del loro codice.

  • GCR (Container Registry): L'immagine dei contenitori è memorizzata all'interno di bucket, il che significa che se puoi leggere i bucket sarai in grado di scaricare le immagini e cercare leak e/o codice sorgente.

storage.objects.setIamPolicy

Puoi darti il permesso di abuse any of the previous scenarios of this section.

storage.buckets.setIamPolicy

Per un esempio su come modificare i permessi con questo permesso, controlla questa pagina:

GCP - Public Buckets Privilege Escalation

storage.hmacKeys.create

La funzione di "interoperabilità" di Cloud Storage, progettata per interazioni cross-cloud come con AWS S3, prevede la creazione di chiavi HMAC per Account di Servizio e utenti. Un attaccante può sfruttare questo generando una chiave HMAC per un Account di Servizio con privilegi elevati, elevando così i privilegi all'interno di Cloud Storage. Mentre le chiavi HMAC associate agli utenti sono recuperabili solo tramite la console web, sia le chiavi di accesso che quelle segrete rimangono perpetuamente accessibili, consentendo un potenziale accesso di backup. Al contrario, le chiavi HMAC collegate agli Account di Servizio sono accessibili tramite API, ma le loro chiavi di accesso e segrete non sono recuperabili dopo la creazione, aggiungendo un ulteriore livello di complessità per l'accesso continuo.

# 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

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

storage.objects.create, storage.objects.delete = Permessi di scrittura su Storage

Per creare un nuovo oggetto all'interno di un bucket hai bisogno di storage.objects.create e, secondo la documentazione, hai anche bisogno di storage.objects.delete per modificare un oggetto esistente.

Un'esploitazione molto comune dei bucket in cui puoi scrivere nel cloud è nel caso in cui il bucket stia salvando file del server web, potresti essere in grado di memorizzare nuovo codice che sarà utilizzato dall'applicazione web.

Composer

Composer è Apache Airflow gestito all'interno di GCP. Ha diverse funzionalità interessanti:

  • Viene eseguito all'interno di un cluster GKE, quindi il SA utilizzato dal cluster è accessibile dal codice in esecuzione all'interno di Composer

  • Tutti i componenti di un ambiente composer (codice dei DAG, plugin e dati) sono memorizzati all'interno di un bucket GCP. Se l'attaccante ha permessi di lettura e scrittura su di esso, potrebbe monitorare il bucket e ogni volta che un DAG viene creato o aggiornato, inviare una versione con backdoor in modo che l'ambiente composer ottenga dalla memorizzazione la versione con backdoor.

Puoi trovare una PoC di questo attacco nel repo: https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs

Cloud Functions

  • Il codice delle Cloud Functions è memorizzato in Storage e ogni volta che viene creata una nuova versione, il codice viene inviato al bucket e poi il nuovo contenitore viene costruito da questo codice. Pertanto, sovrascrivere il codice prima che venga costruita la nuova versione rende possibile far eseguire alla funzione cloud codice arbitrario.

Puoi trovare una PoC di questo attacco nel repo: https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions

App Engine

Le versioni di AppEngine generano alcuni dati all'interno di un bucket con il formato nome: staging.<project-id>.appspot.com. All'interno di questo bucket, è possibile trovare una cartella chiamata ae che conterrà una cartella per ogni versione dell'app AppEngine e all'interno di queste cartelle sarà possibile trovare il file manifest.json. Questo file contiene un json con tutti i file che devono essere utilizzati per creare la versione specifica. Inoltre, è possibile trovare i nomi reali dei file, l'URL ad essi all'interno del bucket GCP (i file all'interno del bucket hanno cambiato nome per il loro hash sha1) e l'hash sha1 di ciascun file.

Nota che non è possibile pre-prendere il controllo di questo bucket perché gli utenti GCP non sono autorizzati a generare bucket utilizzando il nome di dominio appspot.com.

Tuttavia, con accesso in lettura e scrittura su questo bucket, è possibile elevare i privilegi al SA associato alla versione di App Engine monitorando il bucket e ogni volta che viene eseguita una modifica (nuova versione), modificare la nuova versione il più rapidamente possibile. In questo modo, il contenitore che viene creato da questo codice eseguirà il codice con backdoor.

L'attacco menzionato può essere eseguito in molti modi diversi, tutti iniziano monitorando il bucket staging.<project-id>.appspot.com:

  • Carica il nuovo codice completo della versione di AppEngine su un bucket diverso e disponibile e prepara un file manifest.json con il nuovo nome del bucket e gli hash sha1 di essi. Poi, quando viene creata una nuova versione all'interno del bucket, devi solo modificare il file manifest.json e caricare quello malevolo.

  • Carica una versione modificata di requirements.txt che utilizzerà il codice delle dipendenze malevole e aggiorna il file manifest.json con il nuovo nome del file, URL e l'hash di esso.

  • Carica un file main.py o app.yaml modificato che eseguirà il codice malevolo e aggiorna il file manifest.json con il nuovo nome del file, URL e l'hash di esso.

Puoi trovare una PoC di questo attacco nel repo: https://github.com/carlospolop/Monitor-Backdoor-AppEngine

GCR

  • Google Container Registry memorizza le immagini all'interno dei bucket, se puoi scrivere in questi bucket potresti essere in grado di muoverti lateralmente verso dove questi bucket vengono eseguiti.

  • Il bucket utilizzato da GCR avrà un URL simile a gs://<eu/usa/asia/nothing>.artifacts.<project>.appspot.com (I sottodomini di livello superiore sono specificati qui).

Questo servizio è deprecato quindi questo attacco non è più utile. Inoltre, Artifact Registry, il servizio che sostituisce questo, non memorizza le immagini nei bucket.

Riferimenti

Supporta HackTricks

Last updated