XSS編碼與繞過

 XSS編碼與繞過 javascript

0x00 背景

對於瞭解web安全的朋友來講,都知道XSS這種漏洞,其危害性不用強調了。通常對於該漏洞的防禦有兩個思路:一是過濾敏感字符,諸如【<,>,script,'】等,另外一種是對敏感字符進行html編碼,諸如php中的htmlspecialchars()函數。php

通常狀況,正確實施這兩種方案之一就能夠有效防護XSS漏洞了。但其實也會有一些場景,即便實施了這兩種方案,攻擊者也能夠繞過防禦,致使XSS漏洞被利用。html

0x01 繞過場景

下面主要是參考文章http://www.freebuf.com/articles/web/43285.htmljava

場景一:XSS注入點在某個html標籤屬性中,代碼片斷以下git

能夠看到,這裏防禦措施採用的是方案一:過濾敏感字符。那麼這裏若是輸入javascript:alert (11),是會被過濾掉的,輸出的內容會是:github

這固然不能彈框,常規的xss payload就會失敗了。如同參考文中所說的,這裏繞過方法有不少中,你徹底不須要使用 > 去閉合html標籤,也能夠用其餘關鍵字來代替javascript,不過既然說的是編碼問題,固然要用編碼問題來解決問題。web

這裏能夠對"javascript:alert(11)"進行html編碼來繞過,你能夠試試將html編碼後的payload傳遞給name參數,也就是:javascript%3Aalert%2811%29,能夠看到熟悉的窗口又彈出來了。緣由就是,瀏覽器在解析到這段代碼時,會對其先進行html解碼,而後當觸發onclick事件後,會調用js引擎對其進行js編碼後執行js代碼,因此就看到了彈窗。原文在這裏只提到了html編碼的方式,其實這裏還能夠對payload進行js編碼。可是要注意的是,這裏不能將整個payload進行編碼,你要像這樣:express

又能夠看見彈框了。(是否是略微有點看不懂啊,不要緊,接下來還有更繞的)瀏覽器

 

場景二:XSS注入點在js標籤中,代碼片斷:安全

這裏採用的防禦措施是第二套,使用php內置函數htmlspecialchars對敏感字符進行編碼。若是輸入正常的payload,如:<img src=1 onerror=alert(11)>,是不會有彈窗的,此時瀏覽器的輸出:

這裏的敏感字符< >,已經被html編碼了,最後在<div>標籤裏面輸出的時候瀏覽器再使用html解碼將其原文顯示出來,可是並不會再觸發js引擎了,因此也就沒有彈窗了,利用失敗。

這裏使用js編碼就能夠繞過了,由於瀏覽器是先js解碼而後再html解碼,經過js編碼後的payload在html解碼的時候已是正常的html了,就會觸發js引擎,彈框也就出來了。

試試js編碼後的payload:

 

看到這裏,你心中確定有疑問,瀏覽器究竟是怎麼解碼的,爲何一會先js解碼,一下子又是先html解碼?起初我在看到這裏時候也一直很納悶,原文裏面並無對瀏覽器爲何這樣解碼說明緣由,直到我看到這篇文章http://xuelinf.github.io/2016/05/18/編碼與解碼-瀏覽器作了什麼/。該做者從原理上對瀏覽器編碼解碼進行了說明,揭開了個人疑問,這篇文章也主要是說明該問題。

0x02 瀏覽器編碼解碼方式

來看看瀏覽器處理一次完整的http請求,會涉及到的編碼解碼問題。

  1. 當瀏覽器發送http請求時,會先對特殊字符進行URL編碼後,發送給服務器。
  2. 服務器收到客戶端發送來的http請求,會對其進行URL解碼後,再進行處理,處理完成後將結果返回給瀏覽器。
  3. 瀏覽器接收到html文件後,最早是觸發html解析器來解析html,將標籤轉化爲內容樹中的DOM節點,此時在識別標籤的時候,html解析器是不能識別哪些被html實體編碼了,只有當整個DOM樹創建起來後,才能對每一個節點的內容進行識別,若是有html實體編碼,再對其進行解碼。
  4. 在html解析器過程當中,遇到js標籤諸如<script>會調用js解釋器對js代碼進行解析,而js DOM API會對DOM結構進行更改,DOM樹節點的更改也會反過來觸發html解釋器。
  5. CSS解釋器也會在html解釋器過程當中參與進來,但它不會干擾到DOM樹,它會結合<style>標籤和CSS文件以及html指令來構建render tree。

以上,就是瀏覽器解析一次完整http請求所會涉及到的編碼解碼問題。瀏覽器在收到html文件後,若是沒有js DOM API的參與,那麼瀏覽器會按照html解碼àCSS解碼àjs解碼的順序解析下去,可是因爲js DOM API的存在,解碼順利會被打亂,因此有了上面兩個場景中不一樣的解碼順序,那麼到底爲什麼要按照這樣的解碼方式呢?再來具體看看js解釋器的處理流程。

當瀏覽器在處理諸如<script> <style>標籤,解釋器會自動切換到特殊解析模式,src href後邊加入的javascript爲URL,也會進入到JS解析模式。而進入該解析模式的時候,該DOM節點已經創建起來了,可是html解釋器還並未進行html解碼。當觸發js解釋器後,js會先對內容進行解析,若是有js編碼就會進行解碼操做,接下來是就是執行裏面的js語句。因此此時執行該js語言前的解碼順序爲js解碼-->html解碼。

來看看可以觸發js引擎的標籤:

  • 直接嵌入< script> 代碼塊。
  • 經過< script sr=… > 加載代碼。
  • 各類HTML CSS 參數支持JavaScript:URL 觸發調用。
  • CSS expression(…) 語法和某些瀏覽器的XBL 綁定。
  • 事件處理器(Event handlers),好比 onload, onerror, onclick等等。
  • 定時器,Timer(setTimeout, setInterval)
  • eval(…) 調用。

既然js DOM API能夠更改瀏覽器正常的解碼順序,那麼觸發js解釋器的方式有哪些呢?

瞭解了瀏覽器的編碼解碼以後,咱們再回頭看一下前面的兩個場景。

第一個場景中,js語句是在a標籤中,在onclick事件觸發js解釋器以前,DOM樹結構已經創建完成了,而且這裏也沒有DOM API操做,因此瀏覽器會先對該語句進行html解碼,而後再是js解碼,因此當咱們對payload進行html編碼後,在js解釋器解析該js語句時,其已經被html解碼了,是正常的js語句,因此可以正常彈窗。

場景二中,payload是在script標籤裏面,瀏覽器解析到這裏時,會觸發js解釋器,js解釋器會對該語句進行js解碼操做,咱們使用js編碼的payload被還原成正常的語句。雖然此時整個DOM樹已經創建起來了,可是因爲DOM API存在,會再一次的調用html解釋器,對咱們的payload進行解析,payload裏面有js標籤,再一次觸發js解釋器,完成對js語句調用,成功彈窗。

0x03 總結

能夠看到,由於瀏覽器豐富多樣的解碼方式,對於XSS的防護不能徹底單一依靠編碼和過濾操做,須要根據上下文對輸入語句,先進行相應的解碼以後再進行編碼和過濾操做,纔能有效的防護XSS。

 

by:會飛的貓

轉載請註明:http://www.cnblogs.com/flycat-2016

相關文章
相關標籤/搜索