绕过Identity-Aware Proxy(身份感知代理) - Google Cloud 漏洞
原文链接:https://www.seblu.de/2021/12/iap-bypass.html
概述
我发现一种方式:攻击者如何从有权访问受 IAP 保护的 Web 应用程序(身份识别代理)的其他用户手中获取泄露令牌。这允许攻击者劫持会话,从而访问受 IAP 保护的 Web 应用程序。
要执行此类攻击,需要执行的步骤为:
当有权访问目标应用程序的用户访问攻击者受 IAP 保护的应用程序时,原始 OAuth 客户端的有效重定向令牌就会发送到攻击者(第二个)后端服务,攻击者可以在其中读取重定向令牌。
以此:攻击者可以使用此重定向令牌访问受 IAP 保护的目标 Web 应用程序。
Identity-Aware Proxy 简介
Identity-Aware Proxy (IAP) 是 Google Cloud Platform (GCP) 中的一个安全组件,可让您建立更精细的应用级访问控制模型,而不是简单地依赖网络级防火墙规则。
IAP 可用于保护 Web 应用程序(托管在 Compute Engine 虚拟机、App Engine 等上)。此外,通常可以通过 IAP建立 TCP 连接。
为了进一步解释我的方法、漏洞细节以及选择 IAP 作为目标的原因,我想更详细地解释这种 IAP 保护的 Web 应用程序的请求流程:
浅浅解释一下吧:
- 客户端尝试访问 Web 应用程序(例如https://my-secure-app.com/)。此请求发送到外部 HTTPS 负载均衡器。
- 负载均衡器将请求路由到配置的后端服务。但是,由于后端服务启用了 Identity Aware Proxy,请求被 IAP 拦截,并检查 cookie 中的有效授权令牌。
- 由于请求未包含有效令牌,IAP 将客户端重定向到 Google 登录以进行 OAuth (https://accounts.google.com/o/oauth2/v2/auth?client_id=${CLIENT_ID}...),使用为 Identity Aware 代理配置的 OAuth 客户端 ID。
- 身份验证成功后,客户端将重定向到 IAP API(https://iap.googleapis.com/v1/oauth/clientIds/${CLIENT_ID}:handleRedirect?...),将 OAuth 身份验证代码交换为重定向令牌。
- 现在客户端被重定向回初始 Web 应用程序,但包括额外的查询参数(例如 https://my-secure-app.com/? gcp-iap-mode=AUTHENTICATING&redirect_token=...),尤其是交换的重定向令牌。
- 负载均衡器再次将此请求转发给后端服务,但被 IAP 拦截。IAP 现在会注意到额外的查询参数并交换包含最终有效令牌的 Cookie(仅当经过身份验证的用户满足配置的授权要求时)。
- 最后,客户端被重定向到 Web 应用程序和最初请求的 URL(例如 https://my-secure-app.com/)。
- 负载均衡器将请求转发到后端服务,再次被 IAP 拦截。并检查 cookie 中的有效授权令牌。
- 由于令牌有效,请求通过 IAP 并到达后端服务,从而到达实际的 Web 应用程序。
这个详细的重定向和组件列表不仅是我进一步研究的关键,而且还说明了一些见解:
这些功能使 IAP 也成为寻找 bug 的绝佳目标。
漏洞利用思路总结
对于端到端的攻击场景,攻击者必须执行以下步骤才能访问受 IAP 保护的 Web 应用程序:
- 查找目标应用程序的 OAuth 客户端 ID(查看重定向参数)
- 创建一个自己的 GCP HTTPS 负载均衡器,其中 2 个后端服务指向同一个 Web 服务器(可能不同,但没有区别)
- 使用指向此负载均衡器的 DNS 记录创建一个不可疑的 URL。或者使用 nip.io 和/或 tinyurl.com之类的服务 来混淆它。
- 确保第一个后端服务使用目标 OAuth 客户端 ID 和随机客户端密钥启用了 IAP(使用 共享 OAuth 客户端)
- 确保将包含 ?gcp-iap-mode=AUTHENTICATING&redirect_token 的请求路由到第二个未启用 IAP 的后端服务(使用 基于查询参数的路由)
- 在后端服务器上确保请求被正确持久化,尤其是redirect_tokens。为了进一步隐藏攻击,在存储请求数据后重定向一个不可疑的网站也是有意义的。
- 最后,尝试将受害者(允许访问目标应用程序)引诱到准备好的攻击者 URL。想想常用的社会工程方法。一个入口点可以在尝试登录目标应用程序失败后显示在错误屏幕上的管理员电子邮件(对于受 IAP 保护的 Web 应用程序始终存在)。
- 一旦受害者单击 URL,就会快速连续发生一系列重定向。当浏览器使用目标应用程序中允许的 Google 帐户登录时,根本不需要用户交互。最后,重定向进程在不可疑的网站上结束。
- 在重定向期间,受害者的 redirect_token 已被攻击者的 Web 服务器捕获。攻击者可以使用它从目标应用程序中检索有效会话 cookie 并创建授权会话。
挖掘过程
确定潜在攻击场景
主要有 2 种类别的潜在攻击场景:
- 在没有有效凭据的情况下绕过 IAP
- 使用从其他用户泄露的有效凭据绕过 IAP
在经过无数次尝试后,第一种方式失败了,我便尝试第二种方法,并寻找潜在的攻击媒介来窃取授权用户的有效凭据。我花了一些时间才偶然发现 Identity-Aware Proxy 的“便利功能”: Sharing OAuth Clients 。
虽然默认情况下,每个受 IAP 保护的应用程序都会创建自己的 OAuth 客户端(由客户端 ID 和密码组成),但此功能允许通过将 OAuth 客户端重用于多个应用程序来减少创建的 OAuth 客户端的数量。
对我来说,这导致了观点的突然转变,并导致了绕过 IAP 的突破!
突破
这些是OAuth 客户端的客户端 ID 和客户端密码 。客户端 ID 很容易获得,因为它包含在尝试访问目标应用程序时初始重定向的查询参数中。但是,根本无法获取或猜测客户端密码,但还是决定尝试一下:
1. 首先,使用“受害者”Google 帐户和 GCP 项目创建了一个虚拟目标应用程序,该应用程序由一个简单的 nginx 网络服务器组成,该服务器运行在我添加到实例组的计算引擎 VM 上。
2. 然后我创建了一个 外部 HTTPS 负载均衡器,将实例组添加为新的后端服务并在后端服务上激活身份识别代理(自动创建的 OAuth 客户端 ID 为: 1016913171751-u4ncjlfs09ckr8bho0praksql8uj71u2.apps.googleusercontent.com)。
3. 我授予 “受害者”Google 帐户“IAP-secured Web App User”角色,因此使该帐户成为唯一允许访问目标应用程序的帐户。
4. 假设此应用程序可在 https://victim.app/ 下访问。
然后,使用另一个“攻击者”谷歌帐户和 GCP 项目和上述一样配置,只是最初跳过了 IAP 设置。 假设这个应用程序可以在 https://attacker.app/ 下访问。
然后,我使用受害者应用程序中的客户端 ID 继续并在后端服务上激活了 IAP 。由于“攻击者”不知道Client Secret,我便使用了一个随机且不正确的值(1234567890):
gcloud compute backend-services update my-attacker-backend --global --iap=enabled,oauth2-client-id=1016913171751-u4ncjlfs09ckr8bho0praksql8uj71u2.apps.googleusercontent.com,oauth2-client-secret=1234567890
即使密码不正确并且 OAuth 客户端甚至存在于完全不同的 GCP 组织中,该命令也成功了。
然后我尝试访问 https://attacker.app/ 并成功重定向到登录页面以及目标客户端 ID(https://accounts.google.com/o/oauth2/v2/auth?client_id=1016913171751 -u4ncjlfs09ckr8bho0praksql8uj71u2.apps.googleusercontent.com&... )
登录后,我被重定向 到 IAP API (https://iap.googleapis.com/v1/oauth/clientIds/1016913171751-u4ncjlfs09ckr8bho0praksql8uj71u2.apps.googleusercontent.com : handleRedirect ?...),然后返回 https:// /attacker.app/ 包含 redirect_token 参数。
但是,在这里我收到了IAP 错误代码: 错误代码 11 - 您的 OAuth 客户端 ID 配置不正确。所以这就是不正确的客户端密码导致问题的关键点。redirect_token 与客户端密码相关,我的攻击者 IAP 配置引发错误,因为 OAuth 流程未使用配置的客户端密码 (1234567890) 完成。
HTTPS 负载均衡器的一个或多或少的新特性是 基于查询参数的路由。使用这种方法,攻击者可以将有问题的请求(包含查询参数 gcp-iap-mode=AUTHENTICATING 和redirect_token)路由到另一个后端服务(显然没有激活 IAP,因此请求实际上会到达后端)。
因此,(作为攻击者)我创建了第二个后端服务,指向同一个实例组,但完全跳过了 IAP 配置部分。我修改了负载均衡器以使用以下URL 映射配置,利用基于查询参数的路由:
使用与受害者 Google 帐户的浏览器会话,我跳转到 https://attacker.app/ 并发生了典型的 IAP 重定向序列(accounts.google.com、 iap.googleapis.com 并返回到 https://attacker.app/ )。但是,由于额外的 URL Map 配置,最终重定向不再被 IAP 拦截。
如下图,解码的 redirect_token 在 target_uri 中包含 https://attacker.app: