XSS Attacks - Exploiting XSS Filter

wyzsk發表於2020-08-19
作者: 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攻擊。

p1

類似的誤殺還有:

[\"\'][ ]* (([^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攻擊。

p2

同一個正則還有可能在這樣的場景下出現問題:

p3

一旦內容被匹配../1.css就會變成#./1.css也就意味著當前頁面會被當作css被載入。構造類似第一個xss vector的攻擊向量,我們就可以再一次對不存在xss漏洞的頁面進行xss攻擊:

p4

這也就是我們所說的其二,正則存在交集的問題。

0x02 關於修復


facebook和google選擇關閉x-xss-protection或者使用1;mode=block來解決這種不可預期的問題。

本文章來源於烏雲知識庫,此映象為了方便大家學習研究,文章版權歸烏雲知識庫!