# GCP - Storage Privesc

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

## Storage

Osnovne informacije:

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

### `storage.objects.get`

Ova dozvola vam omogućava da **preuzmete datoteke smeštene unutar Cloud Storage**. Ovo potencijalno može omogućiti eskalaciju privilegija jer se u nekim slučajevima **osetljive informacije čuvaju tamo**. Štaviše, neke GCP usluge čuvaju svoje informacije u kanticama:

- **GCP Composer**: Kada kreirate Composer Environment, **kod svih DAG-ova** će biti sačuvan unutar **kante**. Ove zadatke mogu sadržati zanimljive informacije unutar svog koda.
- **GCR (Container Registry)**: **Slika** kontejnera se čuva unutar **kanti**, što znači da ako možete da čitate kante, bićete u mogućnosti da preuzmete slike i **tražite curenja i/ili izvorni kod**.

### `storage.objects.setIamPolicy`

Možete sebi dati dozvolu da **zloupotrebljavate bilo koji od prethodnih scenarija u ovoj sekciji**.

### **`storage.buckets.setIamPolicy`**

Za primer kako da modifikujete dozvole sa ovom dozvolom, pogledajte ovu stranicu:

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

### `storage.hmacKeys.create`

Funkcija "interoperabilnosti" Cloud Storage-a, dizajnirana za **interakcije između različitih cloud-a** kao što je AWS S3, uključuje **kreiranje HMAC ključeva za Service Accounts i korisnike**. Napadač može iskoristiti ovo tako što će **generisati HMAC ključ za Service Account sa povišenim privilegijama**, čime se **escalira privilegije unutar Cloud Storage**. Dok su HMAC ključevi povezani sa korisnicima dostupni samo putem web konzole, pristupni i tajni ključevi ostaju **večno dostupni**, omogućavajući potencijalni pristup za backup. S druge strane, HMAC ključevi povezani sa Service Account-om su dostupni putem API-ja, ali njihovi pristupni i tajni ključevi nisu dostupni nakon kreiranja, dodajući sloj složenosti za kontinuirani pristup.
```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"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
```
Još jedan exploit skript za ovu metodu može se naći [ovde](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/storage.hmacKeys.create.py).

## `storage.objects.create`, `storage.objects.delete` = Dozvole za pisanje u skladištu

Da biste **napravili novi objekat** unutar bucket-a, potrebni su vam `storage.objects.create` i, prema [dokumentaciji](https://cloud.google.com/storage/docs/access-control/iam-permissions#object_permissions), takođe vam je potrebna `storage.objects.delete` da biste **izmenili** postojeći objekat.

Veoma **česta eksploatacija** bucket-a u kojima možete pisati u oblaku je u slučaju da **bucket čuva datoteke web servera**, možda ćete moći da **sačuvate novi kod** koji će se koristiti u web aplikaciji.

### Composer

**Composer** je **Apache Airflow** koji se upravlja unutar GCP-a. Ima nekoliko zanimljivih karakteristika:

- Radi unutar **GKE klastera**, tako da je **SA koji klaster koristi dostupan** kodu koji se izvršava unutar Composera
- Svi komponenti okruženja Composera (**kod DAG-ova**, dodaci i podaci) se čuvaju unutar GCP bucket-a. Ako napadač ima dozvole za čitanje i pisanje nad njim, mogao bi da prati bucket i **kada god se DAG kreira ili ažurira, pošalje verziju sa backdoor-om** tako da okruženje Composer preuzme verziju sa backdoor-om iz skladišta.

**Možete pronaći PoC ovog napada u repozitorijumu:** [**https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs**](https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs)

### Cloud Functions

- Kod Cloud Functions se čuva u Storage-u i kada se kreira nova verzija, kod se šalje u bucket, a zatim se novi kontejner gradi iz ovog koda. Stoga, **prepisivanje koda pre nego što nova verzija bude izgrađena omogućava izvršavanje proizvoljnog koda u cloud funkciji**.

**Možete pronaći PoC ovog napada u repozitorijumu:** [**https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions**](https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions)

### App Engine

AppEngine verzije generišu neke podatke unutar bucket-a u formatu imena: `staging.<project-id>.appspot.com`. Unutar ovog bucket-a, moguće je pronaći folder pod nazivom `ae` koji će sadržati folder po verziji AppEngine aplikacije i unutar ovih foldera biće moguće pronaći datoteku `manifest.json`. Ova datoteka sadrži json sa svim datotekama koje moraju biti korišćene za kreiranje specifične verzije. Štaviše, moguće je pronaći **prava imena datoteka, URL do njih unutar GCP bucket-a (datoteke unutar bucket-a su promenile svoje ime u njihov sha1 hash) i sha1 hash svake datoteke.**

_Napomena: nije moguće unapred preuzeti ovaj bucket jer GCP korisnici nisu ovlašćeni da generišu buckete koristeći naziv domena appspot.com._

Međutim, sa pristupom za čitanje i pisanje nad ovim bucket-om, moguće je eskalirati privilegije na SA vezanu za verziju App Engine-a praćenjem bucket-a i svaki put kada se izvrši promena (nova verzija), izmeniti novu verziju što je brže moguće. Na ovaj način, kontejner koji se kreira iz ovog koda će izvršiti kod sa backdoor-om.

Pomenuti napad može se izvesti na mnogo različitih načina, svi počinju praćenjem `staging.<project-id>.appspot.com` bucket-a:

- Učitajte kompletan novi kod verzije AppEngine u drugi i dostupni bucket i pripremite **`manifest.json` datoteku sa novim imenom bucket-a i sha1 hash-evima**. Zatim, kada se unutar bucket-a kreira nova verzija, samo treba da izmenite `manifest.json` datoteku i učitate zlonamernu.
- Učitajte izmenjenu verziju `requirements.txt` koja će koristiti **kod zlonamernih zavisnosti i ažurirati `manifest.json`** datoteku sa novim imenom datoteke, URL-om i hash-om.
- Učitajte **izmenjenu `main.py` ili `app.yaml` datoteku koja će izvršiti zlonamerni kod** i ažurirati `manifest.json` datoteku sa novim imenom datoteke, URL-om i hash-om.

**Možete pronaći PoC ovog napada u repozitorijumu:** [**https://github.com/carlospolop/Monitor-Backdoor-AppEngine**](https://github.com/carlospolop/Monitor-Backdoor-AppEngine)

### GCR

- **Google Container Registry** čuva slike unutar bucket-a, ako možete **pisati u te buckete**, možda ćete moći da **napravite lateralni pomak do mesta gde se ti bucketi izvršavaju.**
- Bucket koji koristi GCR će imati URL sličan `gs://<eu/usa/asia/nothing>.artifacts.<project>.appspot.com` (Najviši nivo poddomena je specificiran [ovde](https://cloud.google.com/container-registry/docs/pushing-and-pulling)).

> [!TIP]
> Ova usluga je ukinuta, tako da ovaj napad više nije koristan. Štaviše, Artifact Registry, usluga koja zamenjuje ovu, ne čuva slike u bucket-ima.

## **Reference**

- [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}}
