GCP - Storage Privesc

Tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks

Storage

Informazioni di base:

GCP - Storage Enum

storage.objects.get

Questa autorizzazione ti permette di scaricare file memorizzati in Cloud Storage. Questo potenzialmente può permetterti di escalate privileges perché in alcune occasioni informazioni sensibili sono memorizzate lì. Inoltre, alcuni servizi GCP memorizzano le loro informazioni in buckets:

  • GCP Composer: Quando crei un Composer Environment il codice di tutti i DAGs sarà salvato dentro un bucket. Questi task potrebbero contenere informazioni interessanti all’interno del loro codice.
  • GCR (Container Registry): Le image dei container sono memorizzate dentro buckets, il che significa che se puoi leggere i buckets potrai scaricare le immagini e cercare leak e/o codice sorgente.

storage.objects.setIamPolicy

Questa autorizzazione può permetterti di abusare di uno qualsiasi degli scenari precedenti di questa sezione.

# 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

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

# 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

La feature “interoperability” di Cloud Storage, progettata per le interazioni cross-cloud come con AWS S3, prevede la creazione di HMAC keys per Service Accounts e utenti. Un attacker può sfruttarla generando un HMAC key per un Service Account con privilegi elevati, ottenendo così una escalation dei privilegi all’interno di Cloud Storage. Mentre gli HMAC keys associati agli utenti sono recuperabili solo tramite il web console, sia gli access and secret keys restano perpetuamente accessibili, permettendo di conservarli come backup per l’accesso. Al contrario, gli HMAC keys collegati ai Service Account sono accessibili via API, ma i loro access and secret keys non sono recuperabili dopo la creazione, aggiungendo un 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 si trova here.

storage.objects.create, storage.objects.delete = Storage Write permissions

Per poter creare un nuovo oggetto all’interno di un bucket è necessario storage.objects.create e, secondo the docs, è inoltre necessario storage.objects.delete per modificare un oggetto esistente.

Un sfruttamento molto comune dei bucket su cui si può scrivere nel cloud è quando il bucket salva file del web server: potresti essere in grado di inserire nuovo codice che verrà utilizzato dall’applicazione web.

Composer

Composer è Apache Airflow gestito all’interno di GCP. Ha diverse caratteristiche interessanti:

  • Esegue all’interno di un GKE cluster, quindi la SA the cluster uses is accessible dal codice che gira dentro Composer
  • Tutti i componenti di un ambiente composer (code of DAGs, plugins and data) 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 backdoored così l’ambiente composer prenderà dalla storage la versione backdoored.

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

Cloud Functions

  • Il codice di Cloud Functions è memorizzato in Storage e ogni volta che viene creata una nuova versione il codice viene caricato nel bucket e poi il nuovo container viene costruito da questo codice. Pertanto, sovrascrivendo il codice prima che la nuova versione venga costruita è possibile far eseguire alla Cloud Function codice arbitrario.

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

App Engine

Le versioni di AppEngine generano alcuni dati all’interno di un bucket con nome nel formato: staging.<project-id>.appspot.com. All’interno di questo bucket è possibile trovare una cartella chiamata ae che conterrà una cartella per 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 usati per creare la specifica versione. Inoltre, è possibile trovare i nomi reali dei file, l’URL verso di essi all’interno del bucket GCP (i file dentro il bucket hanno cambiato nome con il loro sha1 hash) e l’hash sha1 di ciascun file.

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.

Tuttavia, con accesso di lettura e scrittura su questo bucket, è possibile escalare privilegi alla SA associata alla versione di App Engine monitorando il bucket e ogni volta che viene effettuato un cambiamento (nuova versione), modificare la nuova versione il più rapidamente possibile. In questo modo, il container che viene creato da questo codice eseguirà il codice backdoored.

L’attacco menzionato può essere eseguito in molti modi diversi, tutti partono dal monitorare il bucket staging.<project-id>.appspot.com:

  • Caricare il codice completo della nuova versione di AppEngine in un bucket diverso e disponibile e preparare un manifest.json con il nuovo nome del bucket e gli sha1 hash dei file. Poi, quando viene creata una nuova versione dentro il bucket, sarà sufficiente modificare il manifest.json e caricare quello malevolo.
  • Caricare una versione modificata di requirements.txt che userà il codice delle dipendenze malevole e aggiornare il manifest.json con il nuovo filename, URL e hash.
  • Caricare un file main.py o app.yaml modificato che eseguirà il codice malevolo e aggiornare il manifest.json con il nuovo filename, URL e hash.

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

GCR

  • Google Container Registry memorizza le immagini all’interno di bucket; se puoi scrivere in quei bucket potresti essere in grado di muoverti lateralmente verso i servizi dove quelle immagini vengono eseguite.
  • Il bucket usato da GCR avrà un URL simile a gs://<eu/usa/asia/nothing>.artifacts.<project>.appspot.com (I sottodomini di livello superiore sono specificati here).

Tip

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

References

Tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks