这篇文章是关于我和Sreeram在 2022 年期间在 Google Cloud 中发现的错误的一系列文章中的第一篇。
在 Drive 等常见 Google 应用程序中不断寻找错误后,我们想冒险进入 Google Cloud。这是我们在平台中发现的第一个错误,它对受害用户的 Compute Engine 实例中的单击 RCE 产生了影响。
由于这是我们进入 Google Cloud 的第一步,我们很自然地偶然发现了最受欢迎的产品之一,Compute Engine。在探索其功能及其工作原理时,我注意到“浏览器中的 SSH”。这是 GCP 中的一项功能,允许用户通过浏览器通过 SSH 访问他们的计算实例。从视觉上看,这个界面看起来与 Cloud Shell 非常相似。
SSH 浏览器控制台
我正在查看 SSH-in-browser 的不同功能和选项。引起我注意的一项功能是“更改 Linux 用户名” 。
获取用户输入的用户名
此对话框从用户那里获取输入用户名,然后通过 GET 参数将其传递到服务器newLinuxUsername。即使给定的用户名不存在,它也会使用提供的用户名创建一个新用户并以该用户身份登录。
https://ssh.cloud.google.com/v2/ssh/projects/{PROJECT-NAME}/zones/{INSTANCE-ZONE}/instances/{INSTANCE-NAME}?newLinuxUsername={USERNAME}
由于没有随机令牌或 CSRF 保护,任何人都可以制作一个链接并将其发送给 Compute Engine 用户以在他们的实例中创建一个新用户。没有那么有影响力,但需要注意一些事情。但有趣的是,至少在表面上,它看起来只是在接受用户输入并将其传递给useradd或adduser命令。那么,命令注入?
我尝试添加诸如`whoami`,之类的有效载荷$(whoami),以查看它是否被执行。然而,什么也没有发生。为了检查二阶命令的执行,我尝试`curl https://stazot.com`了作为有效载荷。再一次,什么也没发生。我返回到 Compute Engine 实例页面并开始寻找其他内容。
我注意到在“SSH 密钥”部分下,列出了我尝试用作有效负载的用户名。此部分包含实例的所有用户及其各自添加/生成的 SSH 密钥的列表。虽然按原样`whoami`显示有效载荷,但curl有效载荷以一种奇怪的方式列出。
实例的 SSH 密钥
包含的用户名字段`curl http和包含的 SSH 密钥字段stazot.com`:ssh-key-value。瞬间,钟声开始在我脑海中响起。
服务器使用冒号:作为分隔符。之前的任何内容:都被视为用户名,之后的所有内容都:被视为该用户的 SSH 密钥。理论上,这应该允许攻击者注入用户名和他们的公共 SSH 密钥。这是可能的,因为如前所述,服务器在 GET 请求中获取此输入并且没有 CSRF 保护。
因此,让受害者打开恶意链接会将攻击者的用户名和 SSH 密钥添加到他们的计算实例中。为了确认错误,我构建了以下 URLattacker:{URL-ENCODED-SSH-PUBLIC-KEY}作为有效负载:
https://ssh.cloud.google.com/v2/ssh/projects/{PROJECT-NAME}/zones/{INSTANCE-ZONE}/instances/{INSTANCE-NAME}?newLinuxUsername=attacker:{URL-ENCODED-SSH-PUBLIC-KEY}
以受害者身份打开链接 - 我尝试以攻击者身份登录计算实例。但是,它没有用。原因是我添加的 SSH 密钥随后附加了 Google 在后端生成的 SSH 密钥。为了解决这个问题,我在负载中附加了换行符:
https://ssh.cloud.google.com/v2/ssh/projects/{PROJECT-NAME}/zones/{INSTANCE-ZONE}/instances/{INSTANCE-NAME}?newLinuxUsername=attacker:{URL-ENCODED-SSH-PUBLIC-KEY}%0d%0a
一旦这个受害者打开这个链接,我就尝试以攻击者的身份登录到那个实例——而且成功了!我以sudo权限登录到目标机器。
为什么会出现这个错误?
此行为的存在是为了通过浏览器中的 SSH 功能促进授权。由于浏览器就像一个 SSH 客户端,它需要一个授权的 SSH 密钥才能登录到实例。
Compute Engine 通过为实例中的每个用户(使用 SSH-in-browser)创建 SSH 密钥并将其存储在实例元数据中来处理此问题。当用户使用 SSH-in-browser 登录时,实例从元数据服务器获取所有授权的 SSH 密钥并登录用户。
这是一个非常复杂的过程,这里https://gitlab.com/gitlab-com/gl-security/threatmanagement/redteam/redteam-public/red-team-tech-notes/-/tree/master/oslogin-privesc-june-2020#how-os-login-works将对其进行详细说明。
披露
我们收到了 5000 美元的赏金和 1000 美元的奖金,用于向 Google VRP 报告此错误。
时间线
Jul 14, 2022 - Reported
Jul 15, 2022 - Closed as Intended Behavior
Jul 15, 2022 - Further explanation was sent
Jul 16, 2022 - Unable to reproduce
Jul 16, 2022 - PoC video was sent
Jul 23, 2022 - 🎉 Nice catch!
Jul 26, 2022 - Rewarded a $6000 bounty