# GCP - Storage Enum

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

## Storage

Google Cloud Platform (GCP) Storageは、**高い耐久性と可用性を提供するクラウドベースのストレージソリューション**で、非構造化データのためのオブジェクトストレージです。パフォーマンス、可用性、コストに基づいて、Standard、Nearline、Coldline、Archiveなどの**さまざまなストレージクラス**を提供します。GCP Storageは、データを効果的に管理および保護するための**ライフサイクルポリシー、バージョン管理、アクセス制御**などの高度な機能も提供します。

バケットは、1つのリージョン、2つのリージョン、または**マルチリージョン（デフォルト）**に保存できます。

### Storage Types

- **Standard Storage**: これはデフォルトのストレージオプションで、**頻繁にアクセスされるデータへの高性能、低遅延アクセスを提供**します。ウェブサイトのコンテンツ提供、メディアストリーミング、データ分析パイプラインのホスティングなど、幅広いユースケースに適しています。
- **Nearline Storage**: このストレージクラスは、Standard Storageよりも**低いストレージコスト**と**やや高いアクセスコスト**を提供します。アクセス頻度が低いデータ向けに最適化されており、最小ストレージ期間は30日です。バックアップやアーカイブ目的に最適です。
- **Coldline Storage**: このストレージクラスは、**アクセス頻度が低いデータの長期保存**に最適化されており、最小ストレージ期間は90日です。Nearline Storageよりも**低いストレージコスト**を提供しますが、**アクセスコストは高くなります**。
- **Archive Storage**: このストレージクラスは、**非常に低頻度でアクセスされる冷データ**向けに設計されており、最小ストレージ期間は365日です。すべてのGCPストレージオプションの中で**最も低いストレージコスト**を提供しますが、**最も高いアクセスコスト**があります。コンプライアンスや規制上の理由で保存する必要があるデータの長期保持に適しています。
- **Autoclass**: データにどれだけアクセスするか**わからない場合**は、Autoclassを選択すると、GCPが**コストを最小限に抑えるためにストレージの種類を自動的に変更します**。

### Access Control

**デフォルト**では、**IAMを介してアクセスを制御することが推奨されます**が、**ACLの使用を有効にすることも可能です**。\
IAMのみを使用することを選択し（デフォルト）、**90日が経過すると**、バケットに対して**ACLを有効にすることはできません**。

### Versioning

バージョン管理を有効にすることが可能で、これにより**バケット内のファイルの古いバージョンが保存されます**。**保持したいバージョンの数**や、**非現行**バージョン（古いバージョン）がどれだけの期間生存するかを**設定することができます**。Standardタイプの場合は**7日間が推奨されます**。

**非現行バージョンのメタデータは保持されます**。さらに、**非現行バージョンのACLも保持されるため**、古いバージョンは現在のバージョンとは異なるACLを持つ可能性があります。

詳細は[**docs**](https://cloud.google.com/storage/docs/object-versioning)で確認してください。

### Retention Policy

バケット内のオブジェクトの削除を**禁止したい期間**を指定します（コンプライアンスに非常に役立ちます）。\
**バージョン管理または保持ポリシーのいずれか一方のみを同時に有効にできます**。

### Encryption

デフォルトでは、オブジェクトは**Google管理のキーを使用して暗号化されます**が、**KMSのキーを使用することも可能です**。

### Public Access

**外部ユーザー**（GCPにログインしているかどうかにかかわらず）に**バケットのコンテンツへのアクセスを提供することが可能です**。\
デフォルトでは、バケットが作成されると、バケットを**公開にするオプションは無効**になりますが、十分な権限があれば変更できます。

バケットにアクセスするための**URLの形式**は、**`https://storage.googleapis.com/<bucket-name>`または`https://<bucket_name>.storage.googleapis.com`**（どちらも有効）です。

### HMAC Keys

HMACキーは、_資格情報_の一種であり、**Cloud Storageのサービスアカウントまたはユーザーアカウントに関連付けることができます**。HMACキーを使用して、Cloud Storageへのリクエストに含まれる_署名_を作成します。署名は、**特定のリクエストがユーザーまたはサービスアカウントによって承認されていることを示します**。

HMACキーには、_アクセスID_と_シークレット_の2つの主要な部分があります。

- **Access ID**: 特定のサービスまたはユーザーアカウントにリンクされた英数字の文字列です。サービスアカウントにリンクされている場合、文字列は61文字の長さで、ユーザーアカウントにリンクされている場合、文字列は24文字の長さです。以下はアクセスIDの例です：

`GOOGTS7C7FUP3AIRVJTE2BCDKINBTES3HC2GY5CBFJDCQ2SYHV6A6XXVTJFSA`

- **Secret**: 特定のアクセスIDにリンクされた40文字のBase-64エンコードされた文字列です。シークレットは、あなたとCloud Storageだけが知っている事前共有キーです。認証プロセスの一部として署名を作成するためにシークレットを使用します。以下はシークレットの例です：

`bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ`

**アクセスIDとシークレットはHMACキーを一意に識別しますが、シークレットは署名を**作成するために使用されるため、はるかに敏感な情報です**。

### Enumeration
```bash
# List all storage buckets in project
gsutil ls

# Get each bucket configuration (protections, CLs, times, configs...)
gsutil ls -L

# List contents of a specific bucket
gsutil ls gs://bucket-name/
gsutil ls -r gs://bucket-name/ # Recursive
gsutil ls -a gs://bucket-name/ # Get ALL versions of objects

# Cat the context of a file without copying it locally
gsutil cat 'gs://bucket-name/folder/object'
gsutil cat 'gs://bucket-name/folder/object#<num>' # cat specific version

# Copy an object from the bucket to your local storage for review
gsutil cp gs://bucket-name/folder/object ~/

# List using a raw OAuth token
## Useful because "CLOUDSDK_AUTH_ACCESS_TOKEN" and "gcloud config set auth/access_token_file" doesn't work with gsutil
curl -H "Authorization: Bearer $TOKEN" "https://storage.googleapis.com/storage/v1/b/<storage-name>/o"
# Download file content from bucket
curl -H "Authorization: Bearer $TOKEN" "https://storage.googleapis.com/storage/v1/b/supportstorage-58249/o/flag.txt?alt=media" --output -

# Enumerate HMAC keys
gsutil hmac list

# Get permissions
gcloud storage buckets get-iam-policy gs://bucket-name/
gcloud storage objects get-iam-policy gs://bucket-name/folder/object
```
バケットのリストを取得する際に「権限が拒否されました」というエラーが表示される場合でも、コンテンツにアクセスできる可能性があります。したがって、バケットの名前の規則について知っているので、考えられる名前のリストを生成し、それらにアクセスしてみることができます：
```bash
for i in $(cat wordlist.txt); do gsutil ls -r gs://"$i"; done
```
`storage.objects.list` と `storage.objects.get` の権限があれば、バケット内のすべてのフォルダーとファイルを列挙してダウンロードすることができます。これを実現するための Python スクリプトは次のとおりです:
```python
import requests
import xml.etree.ElementTree as ET

def list_bucket_objects(bucket_name, prefix='', marker=None):
url = f"https://storage.googleapis.com/{bucket_name}?prefix={prefix}"
if marker:
url += f"&marker={marker}"
response = requests.get(url)
xml_data = response.content
root = ET.fromstring(xml_data)
ns = {'ns': 'http://doc.s3.amazonaws.com/2006-03-01'}
for contents in root.findall('.//ns:Contents', namespaces=ns):
key = contents.find('ns:Key', namespaces=ns).text
print(key)
next_marker = root.find('ns:NextMarker', namespaces=ns)
if next_marker is not None:
next_marker_value = next_marker.text
list_bucket_objects(bucket_name, prefix, next_marker_value)

list_bucket_objects('<storage-name>')
```
### 権限昇格

次のページでは、**ストレージの権限を悪用して権限を昇格させる方法**を確認できます：

{{#ref}}
../gcp-privilege-escalation/gcp-storage-privesc.md
{{#endref}}

### 認証されていない列挙

{{#ref}}
../gcp-unauthenticated-enum-and-access/gcp-storage-unauthenticated-enum/
{{#endref}}

### ポストエクスプロイト

{{#ref}}
../gcp-post-exploitation/gcp-storage-post-exploitation.md
{{#endref}}

### 永続性

{{#ref}}
../gcp-persistence/gcp-storage-persistence.md
{{#endref}}

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