GCP - AppEngine Privesc

Tip

学习并练习 AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
学习并练习 GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
学习并练习 Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks

App Engine

有关 App Engine 的更多信息,请查看:

GCP - App Engine Enum

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 所需的权限。也许可以省略 getlist 权限。

你可以在 https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/appengine 找到 python 代码示例。

默认情况下,App 服务的名称为 default,并且同名实例只能有 1 个。
要更改并创建第二个 App,在 app.yaml 中将根键的值改为类似 service: my-second-app

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:

# 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 使用的服务帐号:

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 登录。某些 listget 权限可能并非真正必要。

gcloud app instances ssh --service <app-name> --version <version-id> <ID>

appengine.applications.update, appengine.operations.get

我认为这只是更改 google 用来设置应用程序的后台 SA,因此我认为你无法滥用它来窃取 service account。

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:

# 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.getbigquery.jobs.createiam.serviceAccounts.actAs 权限的身份,可以查询数据集元数据、启动 BigQuery 作业,并使用权限更高的 Service Account 来执行这些作业。

该攻击允许恶意利用 Scheduled Queries 来自动化查询(在所选的 Service Account 下运行),例如可能导致敏感数据被读取并写入攻击者可访问的另一个表或数据集——从而实现间接和持续的 exfiltration,而无需将数据提取到外部。

一旦攻击者知道哪个 Service Account 拥有执行目标查询所需的权限,就可以创建一个使用该 Service Account 运行的 Scheduled Query 配置,定期将结果写入其选择的数据集。

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(请查看此页面的相关信息)

GCP - Storage Privesc

对 Artifact Registry 的写入访问权限

尽管 App Engine 会在 Artifact Registry 中创建 docker images,经测试,即使你修改该服务内的镜像 并删除 App Engine 实例(因此会部署一个新的实例),被执行的代码并不会改变
有可能通过执行类似对存储桶的 Race Condition attack 来覆盖被执行的代码,但这没有经过测试。

Tip

学习并练习 AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
学习并练习 GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
学习并练习 Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks