from:http://l0.cm/xxn/
這又是一篇來自全職賞金獵人Masato kinugawa的神作。一次雙殺,用一篇報告拿下了兩個CVE,分別是CVE-2015-6144和CVE-2015-6176。報告內容指出IE的XSS Filter在對XSS攻擊進行屏蔽時,由于正則的匹配不當在一些場景下會讓本不存在XSS漏洞的頁面產生XSS漏洞的問題。
Internet Explorer自IE8開始也就是2009年左右的時候首次導入了XSS Filter這一機制。不得不說,XSS Filter讓很多安全研究者頭疼。因為有時候你還真的就繞不過去。這會讓我們產生興趣說XSS Filter到底是怎么去阻擋xss攻擊的。說簡單也簡單,IE會去比對用戶的request和response如果IE認為有害的內容同時出現在了request和response當中,IE就會選擇屏蔽掉response中部分xss關鍵字。(根據情況有時候會屏蔽整個response body)舉個例子,如果你用IE像example.com發送如下的請求:
#!html
http://example.com/?q=<img src=x onerror=alert(1)>
那么你看到的response body就會是這樣:
#!html
q param is : <img src=x #error=alert(1)>
onerror變成#nerror后這段html確實沒有辦法執行JavaScript也就談不上什么XSS攻擊。看似非常合理,其實設計上存在非常的大的問題。問題的核心在于IE不會去管response body中出現與request相匹配的內容是原始的response內容還是攻擊者發送請求后所增加的內容。可能說的有點繞口,所以我得再舉個例子。假設你像example.com發送如下的請求:
#!html
http://example.com/?q=AAA&<meta charset=
即便你沒有任何參數(不難想到不看參數是在防范HPP攻擊)它也會毅然決然地把原始的meta tag給屏蔽掉。所以response body會變成這樣:
#!php
<m#ta charset=“utf-8”>
一次完美的誤殺。這也是這兩個CVE所利用到的IE的特性之一。居然說到了之一,就肯定有之二。之二是什么呢?之二就是負責防守不同場景下的XSS的正則在特定情況下,產生了交集。所以在這里我得再再舉個例子來說明這個問題。在IE負責虐殺XSS的mshtml.dll當中有這么一段正則:
#!bash
[ /+\t\"\'`]style[ /+\t]*? =.*?([:=]|(&[#()\[\].]x?0*((58)|(3A)| (61)|(3D));?)).*?([(\\]|(&[#()\[\].]x? 0*((40)|(28)|(92)|(5C));?))
這個正則是用來防誰的呢?就是下面這段xss攻擊:
#!php
<p style="x:expression(alert(1))">
這里的[ /+\t]*?
會匹配style
和=
之間出現多余0的空白字符(0x09-0x0D
,0x20
,/
,+
)。看似沒有問題,然而研究者再次發現url中出現的“+”
可以被任意的[0-6]byte
的html內容所匹配。
也就是說當我們對下面的頁面發送類似這樣的請求URL:?/style++++++=++=\
時
#!html
<style> body{background:gold} </style>
</head>
<body>
<input name="q" value="">
由于URL中的”+”可以被看作是任意的[0-6]byte
的html內容,所以從style結束到第一個等號開始的31 bytes內容會被[ /+\t]*?
匹配上。瀏覽器認為這是一次類<p style="x:expression(alert(1))">
攻擊,毫不猶豫的把style
替換成st#le
,response body再一次變成:
#!html
<style> body{background:gold} </st#le>
</head>
<body>
<input name="q" value="">
又一次的誤殺。伴隨著誤殺xss注入點也瞬間從html attribute content變成css content。這時我們便可以發送請求?q=%0A{}* {x:expression(alert(1))}&/style++++++=++=\
來對本不存在xss漏洞的頁面進行xss攻擊。
類似的誤殺還有:
[\"\'][ ]* (([^a-z0-9~_:\'\" ])|(in)) .+?[.].+?=
這段原來是為了防止script content中被注入類似location.href=xxoo
的內容時會產生xss的問題。不料卻又匹配到了其它的內容。
請求:
URL:?"/++.+++=
被IE篡改過后的響應:
#!html
<script src="http://example.co#jp/test.js" type="text/javascript">
</script>
原本該從example.co.jp/test.jp
讀取的內容代碼,卻又跑去讀example.co去了。這也就意味著針對于特定的域名和特定的目標攻擊者是只需要注冊example.co然后誘導用戶去訪問自己構造的example.com/?”/++.+++=
就能實現xss攻擊。
URL里沒有xss攻擊的跡象,頁面不存在XSS漏洞,并沒有xss注入點,然而這是一次xss攻擊。
同一個正則還有可能在這樣的場景下出現問題:
一旦內容被匹配../1.css
就會變成#./1.css
也就意味著當前頁面會被當作css被加載。構造類似第一個xss vector的攻擊向量,我們就可以再一次對不存在xss漏洞的頁面進行xss攻擊:
這也就是我們所說的其二,正則存在交集的問題。
facebook和google選擇關閉x-xss-protection
或者使用1;mode=block
來解決這種不可預期的問題。