Web、HTML、CSS、各家瀏覽器,都在持續演進著,以資安的觀點來看,演進的過程中包含了許多為了修補當初不安全設計而做得努力。IE,現在已經到IE 8了。
本文續「誰在看我的噗?第一回:DOM沙盒 vs 跨網站腳本漏洞(XSS)」。
許多朋友透過email/msn/plurk問我,這個攻擊為何說IE<=7才能觸發?其實這個問題不是三言兩語解釋得清楚,所以我只在文中寫IE<=7,不想讓已經很長的一篇變得更長,但沒想到大家都很厲害,這個問題大家都還是問了。那我們就來談談,為何此攻擊IE<=7才能work吧!
其實我只確定IE 7可以work,IE 8不行,IE 1-6,我沒裝,沒測過。可是為何我沒說IE 8可以,而又為何有朋友認為應該可以?認為可以的朋友們最大的「證據」之一,就是Plurk個人首頁的HTML中有一行:
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
由於CSS、HTML的規格不斷演進,各家瀏覽器也一直在變,一個網頁如何被解譯,跟瀏覽器決定用何種模式來解譯有很大的關係。HTML 5規格中即定義了三個模式:no quirks mode(標準模式,standard mode)、quirks mode(相容模式)、以及limited quirks mode(限制相容模式 / 近標準模式,almost standards mode)。不同模式影響了瀏覽器如何解析(parse)以及展現一份HTML文件;就資安的角度而言,不同模式的影響甚大,例如文件中對於script的處理,就會因不同模式而有差異。
就瀏覽器來說,不同模式間行為差距最大的,應該算是IE,又以IE 7到IE 8為明顯。IE 8一共支援了四種模式:IE 8 standard(標準)模式、IE 8 almost standards(近標準)模式、IE 7 standard(標準)模式、IE 5.5 quirks(相容)模式。「誰在看我的噗?」中所用的攻擊點:
body {background-image: expression(alert("XSS"));}
即是自從IE 8 beta 2之後,已經自IE 8標準模式中移除了;意思就是,如果是在IE 8標準模式下,此攻擊點無效,expression並不會被執行。那麼IE 8如何決定何時用哪種模式來執行呢?答案是根據許多條件,其中包含了HTTP檔頭、doctype、meta X-UA-Compatible、微軟的網站黑名單、以即使用者的設定等。那滲透測試的過程中,如何得知IE選擇哪種模式來處理一個網頁呢?最簡單的方式,是安裝IE Developer Toolbar。這個跟firebug互別苗頭的工具,一直是滲透測試時的好幫手。IE Developer Toolbar可以顯示出IE使用哪種模式來解譯目前的網頁。以Plurk為例,我的Toolbar顯示如下:
為何Plurk是在IE 8標準模式執行呢?我們看一下程式碼:
Server: nginx/0.6.32
Date: Sun, 28 Jun 2009 18:49:38 GMT
Content-Type: text/html; charset=utf-8
Connection: keep-alive
Expires: Sun, 28 Jun 2009 18:49:37 GMT
Cache-Control: no-cache
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 36704
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<script type="text/javascript">
if(window != top && window.location.toString().indexOf("/_comet/") == -1) {
//Inside an iframe
top.location.href = location.href;
}
</script>
<title>
armorize_wayne
</title>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
<meta name="verify-v1" content="iBRwaQ/3d4NoF1uaa2SAfCJ962ORry1TE8/4XxtIbHk=" />
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
恩,既然有定義doctype,也有用meta定義了X-UA-Compatible為「IE=EmulateIE7」,那應該要迫使IE 8在「IE 7標準模式」下解譯Plurk,為何toolbar還是顯示「IE 8標準模式」,而且攻擊也確實無法執行?始作俑者就是meta前面的javascript。如果沒有這段javascript的話,那IE 8就會轉換至「IE 7標準模式」下執行,而上述攻擊就仍然有效。當場try看看好了。利用fiddler,然後用IE 8開plurk,用羔羊帳號(goat_victim)登入,然後瀏覽我的Plurk頁面,可以看出瀏覽器發出以下的http request,其中並沒有對553lab.org發出request,表示攻擊並未成功:
這時我們利用「bpu http://www.plurk.com/armorize_wayne」設好中斷點(breakpoint,見上圖底黑底緑字處),然後IE 8按F5重新載入,中斷點停下來後,選擇「Break on Response」,然後等到獲得plurk伺服器回應的http response時,中斷點又再度停下來,這時我們手動改此HTML,將javascript移到「X-UA-Compatible」這行之後,並選擇「Run to Completion」:
下圖為執行後的畫面,我們看到IE 8發了一個request給http://553lab.org,表示我們的XSS(跨網站腳本漏洞)成功了,javascript被執行了:
回到IE 8,可以看到我的Plurk頁面上,機器人已經自動對來訪者(goat_victim)打招呼了:
那麼IE 8決定解譯模式的流程為何?以下流程圖來自:http://hsivonen.iki.fi/doctype/ie8-mode.png
圖中紅色部分為這次我的IE 8決定採用「IE 8標準模式」的流程圖。IE 8的決定,除了噗浪網站的HTTP檔頭與HTML內容外,我本身的IE 8 相容性設定也有影響。我的相容性設定為預設值(Tools->Compatibility View Settings):
其中的決定包含:
1. 是否有X-UA-Compatible meta標籤:事實:有,但是前面已經先有javascript。
2. HTTP檔頭中是否有設X-UA-Compatible?事實:沒有
3. 我的IE 8相容性設定是否有勾選「display all websites」?事實:沒有
4. ...
有可能這是Plurk刻意的設計,讓IE 8在「IE 8標準模式」中執行,但也有可能是Plurk本意是要藉由設定X-UA-Compatible來讓IE 8切換至「IE 7標準模式」,可是後來在前面加了一段javascript,誤讓模式跳回了「IE 8標準模式」,也同時讓我們的攻擊失效了。
無論如何,Plurk讓IE 8在「IE 8標準模式」中執行,導致我們前一篇中所提之攻擊點失效,也是為何前一篇中,我沒有說攻擊能在IE 8上執行之原因。至於有朋友問,明明CSS中的expression,有用IE 8測過,確定可以work,為何說不行?答案是這要看你的頁面讓你的IE 8呈現何種模式?如果在HTML內或HTTP檔頭中都沒有設定X-UA-Compatible,也沒有特別設定doctype的話,那就很有可能跑到相容模式去,而導致CSS expression攻擊成功了。
瀏覽器的解譯模式會直接影響javascript執行方式,進而影響資安結構;不但doctype、meta tag以及HTTP檔頭,甚至連javascript擺的位子之些微差距,都有可能影響一個網頁之安全性。您清楚您網站於IE各版本上的解譯模式嗎?
作者Wayne為阿碼科技一員
p.s.順便簡短一併回一些問題:
Q:這個漏洞可以用來寫蠕蟲嗎?答:可以
Q:噗浪修補好了嗎?答:「這個漏洞」修補好了,但是即使同一個手法,也可以有很多種變形,是否都阻擋了?我沒測
Q:之前提的csrf蠕蟲能公開嗎?答:噗浪還沒修好,所以還不能公開
系列第一篇:誰在看我的噗?第一回:DOM沙盒 vs 跨網站腳本漏洞(XSS)
系列第二篇:(本篇)誰在看我的噗?第二回:IE執行模式 vs 跨網站腳本漏洞(XSS)
系列第三篇:誰在看我的噗?第三回:弔詭的過濾函式
系列第四篇:誰在看我的噗?第四回:我噗誰在看!
繼續閱讀全文...