缓解 Google Cloud CLI 的 OAuth 令牌被破解的最佳实践

Last reviewed 2024-02-15 UTC

本文档介绍了如何缓解攻击者破解 gcloud CLI 所使用的 OAuth 令牌造成的影响。

如果攻击者获得访问正当用户账号或服务账号已使用 gcloud CLI 进行身份验证的端点的权限,则可以破解这些 OAuth 令牌。然后,攻击者可以将这些令牌复制到他们控制的其他端点,以发出模拟合法身份的请求。即使您移除攻击者对遭破解端点的访问权限,攻击者仍然可以使用复制的令牌发出经过身份验证的 API 请求。为帮助降低此风险,您可以使用短期有效和情境感知的凭据来控制对系统的访问权限。

本文档适用于负责保护云资源免遭非法访问的安全团队或云架构师。本文档介绍了一些可用控件,可供您用来主动降低被盗用的 gcloud CLI OAuth 令牌的影响,并在端点被盗用后修复您的环境。

概览

如需了解此威胁的工作原理,您必须了解 gcloud CLI 如何存储 OAuth 2.0 凭据,以及这些凭据遭攻击者破解时如何被滥用。

gcloud CLI 存储的凭据类型

gcloud CLI 使用 OAuth 2.0 访问令牌对 Google Cloud API 请求进行身份验证。OAuth 流程因使用的凭据类型而异,但访问令牌和其他凭据通常可在本地访问。每种情况下,访问令牌都会在 60 分钟后到期,但其他凭据类型可能是永久性的。

当您使用用户账号向 gcloud CLI 授权时,gcloud CLI 会启动三足式 OAuth 同意流程,以代表用户访问 Google Cloud API。用户完成同意流程后,gcloud CLI 会收到访问令牌以及使其能够请求新访问令牌的刷新令牌。在默认设置下,长期有效的刷新令牌在满足到期条件之前会一直保留。

当您使用服务账号向 gcloud CLI 授权时,gcloud CLI 会启动二足式 OAuth 流程,以服务账号身份访问 Google Cloud API。通过私钥文件激活服务账号后,此密钥将用于定期请求访问令牌。长期有效的私钥存储在 gcloud CLI 配置中,在您删除服务账号密钥之前一直有效。

在 Google Cloud 环境(例如 Compute Engine 或 Cloud Shell)中运行 gcloud CLI 时,应用可以自动查找凭据并以服务账号身份进行身份验证。例如,在 Compute Engine 中,像 gcloud CLI 这样的应用可以在元数据服务器中查询访问令牌。Google 会管理和轮替用于创建访问令牌的签名私钥,并且不会向应用公开长期有效的凭据。

当您使用工作负载身份联合进行身份验证时,应用会根据来自外部身份提供方的凭据进行身份验证,并接收短期有效的联合访问令牌。如需详细了解如何存储和管理外部身份提供方使用的长期有效凭据,请参阅使用工作负载身份联合的最佳实践

攻击者如何使用被破解的 OAuth 令牌

如果攻击者成功破解了端点,则 OAuth 令牌等凭据是有价值的目标,因为它们可让攻击者保留或提升其访问权限。

开发者在编写和调试代码时可能有合法需求来查看自己的凭据。例如,使用不受支持的客户端库时,开发者可能需要使用 REST 请求向 Google Cloud 服务进行身份验证。开发者可以通过各种方法查看凭据,包括:

但是,攻击者可能会在破解端点后使用上述相同的方法。

如果攻击者破解了端点(例如开发者工作站),则主要威胁是攻击者可以使用经过身份验证的身份的合法凭据运行 gcloud CLI 命令或其他代码。此外,攻击者可能会将 OAuth 令牌复制到他们控制的其他端点以保留其访问权限。此凭据发生盗用时,会存在一个次要威胁:即使您移除了对遭破解的端点的访问权限,攻击者仍然可以使用长期有效的 OAuth 令牌获得永久性访问权限。

如果攻击者设法破解了 OAuth 令牌,则可以完成以下操作:

  • 攻击者可以冒充被盗用的用户或服务账号。使用被破解的令牌的 API 流量会被记录为来自被破解的用户或服务账号,因此很难区分日志中的正常活动和恶意活动。
  • 攻击者可以使用与用户关联的永久性刷新令牌或与服务账号关联的私钥无限期地刷新访问令牌。
  • 攻击者可以使用用户的密码或两步验证绕过身份验证,因为令牌是在登录流程后授予的。

降低风险的最佳实践

请实施以下部分中所述的控制措施,以帮助降低 gcloud CLI 令牌被破解的风险。如果您遵循了企业基础蓝图Google Cloud 中的着陆区设计所述的安全方面的最佳实践,则您可能已经实施了这些控制措施。

设置 Google Cloud 服务的会话时长

如需减少攻击者利用已破解令牌的时间,请设置 Google Cloud 服务的会话时长。默认情况下,系统在身份验证后授予的刷新令牌为长期有效的凭据,而 gcloud CLI 会话从不需要重新进行身份验证。更改此设置以配置会话时长介于 1 到 24 小时之间的重新身份验证政策。在定义的会话时长之后,重新身份验证政策会使刷新令牌失效,并强制用户定期使用其密码或安全密钥重新验证 gcloud CLI 身份。

Google Cloud 服务的会话时长是一项与 Google 服务的会话时长不同的设置,后者控制在 Google Workspace 服务中登录的 Web 会话,但不控制对 Google Cloud 的重新身份验证。如果您使用 Google Workspace 服务,请同时设置两者的会话时长。

配置 VPC Service Controls

在您的环境中配置 VPC Service Controls,以便确保只有源于您定义的边界内的 Google Cloud API 流量才可以访问受支持的资源。服务边界限制了被破解的凭据的作用,因为边界会阻止源于环境之外的攻击者控制的端点的受限服务请求。

配置 BeyondCorp Enterprise

配置 BeyondCorp Enterprise 政策,以便保护 Google Cloud 控制台和 Google Cloud API。 配置 BeyondCorp Enterprise 访问权限级别和绑定,以选择性地允许在每个 API 请求上评估的属性,包括基于 IP 地址的访问权限或针对双向 TLS 的基于证书的访问权限。使用被破解的授权凭据但不符合 BeyondCorp Enterprise 政策中定义的条件的请求会被拒绝。

BeyondCorp Enterprise 是以用户为中心的控制机制,可拒绝不符合定义的条件的用户 API 流量。VPC Service Controls 是以资源为中心的控制机制,定义了资源可在其中进行通信的边界。VPC Service Controls 适用于所有用户身份和服务账号身份,但 BeyondCorp Enterprise 仅适用于您的组织内的用户身份。结合使用 BeyondCorp Enterprise 和 VPC Service Controls时,会降低环境之外的攻击者控制的机器上被破解凭据的有效性。

强制执行两步验证以进行远程服务器访问

如果您允许开发者使用 SSH 访问 Compute Engine 资源,请配置 OS Login 及两步验证。这会强制执行一个额外的检查点,用户必须使用密码或安全密钥重新验证身份。此功能可以能阻止只有被破解的 OAuth 令牌但没有任何密码或安全密钥的攻击者。

使用远程桌面协议 (RDP) 访问 Compute Engine 上的 Windows 实例不支持 OS Login 服务,因此无法对 RDP 会话精细执行两步验证。使用 IAP 桌面或基于 Google Chrome 的 RDP 插件时,请为用户的 Web 会话设置粗粒度控制机制(例如 Google 服务的会话时长两步验证设置),并在两步验证下停用允许用户信任设备设置。

限制服务账号密钥的使用

使用服务账号密钥进行身份验证时,密钥值与下载的密钥文件分开存储在 gcloud CLI 配置文件中。有权访问您的环境的攻击者可能会从 gcloud CLI 配置中复制密钥,或者从本地文件系统或内部代码库中复制密钥文件。因此,除了减少访问令牌被破解的方案之外,请考虑如何管理下载的服务账号密钥文件。

查看更安全的身份验证替代方案,以减少或消除依赖于服务账号密钥的应用场景,并强制执行组织政策限制条件 iam.disableServiceAccountKeyCreation 以停用服务账号密钥创建功能。

考虑最小权限原则

设计 IAM 政策时,请考虑最小权限。在最小范围内向用户授予完成任务所需的角色。请勿授予他们不需要的角色。查看并应用角色建议,以避免您的环境中具有未使用和过多角色的 IAM 政策。

保护您的端点

考虑攻击者如何获得端点(例如开发者工作站或 Compute Engine 实例)的物理访问权限或远程访问权限。虽然解决被破解的 OAuth 令牌威胁的方案非常重要,但首先还要考虑如何应对攻击者破解可信端点的威胁。如果攻击者有权访问可信端点,则可以直接在端点本身上运行 gcloud CLI 命令或其他代码。

虽然对开发者工作站的全面保护不在本文档的介绍范围内,但请评估您的安全工具与运营如何帮助保护端点以及监控端点是否被破解。请考虑以下问题:

  • 如何保护开发者工作站的物理安全性?
  • 如何识别和应对网络入侵?
  • 用户如何获取对 SSH 或 RDP 会话的远程访问权限?
  • 其他永久性凭据(如 SSH 密钥或服务账号密钥)如何遭到破解?
  • 是否存在使用可能被短期有效凭据替换的永久性凭据的工作流?
  • 是否存在有人在其中可能读取其他用户的缓存 gcloud CLI 凭据的共享设备?
  • 用户是否可以通过非可信设备使用 gcloud CLI 进行身份验证?
  • 已批准的流量如何连接到 VPC Service Control 边界内的资源?

确保您的安全运维能够解决上述每个问题。

使响应团队保持一致

提前确保负责突发事件响应的安全团队在 Google Cloud 控制台和管理控制台中拥有适当的访问权限。如果单独的团队负责管理 Google Cloud 控制台和管理控制台,则突发事件期间响应可能会延迟。

如需从被盗用的用户账号中移除访问权限,您的突发事件响应团队需要 Admin Console 角色,例如 User Management Admin。为了评估您的 Google Cloud 资源中是否发生了可疑活动,该团队还需要具有相应的 IAM 角色,例如跨所有项目的 Security Reviewer 或针对集中式日志接收器的 Logs Viewer。安全团队的必要角色因环境设计和运营而异。

安全事件发生后进行补救的最佳实践

在端点被破解后,作为事件管理方案的一部分,确定如何响应被破解端点的主要威胁以及如何缓解可能持续的损害被破解的令牌的次要威胁。如果攻击者拥有对开发者工作站的持久性访问权限,则在合法用户重新进行身份验证后,他们可能会再次复制令牌。如果您怀疑 gcloud CLI 令牌可能被盗用,请通过 Cloud Customer Care 开立工单,并完成以下各部分中的建议。这些操作有助于限制此类事件在 Google Cloud 组织中的影响。

本部分中的建议与有关处理被破解的 Google Cloud 凭据的一般指导信息重叠,但主要侧重于从被破解的端点复制的 gcloud CLI 令牌的威胁。

使用 Google Cloud 会话控制使所有用户账号的活跃令牌过期

如果您尚未强制执行 Google Cloud 会话控制,请立即以短暂的重新身份验证频率启用它。此控制有助于确保所有刷新令牌都会在您定义的时长结束时到期,从而限制攻击者可以使用被破解的令牌的时长。

手动使被破解的用户账号的令牌失效

查看有关为可能遭破解的任何用户身份处理被破解的凭据的指导信息。具体来说,移除 gcloud CLI 凭据是安全团队为用户身份处理被破解的 OAuth 令牌的最有效方法。如需立即使 gcloud CLI 的刷新令牌和访问令牌失效,并强制用户使用其密码或安全密钥重新进行身份验证,请从用户的已关联应用列表中移除 gcloud CLI。

单个用户也可以针对其个人账号移除 gcloud CLI 凭据

其他方法(例如暂停用户、重置用户密码或重置登录 Cookie)不会明确解决被破解的 OAuth 令牌的威胁。这些方法通常适用于突发事件响应,但不会使攻击者已控制的访问令牌失效。例如,如果您选择在调查期间暂停用户,但未撤消 gcloud CLI 令牌,则当已暂停的用户在访问令牌到期之前恢复时,访问令牌可能仍然有效。

以编程方式使许多用户账号的令牌失效

如果您怀疑遭到入侵,但无法确定哪些用户受到影响,请考虑更快地为组织中的所有用户撤消活跃会话(相较于重新身份验证政策所允许的)。

此方法可能会给合法用户带来干扰,并终止依赖于用户凭据的长时间运行的进程。如果您选择采用此方法,请为安全运营中心 (SOC) 准备一个编写了脚本的解决方案,以便提前运行并在少量用户中进行测试。

以下示例代码使用 Workspace Admin SDK 来标识 Google Workspace 或 Cloud Identity 账号中有权访问 gcloud CLI 的所有用户身份。如果用户已授权 gcloud CLI,则脚本会撤消刷新令牌和访问令牌,并强制他们使用密码或安全密钥重新验证身份。如需了解如何启用 Admin SDK API 并运行此代码,请参阅 Google Apps 脚本快速入门

/**
 * Remove access to the Google Cloud CLI for all users in an organization
 * @see https://developers.google.com/admin-sdk/directory/reference/rest/v1/tokens
 * @see https://developers.google.com/admin-sdk/directory/reference/rest/v1/users
 * @see https://developers.google.com/apps-script/guides/services/advanced#enabling_advanced_services
 */

function listUsersAndInvalidate() {
  const users = AdminDirectory.Users.list({
    customer: 'my_customer' // alias to represent your account's customerId
    }).users;
  if (!users || users.length === 0) {
    Logger.log('No users found.');
    return;
  }
  for (const user of users){
    let tokens = AdminDirectory.Tokens.list(user.primaryEmail).items
    if (!tokens || tokens.length === 0) {
      continue;
    }
    for (const token of tokens) {
      if (token.clientId === "32555940559.apps.googleusercontent.com") {
        AdminDirectory.Tokens.remove(user.primaryEmail, token.clientId)
        Logger.log('Invalidated the tokens granted to gcloud for user %s', user.primaryEmail)
      }
    }
  }
}

使服务账号的凭据失效并轮替

与授予用户身份的访问令牌不同,授予服务账号的访问令牌不能通过管理控制台或 gcloud auth revoke 命令等失效此外,您在 Google Cloud 会话控制中指定的会话时长适用于 Cloud Identity 或 Google Workspace 目录中的用户账号,但不适用于服务账号。因此,针对被盗用的服务账号的突发事件响应需要同时处理永久性密钥文件和短期访问令牌。

如果您怀疑服务账号的凭据遭到破解,请停用该服务账号删除服务账号密钥(如果存在),然后 60 分钟后启用该服务账号。删除服务账号密钥可能会使长期有效的凭据失效,这样攻击者就无法请求新的访问令牌,但不会使已授予的访问令牌失效。为了确保访问令牌在 60 分钟内不会被滥用,您必须将服务账号停用 60 分钟。

或者,您也可以删除和替换服务账号,以立即撤消所有短期和长期有效的凭据,但这可能需要进行更多中断性工作才能替换应用中的服务账号。

后续步骤