作者:
mramydnei
·
2015/12/21 10:11
from:http://l0.cm/xxn/
0x00 前言
這又是一篇來自全職賞金獵人Masato kinugawa的神作。一次雙殺,用一篇報告拿下了兩個CVE,分別是CVE-2015-6144和CVE-2015-6176。報告內容指出IE的XSS Filter在對XSS攻擊進行遮蔽時,由於正則的匹配不當在一些場景下會讓本不存在XSS漏洞的頁面產生XSS漏洞的問題。
0x01 IE的XSS Filter
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="//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攻擊:
這也就是我們所說的其二,正則存在交集的問題。
0x02 關於修復
facebook和google選擇關閉x-xss-protection
或者使用1;mode=block
來解決這種不可預期的問題。
本文章來源於烏雲知識庫,此映象為了方便大家學習研究,文章版權歸烏雲知識庫!