# GCP - Storage Privesc

{{#include ../../../banners/hacktricks-training.md}}

## Storage

Basiese inligting:

{{#ref}}
../gcp-services/gcp-storage-enum.md
{{#endref}}

### `storage.objects.get`

Hierdie toestemming laat jou toe om **lêers wat in Cloud Storage gestoor is af te laai**. Dit kan jou moontlik toelaat om voorregte te eskaleer omdat in sommige gevalle **sensitiewe inligting daar gestoor is**. Daarbenewens stoor sommige GCP-dienste hul inligting in buckets:

- **GCP Composer**: Wanneer jy 'n Composer Environment skep sal die **kode van al die DAGs** binne 'n **bucket** gestoor word. Hierdie take kan interessante inligting in hul kode bevat.
- **GCR (Container Registry)**: Die **image** van die containers word binne **buckets** gestoor, wat beteken dat as jy die buckets kan lees jy die images kan aflaai en **soek na leaks en/of bronkode**.

### `storage.objects.setIamPolicy`

Dit kan jou toelaat om jouself toestemming te gee om **enige van die vorige scenario's in hierdie afdeling te misbruik**.
```bash
# 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`**

Vir 'n voorbeeld van hoe om toestemmings te wysig met hierdie toestemming, sien hierdie bladsy:
```bash
# 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

```
{{#ref}}
../gcp-unauthenticated-enum-and-access/gcp-storage-unauthenticated-enum/gcp-public-buckets-privilege-escalation.md
{{#endref}}

### `storage.hmacKeys.create`

Cloud Storage se "interoperability"-funksie, ontwerp vir **cross-cloud interactions** soos met AWS S3, behels die **creation of HMAC keys for Service Accounts and users**. 'n Aanvaller kan dit misbruik deur **generating an HMAC key for a Service Account with elevated privileges**, en sodoende **escalating privileges within Cloud Storage**. Terwyl gebruiker-geassosieerde HMAC-sleutels slegs via die web console herwin kan word, bly beide die access en secret keys **perpetually accessible**, wat dit moontlik maak om toegang as 'n rugsteun te stoor. Daarenteen is Service Account-gekoppelde HMAC-sleutels API-accessible, maar hul access en secret keys is nie na skepping herwinbaar nie, wat 'n ekstra laag kompleksiteit byvoeg vir deurlopende toegang.
```bash
# 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"storage-sa@{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
```
Nog 'n exploit script vir hierdie metode kan gevind word [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/storage.hmacKeys.create.py).

### `storage.objects.create`, `storage.objects.delete` = Storage Write toestemmings

Om 'n nuwe objek binne 'n bucket te skep benodig jy `storage.objects.create` en, volgens [the docs](https://cloud.google.com/storage/docs/access-control/iam-permissions#object_permissions), benodig jy ook `storage.objects.delete` om 'n bestaande objek te wysig.

'n Baie algemene uitbuiting van buckets met skryfregte in die cloud is wanneer die bucket webserver-lêers stoor — jy kan dalk nuwe kode stoor wat deur die webtoepassing gebruik sal word.

### Composer

**Composer** is **Apache Airflow** bestuur binne GCP. Dit het verskeie interessante eienskappe:

- Dit loop binne 'n **GKE cluster**, dus is die **SA wat die cluster gebruik toeganklik** deur die kode wat binne Composer loop.
- Al die komponente van 'n Composer-omgewing (**kode van DAGs**, plugins en data) word gestoor in 'n GCP bucket. As die aanvaller lees- en skryfregte oor hierdie bucket het, kan hy die bucket monitor en **wanneer 'n DAG geskep of opgedateer word, 'n backdoored weergawe indien** sodat die Composer-omgewing die backdoored weergawe vanaf Storage kry.

**Jy kan 'n PoC van hierdie aanval in die repo vind:** [**https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs**](https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs)

### Cloud Functions

- Cloud Functions-kode word in Storage gestoor en wanneer 'n nuwe weergawe geskep word word die kode na die bucket ge-push en dan word die nuwe container uit hierdie kode gebou. Daarom, deur die kode oor te skryf voordat die nuwe weergawe gebou word, is dit moontlik om die Cloud Function arbitrary code te laat uitvoer.

**Jy kan 'n PoC van hierdie aanval in die repo vind:** [**https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions**](https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions)

### App Engine

AppEngine-weergawes genereer sekere data binne 'n bucket met die formaat naam: `staging.<project-id>.appspot.com`. Binne hierdie bucket is dit moontlik om 'n gids genaamd `ae` te vind wat 'n gids per weergawe van die AppEngine-app sal bevat en binne hierdie gidse sal dit moontlik wees om die `manifest.json` lêer te vind. Hierdie lêer bevat 'n json met al die lêers wat gebruik moet word om daardie spesifieke weergawe te skep. Verder is dit moontlik om die **werklike name van die lêers, die URL na hulle binne die GCP bucket (die lêers binne die bucket het hul naam verander na hul sha1-hash) en die sha1-hash van elke lêer** te vind.

_Note dat dit nie moontlik is om hierdie bucket vooraf te pre-takeover nie omdat GCP gebruikers nie gemagtig is om buckets te genereer met die domeinnaam appspot.com nie._

Met lees- en skryf toegang oor hierdie bucket is dit egter moontlik om voorregte te eskaleer na die SA wat aan die App Engine-weergawes gekoppel is deur die bucket te monitor en enige keer as 'n verandering gemaak word (nuwe weergawe), die nuwe weergawe so vinnig moontlik te wysig. Op hierdie manier sal die container wat uit hierdie kode geskep word die backdoored kode uitvoer.

Die genoemde aanval kan op baie verskillende maniere uitgevoer word; almal begin deur die `staging.<project-id>.appspot.com` bucket te monitor:

- Laai die volledige nuwe kode van die AppEngine-weergawes op na 'n ander beskikbare bucket en berei 'n **`manifest.json` lêer met die nuwe bucketnaam en sha1-hashes daarvan** voor. Dan, wanneer 'n nuwe weergawe binne die bucket geskep word, hoef jy net die `manifest.json` lêer te wysig en die kwaadwillige een op te laai.
- Laai 'n gemodifiseerde `requirements.txt` op wat die **kwaadwillige afhanklikhede-kode** sal gebruik en werk die `manifest.json` lêer by met die nuwe lêernaam, URL en die hash daarvan.
- Laai 'n **gemodifiseerde `main.py` of `app.yaml` lêer wat die kwaadwillige kode sal uitvoer** en werk die `manifest.json` lêer by met die nuwe lêernaam, URL en die hash daarvan.

**Jy kan 'n PoC van hierdie aanval in die repo vind:** [**https://github.com/carlospolop/Monitor-Backdoor-AppEngine**](https://github.com/carlospolop/Monitor-Backdoor-AppEngine)

### GCR

- **Google Container Registry** stoor die images binne buckets; as jy daardie buckets kan skryf kan jy dalk lateraal beweeg na waar daardie buckets uitgevoer word.
- Die bucket wat deur GCR gebruik word sal 'n URL hê soortgelyk aan `gs://<eu/usa/asia/nothing>.artifacts.<project>.appspot.com` (Die topvlak subdomeine word gespesifiseer [here](https://cloud.google.com/container-registry/docs/pushing-and-pulling)).

> [!TIP]
> Hierdie diens is deprecated, dus is hierdie aanval nie meer nuttig nie. Boonop stoor Artifact Registry, die diens wat hierdie een vervang, nie die images in buckets nie.

## **Verwysings**

- [https://rhinosecuritylabs.com/cloud-security/privilege-escalation-google-cloud-platform-part-2/#:\~:text=apiKeys.-,create,privileges%20than%20our%20own%20user.](https://rhinosecuritylabs.com/cloud-security/privilege-escalation-google-cloud-platform-part-2/)

{{#include ../../../banners/hacktricks-training.md}}
