GCP权限提升:滥用Function Admin角色实现完全项目接管
在之前的文章中,我们成功将权限从一个没有角色的服务账户提升到对存储桶具有只读权限的默认服务账户。这使我们能够读取和下载存储桶内容。
在今天的实验中,我们将详细介绍如何通过读取这些存储桶发现易受攻击的云函数的源代码,并最终实现完全项目接管。
我们将使用CyberWarFare Labs的Google Cloud Red Team Specialist(CGRTS)培训进行演示。这是一个优秀的实验,涵盖了许多真实的GCP攻击场景。
目录
- 所需工具
- 利用步骤
- 缓解策略
- 参考资料
- GCP渗透测试系列
所需工具
对于本实验,您需要在测试机器上安装gcloud CLI。您可以直接从Google Cloud安装,或使用RedCloud-OS - 这是CWL创建的VMware机器,预装了所有用于云渗透测试评估(GCP、Azure、AWS)的基本工具。
安装选项
- 安装gcloud CLI | Google Cloud CLI文档
- RedCloud-OS | GitHub
所需权限
- 具有Cloud Functions Admin权限的服务账户访问权限(用于修改和部署函数)
- 使用特权服务账户运行的目标函数,例如具有roles/owner角色的函数
利用步骤
在本实验中,我们获得了名为function-admin-srv-acc的服务账户的访问权限,该账户具有云函数管理员角色。我们通过查看函数的源代码,找到正确的输入参数,并调用函数来窃取其访问令牌。
现在,我们将了解如何使用这些权限来提升我们的访问权限并成为项目所有者。我们将通过修改函数的代码来获取附加到函数的访问令牌(具有roles/owner角色)来实现这一点。
1. 枚举IAM策略
每当我们获得新服务账户的访问权限时,第一步是检查其分配的角色:
|
|
我们可以看到function-admin-srv-acc账户分配了一个自定义角色:FunctionAdminlzg。
自定义角色通常遵循命名约定,以项目名称开头,后跟角色名称,如:
projects/[项目名称]/roles/[角色名称]
这与预定义角色(如roles/owner)不同,后者遵循以下格式:
roles/[角色名称]
自定义角色通常用于提供细粒度控制,仅授予目标用户所需的特定权限。
2. 枚举可用函数并检查IAM策略
下一步是使用functions list命令列出项目中的可用函数:
|
|
我们已在本系列的第1篇文章中破坏了network-mgmt-function,在第2篇文章中破坏了function-mgmt-function - 请查看这些文章以更好地了解我们如何达到这一点。
现在我们的目标是resource-mgmt-function。为了收集更多信息,我们使用describe命令检索其元数据:
|
|
从函数元数据中,有两个有趣的发现:
- 这是一个HTTP触发的函数 - 意味着我们可以使用curl或访问其URL来调用它。
- 该函数在默认服务账户下运行,该账户通常具有Editor角色,除非权限受到限制。
了解这一点后,我们可以在以下步骤中利用该函数。
3. 检查服务账户的IAM策略
由于我们从受损的服务账户function-admin-srv-acc获得了cloudfunctions.functions.update权限,我们可以更新函数的配置 - 包括其元数据,如名称、描述和附加的服务账户。
这意味着我们可以将函数的当前服务账户替换为具有更高权限(如roles/owner)的另一个服务账户,以提升我们的访问权限。
要检查分配给服务账户的角色,我们首先配置环境以使用正确的项目,然后列出所有可用的服务账户:
|
|
接下来,列出项目中的所有服务账户:
|
|
要检查分配给每个账户的角色,并识别任何比附加到resource-mgmt-function的默认账户具有更多权限的账户,我们可以手动运行以下命令:
|
|
或者,我们可以使用Bash脚本自动化此过程:
|
|
在下面的输出中,我们看到了服务账户列表及其分配的角色。在这里,我们识别出project-admin-srv-acc具有roles/owner权限!这为我们提供了一个可以绑定到resource-mgmt-function的更高权限服务账户。
我们可以进一步优化脚本,遍历自定义角色,检索其权限,甚至添加颜色以提高可读性。我将脚本添加到了GitHub - GCP仓库: https://github.com/nairuzabulhul/gcp-service-account-mapper
4. 更新函数元数据
我们将附加到函数的服务账户更新为project-admin-srv-acc,该账户在项目中具有Owner角色。
为此,我们运行gcloud functions deploy命令,传递函数的源代码和function-mgmt-srv-acc的访问令牌(我们已经破坏)来更新函数的设置。
我们在之前的文章中获得了函数源代码,当时我们获得了对存储桶具有只读OAuth范围的默认服务账户的访问权限。
以下是部署命令:
|
|
运行deploy命令时需要考虑以下几点:
- 主源文件必须命名为main.py、main.js或main.java等。
--source
标志应指向包含函数代码的目录。--entry-point
是在主源文件中定义的函数名称。
如下所示,我们成功运行了deploy命令,并将函数的服务账户更新为project-admin-srv。
5. 更新函数源代码
由于我们的服务账户function-admin-srv-acc具有管理员角色,该账户已包含在角色分配中的cloudfunctions.functions.sourceCodeSet权限。有了此权限,我们可以修改函数的代码并提取附加服务账户project-admin-srv的访问令牌。
以下是用于获取令牌的Python代码:
|
|
首先,确保function-admin-srv-acc服务账户具有新的访问令牌,因为它会在1小时后过期。您可以通过触发我们之前破坏的函数来获取令牌:
|
|
获得令牌后,使用新代码部署更新的函数:
|
|
部署后,调用更新的函数以检索访问令牌:
|
|
最后,验证访问令牌是否属于project-admin-srv-acc账户:
|
|
缓解策略
为了减少通过配置不当的Function Admin角色或过度许可的服务账户进行权限提升的风险,请考虑以下最佳实践:
- 仅授予所需的最小权限集。避免将Editor或Owner等角色分配给默认服务账户。
- 使用仅包含服务账户目的所需权限的自定义角色。除非必要,不要添加过度特权的权限,如cloudfunctions.sourceCodeSet、cloudfunctions.functions.update或iam.serviceAccounts.actAs。
- 审计现有的云函数,并停用那些已弃用或未使用的函数。
本实验突显了如何滥用通过配置不当的Function Admin角色授予的有限权限来提升权限并破坏整个GCP项目。
通过将IAM策略枚举、云函数滥用和服务账户模拟链接在一起,我们展示了一个导致roles/owner的完整权限提升路径。
至此,我们结束了本文。敬请期待下一篇文章!
参考资料
- Google Cloud Red Team Specialist [CGRTS]
- GCP渗透测试系列
- 使用配置不当的IAM策略窃取云函数访问令牌[GCP]
- 滥用计算实例IAM错误配置在GCP中获取权限
- GCP权限提升:滥用Function Admin角色实现完全项目接管