GCP - Storage Enum

Support HackTricks

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で学べます。

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

# 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

バケットのリストを取得する際に「権限が拒否されました」というエラーが表示された場合でも、コンテンツにアクセスできる可能性があります。したがって、バケットの名前の規則について知っているので、可能な名前のリストを生成し、それらにアクセスを試みることができます:

for i in $(cat wordlist.txt); do gsutil ls -r gs://"$i"; done

storage.objects.liststorage.objects.get の権限があれば、バケット内のすべてのフォルダーとファイルを列挙してダウンロードできるはずです。これを実現するには、次の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>')

権限昇格

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

認証されていない列挙

ポストエクスプロイト

永続性

HackTricksをサポートする

Last updated