- 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¶ms[appTabUrl]=javascript:alert(1);¶ms[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¶ms[appTabUrl]=javascript:alert(1);¶ms[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修复漏洞
参考来源: