请选择 进入手机版 | 继续访问电脑版
查看: 328|回复: 0

Google.org点击劫持DOM XSS

[复制链接]
  • TA的每日心情

    昨天 19:26
  • 签到天数: 745 天

    [LV.9]以坛为家II

    发表于 7 天前 | 显示全部楼层 |阅读模式
    谷歌有一个项目相信许多人可能都没听过,那就是谷歌危机地图(Google Crisis Map)。

    该项目旨在帮助人们可以快速的查找和使用一些关键的应急信息(来源)。

    虽然它目前仍在使用,但它似乎使用的人并不多。

    由于这是一个较老的项目(创建于2012年)且很长一段时间没有更新,因此可以说这是一个查找漏洞的绝佳目标。

    它被托管在google.org域,该域的严重程度虽不如google.com(针对客户端漏洞),但它仍然是Google所拥有的域名。

    登录
    如果你打开项目的主页(google.org/crisismap),你将被重定向到默认地图“天气和事件”。这对我们来说意义不大,因为我们唯一能做的就是查看地图。

    这里有一种可以管理和创建新地图的方法。如果我们在网址末尾添加.maps后缀,如:google.org/crisismap/.maps


    打开此页面后,你需要使用自己的Google帐户登录才能继续。现在,你应该能够看到一个带有地图列表的仪表板。每个帐户都有三个默认地图。

    出于某种原因,如果你在自己的域上发布其中的一个地图,则所有人都能在仪表板的“已发布地图”字段下看到该地图。

    创建地图

    如果单击红色的“Create Map”按钮,你会看到一条消息显示,gmail.com域不能用于创建新地图。

    这意味着我们需要使用包含我们自定义域的电子邮件进行登录。我们可以通过使用GSuite帐户,或使用gmail.com以外域的电子邮件登录来执行该操作。之后,我们就可以创建一个新地图了。

    单击“Continue”按钮后,我们将被重定向到我们可以编辑新创建地图的页面。

    查找 XSS
    首先,我们将向地图添加一个新图层。

    将会弹出用于创建新图层的弹框。

    输入任意内容作为“Title”。

    现在,如果我们在“Source URL”字段中输入javascript:alert(document.domain),它将显示一个错误:

    [AppleScript] 纯文本查看 复制代码
    Invalid URL – please include a protocol (e.g. http:// or https://)


    这意味着它会在允许你保存新图层之前检查URL是否有效。验证URL的反混淆javascript代码如下所示:

    [AppleScript] 纯文本查看 复制代码
    if (url && !url.toLowerCase().match("^\\s*(http://|https://|docs://|$)")) {
      showError("Invalid URL - please include a protocol (e.g. http:// or https://)");
    }

    但这只是在将实际保存请求发送到后端之前的客户端验证。

    修改请求
    我们可以使用像Fiddler或Burp Suite这样的Web调试代理,来修改请求并发送修改后的版本。

    首先,我们需要将“Source URL”更改为有效的URL,例如https://example.com

    我们单击“OK”按钮并单击“Save”以发送保存请求。然后我们将修改请求。请求如下:

    [AppleScript] 纯文本查看 复制代码
    POST [url]https://google.org/crisismap/.api/maps/1234[/url]

    [AppleScript] 纯文本查看 复制代码
    {
      "id": "1234",
      "title": "Untitled map",
      "base_map_type": "GOOGLE_ROADMAP",
      "layers": [{
        "id": "1",
        "title": "Test layer",
        "visibility": "DEFAULT_ON",
        "type": "KML",
        "source": {
          "kml": {
            "url": "https://example.com"
          }
        }
      }]
    }

    我们将用javascript:alert(document.domain)替换https://example.com,并发送修改后的请求。

    测试 XSS
    现在请求已发送并保存,因此让我们重新加载页面。

    打开“Layers”,然后单击“Download KML”。

    点击下载链接后,XSS将被触发,并弹出带有域的警告框!


    如何修复
    为什么会这样?URL验证仅发生在前端而不是后端。这意味着可以通过验证后端的URL来解决这个问题。

    但谷歌并没有这么做。而是在URL保存到后端时检查URL,显示在DOM中前URL已被验证。

    因此,如果URL无效,则不会将其用作链接,并将使用一个无意义的值,如:about:invalid代替。

    [AppleScript] 纯文本查看 复制代码
    <a href="about:invalid#zClosurez">Download KML</a>


    影响
    好的,现在我们有一个包含payload指向javascript: URI的链接。该链接位于用于管理地图的页面上。你必须登录才能获取该页面的访问权限。

    显然这是self-XSS,因为只有我们能够执行该XSS。

    现在,我们要做的就是如何将self-XSS变成真正的有影响的XSS?

    这样,任何人都可以打开此URL并查看我们创建的地图。想要使XSS正常工作,用户需要打开或导航到此页面,打开“Layers”并单击“Download KML”链接。

    这意味着它已不再是self-XSS,但缺点是这需要用户操作的步骤过多。

    点击劫持
    如果我们查看HTTP响应头,可以看到google.org并未发送X-Frame-Options标头。
    增加严重性
    我们创建的每张地图都可以发布供公众查看。如果你通过包含域example.com的电子邮件登录,则可以将地图发布到:http://google.org/crisismap/example.com/test


    X-Frame-Options HTTP 响应头是用来给浏览器指示允许一个页面可否在<frame>, <iframe>, <embed> 或者 <object> 中展现的标记。站点可以通过确保网站没有被嵌入到别人的站点里面,从而避免clickjacking攻击。

    google.org上缺少该标头,则意味着我们可以将已发布的地图嵌入到我们自己网站上的iframe中。
    [AppleScript] 纯文本查看 复制代码
    <iframe src="https://google.org/crisismap/example.com/test"></iframe>

    如下所示。用户现在甚至不需要离开我们的站点。但仍需要用户点击iframe中的两个位置(“layers”>“download kml”)。

    iframe在我们的网站上被加载 – 这意味着我们可以使用CSS和JavaScript来操作它。

    我想到的第一件事,就是将黑色的DIV放置在我们希望用户点击的位置。然后检测单击事件并将DIV移动到第二个点。

    这很有效,但仍需要用户点击两个不同的位置。

    但有个更好的方案就是绝对定位iframe,这样用户就不必移动光标了。

    以下演示我们将iframe缩放了50倍,并将其移动了到我们希望用户单击的位置。首先转到“Layers”选项卡。点击后,它会在带有payload的链路上移动。

    你可以通过在下面的iframe中单击两次来尝试该示例:


    总结
    不要相信用户输入。在使用它之前一定要验证/转义它,甚至在保存它之前最好检查它是否有效。

    通过正确设置X-Frame-Options标头,不允许其他域将你的网站嵌入iframe。

    在查找漏洞时,请尝试找到该漏洞可能的最高严重性。

    例如,如果你找到一个XSS,请尝试通过查找错误配置的Cookie或端点接管帐户。

    寻找仍然适合bug奖励计划范围的旧项目。我在谷歌危机地图上发现了另外两个漏洞,后续我也会发布有关它们的文章。

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?注册

    x
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    快速回复 返回顶部 返回列表