价值3w美元的Google Cloud SSRF

admin 2025年1月6日12:00:35评论3 views字数 2438阅读8分7秒阅读模式

https://nechudav.blogspot.com/2020/11/31k-ssrf-in-google-cloud-monitoring.html

Google Cloud Monitoring 

Google Cloud Monitoring(以前称为Stackdriver)是一项服务,它为云资源(虚拟机实例、应用引擎、云功能......)提供监控。它可以从Google Cloud控制台获得。这项服务提供监控、警报、云资源的正常运行时间检查等等。值得注意的是,Google Cloud监控服务本身是在Google Cloud虚拟机上运行。

Google Cloud中的每个虚拟机都在元数据服务器上存储其元数据。这些元数据包括项目ID、服务账户信息、虚拟机的信息或公共ssh密钥。元数据可能从实例内部(从IP地址169.254.169.254)或来自计算引擎API。

Google Cloud监控提供的服务之一是正常运行时间检查。正常运行时间检查是一项服务,它定期向一个资源发送请求,看它是否有反应。检查可以用来确定应用引擎、虚拟机实例、URL等的可用性。

我开始通过创建一个正常运行时间检查功能来测试SSRF的这个功能,它向一个URL/IP地址发送请求。大多数的URL和IP地址,也就是通常的SSRF目标都被阻止了。但是,由于云监控本身是在Google Cloud虚拟机实例上运行的,我有可能尝试请求元数据API,因为对元数据API本身的请求将从实例中发出。

值得注意的是,当从虚拟机内部查询元数据时,需要包括头 "Metadata-Flavor: Google"(旧版本的元数据API不需要这个标头)。有一个选项可以在请求中添加自定义头信息。

我用以下参数创建了正常运行时间检查。

Protocol: HTTPHostname: 169.254.169.254Path: /computeMetadata/v1/project/project-idCustom Headers: Metadata-Flavor: Google (required for /v1/ metadata endpoints)

价值3w美元的Google Cloud SSRF

然后我按下了正常运行时间检查创建表格底部的测试按钮,它向元数据服务器发送了一个请求,然后显示检查成功了。

我看到的响应是。

价值3w美元的Google Cloud SSRF

因为响应代码是200,响应时间是2毫秒,我确信通过正常运行时间检查,元数据API是可以到达的(请求外部URL会花费更多时间)。问题是,无法看到响应的内容。只有两样东西被返回,那就是响应代码和响应时间。所以这里是一个盲SSR

用SSRF获取信息

为了获得响应体,我使用了另一个正常运行时间检查功能--响应验证。响应验证是一个检查响应体是否包含特定字符串的功能。在下面的图片中可以看到配置的例子。

价值3w美元的Google Cloud SSRF

我使用的方法如下 - 我开始寻找响应中包含的一个字符。我通过逐步测试响应是否包含所有可能的字符之一来实现这一目标。然后在找到一个字符后,我试图通过在已经找到的字符上添加或预置字符来寻找第二个字符,并再次尝试是否包含在响应中。这个过程将重复进行,直到从元数据服务器解析出完整的响应。

例如,我将尝试响应是否包含字符'a'、'b'、'c'...... 比方说,我发现响应中包含'c'。然后我将继续尝试预置或附加另一个字符,并试图找到响应是否包含字符'ca'、'cb'、'cc'...... 然后,如果我发现响应中返回了'ca',我将尝试其他组合--'caa'、'cab'、'cac'......并重复这一过程,直到我得到响应。

为了进行响应体的验证,按下正常运行时间检查表中的测试按钮时,即可调用该API

这个请求看起来像这样。

价值3w美元的Google Cloud SSRF
我创建了一个简单的Python脚本,它使用所述方法自动解析响应。该脚本可在此获得(https://gist.github.com/nechudav/0b2e0217ffe31a3cd1c1743c590595e6)

通过这个脚本,我获得了项目级元数据--公共SSH密钥、项目名称和其他关于谷歌云监控项目的信息。也可以得到实例级的元数据,这些元数据对所有实例都是一样的(机器类型、CPU平台......)。但我在获取实例级元数据时遇到了困难,这些元数据对每个实例或定期刷新的数据都是唯一的(例如服务账户令牌、实例的IP地址)。这是因为正常运行时间检查服务是在世界各地的多个实例上运行的(大约有54个运行的实例),对服务的请求是负载平衡的。所以不能保证多个请求会被发送到同一个实例上。获得独特的实例级元数据将需要发送大量的请求,这是有问题的,因为API是有速率限制的,这将是非常耗时的。在这一点上,我没有继续进行研究。

我报告了这个问题,它被接受了,谷歌VRP为这个错误奖励了我31337美元。我想感谢谷歌VRP团队的奖励和快速反应。

报告的时间。2020年6月

更新:谷歌工程师找到了一个非常好的、聪明的方法,通过使用二进制搜索和regex减少请求的数量来获得访问令牌。下面是描述他们解决方案的评论。

评论:实际上,在与同样的限制作斗争后,我们最终写了一个漏洞来获取访问令牌。两个主要的技巧是对每个字符进行二进制搜索(发送更少的请求)和探测正负匹配(获得可靠的结果)。比如说。

  • foo[a-n]
  • foo[^a-n]

当我们碰到正确的API时,这些请求中最终肯定会有一个成功的响应返回。我们会重复查询(达到一定的限度),直到我们得到任何成功的响应,然后在此基础上调整搜索空间。由于有了regexps,你可以并行地探测多个字符(foo[a-n], foo. [a-n], foo...[a-n])。在开始时令牌会重叠,但在~10个字符左右后,我们通常有一个独特的前缀。访问令牌的有效期为60分钟,所以平均来说你有30分钟。最后,这个漏洞花了~15分钟来获得一个完整的访问令牌,包括速率限制。有趣的错误。:)

 

原文始发于微信公众号(火线Zone):价值3w美元的Google Cloud SSRF

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年1月6日12:00:35
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   价值3w美元的Google Cloud SSRFhttp://cn-sec.com/archives/1217182.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息