xss編碼繞過詳解(更像是在介紹實體編碼和JS編碼的解析過程)

xss編碼繞過詳解(更像是在介紹實體編碼和JS編碼的解析過程)

注:本文通過研究各種情況下實體編碼和JS編碼是否生效,進而總結了哪些情況下能夠進行編碼後,javascript代碼依然能夠正常執行。

解析順序是這樣的,URL 解析器,HTML 解析器, CSS 解析器,JS解析器

URL的解碼是在後臺服務檢測之前的,可以理解爲後臺收到URL後會自動進行解碼,
然後纔是執行開發人員編寫的對URL中的值的檢測函數,首先URL編碼作用不在於繞過後臺檢測,但是當我們是GET方式提交數據時,而我們提交的數據中進行了實體編碼,也就意味着存在&,#這樣的特殊字符,這時就需要對這些特殊字符進行URL編碼,這樣纔會保證正常解析,如果不進行URL編碼的話,就會把#認爲是空格了,而&也會是被認爲用來連接URL中參數的連接符,故需要進行URL編碼。如果是以POST方式傳遞值,就不需要進行URL編碼了。

着重談
實體編碼(HTML解析器)&#十進制; 或者&#x十六進制;
JS編碼(JS解析器) \u00十六進制

一、HTML解析(只要是DOM節點裏屬性的值,都可以被HTML編碼和解析)

瀏覽器接收到頁面數據,於是開始進行HTML 解析,構造DOM樹。HTML 的分析器只能識別特定的詞法規則,才能構建起DOM 樹,這一塊,HTML 不會做解碼的工作,因爲它做不了。
<img src%26%23x3d%3B"test"> (對=號進行了一次實體編碼後再進行了一次JS編碼)
因爲正確的語法是 src=value 只有這樣的時候,HTML解析器纔會認爲src是標籤img的一個屬性,而value是這個屬性的值。
舉例:(注意:以下列子都是以GET方式傳遞值,所以需要進行URL編碼)

http://192.168.149.143/xss/example1.php?name=

在這裏我們通過GET方式傳給name參數的值:
編碼前:

對字符串test先進行一次實體編碼,再進行一次JS編碼(進行JS編碼的原因已經在文章開頭講述過了)
於是就成了如下形式

進行訪問,查看結果:

在這裏插入圖片描述
我們審查元素(審查元素所看到的就是經過解碼後的結果)

在這裏插入圖片描述
查看網頁源碼:
可以看到src的值都是實體編碼,這也證實

在這裏插入圖片描述
這也證實URL解碼是在後臺服務器上做的,而不是在瀏覽器,然後瀏覽器構建完DOM樹後,進行了實體編碼解析,於是看到了我們審查元素時所看到的結果

如果我們對"test"(包括test兩邊的雙引號)進行一次實體編碼再進行一次JS編碼會怎麼樣
審查元素如下,發現多了一對雙引號

在這裏插入圖片描述查看網頁源代碼卻是正常的,並沒有多雙引號,雙引號的實體編碼是"

在這裏插入圖片描述
這裏應該是因爲瀏覽器存在一個自動糾錯的功能

在這裏插入圖片描述
現在我們對="test"這一部分進行一次實體編碼再進行一次JS編碼

沒有像正常那樣出現一個圖片訪問錯誤的圖標
審查元素,發現實體編碼都未進行解析

在這裏插入圖片描述
查看源碼

在這裏插入圖片描述
這裏就說明img的標籤是已經正常構成的,但是它的src屬性卻並沒有正常構成,因爲=號被編碼後,導致構造DOM樹時,屬性src不符合語法規則,無法被識別,所以src的值也無法進行實體編碼解析

如果對src進行上述編碼,經測試也無法進行實體編碼解析,在這就不在贅述

小結:所以如果想要能夠進行實體編碼解析,就必須不能破壞語法結構,比如不能對標籤名稱、<>=等具有語法結構的特殊字符進行實體編碼,可以對比如對標籤之間的文本進行實體編碼、對標籤的屬性的值進行實體編碼

二、JS解析器,只有進入JS解析環境,纔會進行JS編碼解析,並且位於JS解析環境的,不會進行實體編碼解析

測試:
編碼前:
http://192.168.149.143/xss/example1.php?name=
進行訪問,如果如下:

在這裏插入圖片描述
觸發了彈框,但是發現內容依然是實體編碼
說明了test並沒有進行實體編碼解析
查看源碼:

在這裏插入圖片描述
下面我們對test進行JS編碼(只能是unicode編碼,即\u00十六進制)
編碼前
http://192.168.149.143/xss/example1.php?name=
進行訪問,結果如下:
可以看到正常顯示爲了test,說明JS編碼被解析了

在這裏插入圖片描述

之間的就是JS解析環境

對alert進行JS編碼

在這裏插入圖片描述
結果能夠正常觸發彈框
筆者還作了如下嘗試
1、將alert(“test”);中的(進行JS編碼
結果無法觸發彈框
2、將alert(“test”);中的"進行JS編碼
結果無法觸發彈框
3、將alert(“test”);中的;進行JS編碼,事實上把這個;去掉一樣能觸發彈框
結果無法觸發彈框
可以發現對這幾個特殊字符進行JS編碼後,卻無法觸發彈框(這裏爲什麼無法觸發彈框,本人暫時也不太清楚,這裏到底是否進行JS編碼解析,也不太清楚)

因爲這裏的alert可以算作是之間的文本節點(文本節點這種說法可能不太準確,但是這裏因爲是JS解析環境只能進行JS編碼解析),就像是位於

之間的文本節點
筆者還進行了如下嘗試:(這裏有點偏向 文章所述 的第一條 實體編碼解析 的驗證)
1、對script中的任意幾個字母進行實體編碼+URL編碼,比如cr
這種情況下,瀏覽器不會對實體編碼解析,但是卻會認爲<script>這是一個標籤,還自動給加了一個閉合標籤</script>
2、對script這整個字符進行實體編碼+URL編碼
這種情況下,

在這裏插入圖片描述
3、對script前的<進行實體編碼+URL編碼
這種情況的結果與第2種情況一樣

觸發JS解析環境的還有javascript僞協議、onerror等

下面再測試下javascript僞協議
正常的一個標籤a通過javascript觸發JS彈框

在這裏插入圖片描述
現做如下嘗試:
1、對javascript:alert(/test/);中的test進行JS編碼

在這裏插入圖片描述
發現JS未進行解碼,這就有點神奇了,這不應該是JS解析環境嗎,繼續往下看
補充:這裏未能進行JS解碼解析,感覺有點困惑,於是嘗試了
javascript:alert(‘test’);即將test兩側的/換成了單引號,再對test部分進行JS編碼

在這裏插入圖片描述
結果正常顯示成test

在這裏插入圖片描述
審查下元素

在這裏插入圖片描述
看來上面無法進行JS編碼解析的原因是test兩側的/造成的,但爲什麼會造成這種情況,暫時不太清楚

2、對javascript:alert(/test/);中的test進行實體編碼+URL編碼

在這裏插入圖片描述
發現實體編碼進行了正常解析

3、對javascript:alert(/test/);中的alert進行JS編碼

在這裏插入圖片描述

alert進行了JS編碼解析,審覈元素看下

在這裏插入圖片描述
4、對javascript:alert(/test/);中的alert進行實體編碼+URL編碼

在這裏插入圖片描述
進行了實體編碼解析,審查元素看下
在這裏插入圖片描述
根據3,4兩個測試,發現alert既可以JS編碼解析又可以實體編碼解析

5、對javascript:alert(/test/);中的javascript進行JS編碼

在這裏插入圖片描述
直接報了這樣一個錯誤,相當於是把編碼部分也當成了鏈接的一部分,而不是javascript協議

6、對javascript:alert(/test/);中的javascript進行實體編碼+URL編碼
在這裏插入圖片描述

進行了實體編碼解析,觸發JS彈框
7、對javascript:alert(/test/);這一個整體進行實體編碼+URL編碼
在這裏插入圖片描述

進行了實體編碼解析,觸發JS彈框,這是不是說明這裏雖然是用到了javascript僞協議,但是
javascript:alert(/test/);這一部分卻依然是看做標籤a屬性href的值,從而能進行實體編碼解析

小結:因爲javascript:alert(/test/);這一部分依然可以看做是標籤a屬性href的值,於是當我們對其任意字符進行實體編碼後,依然能夠正常實體編碼解析,並觸發javascript僞協議;
可以對javascript:後面的部分做js編碼,因爲當觸發javascript僞協議後,就會進入JS解析環境,
然後對alert(/test/);的編碼解析情況就像是位於之間那樣

測試on事件

舉例:

現做如下嘗試
1、將alert(1)整個部分進行實體編碼+URL編碼
結果:成功彈窗
2、將alert(1)的整個部分進行JS編碼
結果:不彈窗
3、將alert(1)的alert進行JS編碼
結果:成功彈窗

小結:這裏的情況就像是位於javascript僞協議冒號後面一樣,同樣都可以進行實體編碼或JS編碼,
但是進行JS編碼時,不能對括號、引號都具有構成函數特殊意義的特殊字符進行JS編碼,但可以對函數的名稱比如alert進行JS編碼。

總結:實體編碼要在不破壞DOM樹的構成,對於有語法結構的標籤名、屬性名、標籤名就不能進行實體編碼,對屬性的值,標籤之間的文本節點能夠進行實體編碼,而JS編碼只能對位於JS解析環境內字符進行編碼且不能是括號、雙引號、單引號等構成特殊意義的特殊字符,比如alert(1)中的括號就不能進行實體編碼,而且在JS編碼環境中不會進行實體編碼解析,但有一個例外,在javascript僞協議中,比如test,即可以把javascript:alert(‘test’);這一部分看成是標籤a的屬性href的值,從而能夠進行實體編碼會被正常實體編碼解析,又可以對alert或alert中的字符進行JS編碼,但對alert中的字符編碼沒什麼實際作用,如果是javascript:alert(document.domain);這樣的,對document.domian進行JS編碼是不可行的,會報JS上的語法錯誤,不過能夠進行實體編碼,因爲是先進行實體編碼解析,後再進入js解析環境。

那麼對於XSS編碼繞過以上的編碼解析該如何起作用:
1、如果過濾了javascript,則可以考慮將javascript進行實體編碼繞過
(待補充)

參考:https://www.jianshu.com/p/5b72458a5258

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章