GCP - Storage Enum

支持HackTricks

存储

Google Cloud Platform(GCP)存储是一种提供高度耐用和可用的对象存储的基于云的存储解决方案,适用于非结构化数据。它提供基于性能、可用性和成本的各种存储类别,包括标准、Nearline、Coldline和Archive。GCP存储还提供高级功能,如生命周期策略、版本控制和访问控制,以有效管理和保护数据。

存储桶可以存储在一个区域、2个区域或多个区域(默认)

存储类型

  • 标准存储:这是默认的存储选项,提供对频繁访问数据的高性能、低延迟访问。适用于各种用例,包括提供网站内容、流媒体传输和托管数据分析管道。

  • Nearline存储:此存储类别提供比标准存储更低的存储成本稍高的访问成本。它针对不经常访问的数据进行了优化,最短存储期为30天。非常适合备份和归档目的。

  • Coldline存储:此存储类别针对不经常访问的数据进行了长期存储,最短存储期为90天。它提供比Nearline存储更低的存储成本,但访问成本更高

  • Archive存储:此存储类别专为非常不经常访问的冷数据设计,最短存储期为365天。它提供所有GCP存储选项中最低的存储成本,但访问成本最高。适用于需要出于合规或监管原因存储的数据的长期保留。

  • 自动分类:如果不知道将访问多少数据,可以选择自动分类,GCP将自动更改存储类型以最小化成本

访问控制

默认情况下建议通过IAM控制访问,但也可以启用ACL的使用。 如果选择仅使用IAM(默认)并且经过90天,则将无法为存储桶启用ACL

版本控制

可以启用版本控制,这将保存存储桶中文件的旧版本。可以配置要保留的版本数量,甚至希望非当前版本(旧版本)存在多长时间。推荐为标准类型的7天

非当前版本的元数据会被保留。此外,非当前版本的ACL也会被保留,因此旧版本可能具有与当前版本不同的ACL。

文档中了解更多信息。

保留策略

指定希望禁止删除存储桶内对象的时间(至少对合规性非常有用)。 版本控制或保留策略只能同时启用一个

加密

默认情况下,对象使用Google托管密钥进行加密,但也可以使用来自KMS的密钥

公共访问

可以向外部用户(登录GCP或未登录)提供对存储桶内容的访问权限。 默认情况下,创建存储桶时,将禁用公开暴露存储桶的选项,但具有足够权限时可以更改。

访问存储桶的URL格式为**https://storage.googleapis.com/<bucket-name>https://<bucket_name>.storage.googleapis.com**(两者都有效)。

HMAC密钥

HMAC密钥是一种_凭证_,可以与Cloud Storage中的服务帐户或用户帐户关联。您使用HMAC密钥创建_签名_,然后将其包含在对Cloud Storage的请求中。签名表明给定请求由用户或服务帐户授权

HMAC密钥有两个主要部分,即_访问ID_和_密钥_。

  • 访问ID:与特定服务或用户帐户关联的字母数字字符串。当与服务帐户关联时,字符串长度为61个字符,当与用户帐户关联时,字符串长度为24个字符。以下是访问ID的示例:

GOOGTS7C7FUP3AIRVJTE2BCDKINBTES3HC2GY5CBFJDCQ2SYHV6A6XXVTJFSA

  • 密钥:与特定访问ID关联的40个字符的Base-64编码字符串。密钥是您和Cloud Storage知道的预共享密钥。您使用密钥在身份验证过程的一部分创建签名。以下是密钥的示例:

bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ

访问ID和密钥唯一标识HMAC密钥,但密钥是更敏感的信息,因为它用于创建签名

枚举

# 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>')

提权

在以下页面中,您可以查看如何滥用存储权限以提升权限

GCP - Storage Privesc

未认证枚举

GCP - Storage Unauthenticated Enum

后渗透

GCP - Storage Post Exploitation

持久性

GCP - Storage Persistence
支持HackTricks

Last updated