有關XSS編碼問題的個人總結

XSS也太太太難了,主要也是因爲自己沒花時間集中。

文章脈絡:根據我粗淺的理解,從開始學習XSS到現在,從一開始的見框就插到現在去學構造、編碼,首先需要的是能看懂一些payload,然後再去深入理解。所以,文章首先會介紹一些常見的可供利用的編碼,然後再理解瀏覽器如何解析HTML文檔,最後再總結一下。應該有很多不正確的地方,希望看到的朋友幫我指正以下,帶我挖洞,衝。QQ:2309896923

寫的這些內容都是借鑑總結了許多大神的文章,對大神提及的一些注意點進行總結歸納。

一、一般可利用的編碼

1.URL編碼
格式:%十六進制數

字符 編碼
= %3D
a %61
我太難了 %E6%88%91%E5%A4%AA%E9%9A%BE%E4%BA%86

記住常用符號、字母的 ASCII 碼,能熟練轉換 10 -16 進制即可。中文的URL編碼略有不同,因爲用的地方沒有,也就不詳寫了

如何利用:瀏覽器的 URL 地址欄,反射型 XSS,可以將特殊字符進行 URL 編碼,可以嘗試多次編碼試一試;POST過去的數據,存儲型 XSS,跟反射型的一樣。最後提一點:因爲一般網站處理數據的時候最開始解碼的一般是 URL 解碼,所以可以在用其他編碼構造完成 payload 後,最後再進行 URL 編碼,由此可見,可以根據解碼順序,靈活得進行編碼,最先解碼的,就最後編碼,懂我什麼意思吧,我也不太懂我到底有沒有說懂

2.HTML實體編碼
格式:&#十進制/十六進制; (一般是用十進制)十六進制的時候爲 &#x十六進制數

字符 實體名稱 實體編碼
< &lt; &#60;
: &colon; &#58;
換行 &NewLine; &#13;
空格 &nbsp; &#32;

對照ASCII碼錶基本就可以輕鬆轉換了

HTML實體編碼對照表參考地址:https://www.w3school.com.cn/html/html_entities.asp

如何利用:注意不要編碼 標籤的 <> 、屬性名、以及賦值號(等號=,冒號:)就可以了

3.JS編碼
格式:①--unicode:\u十六進制 ②--\八進制、\十六進制

字符 \u \八進制 \十六進制
a \u0061 \141 \x61
b \u0062 \142 \x62
c \u0063 \143 \x63

如何利用:一般使用 jsUnicode編碼比較多,其他的兩種還在研究,望得到高人指點

4.CSS編碼
格式:\1~6位十六進制數
後邊就不能直接緊跟數字或字母,否則會被當成轉義裏的內容處理,所以CSS 選擇了空格作爲終止標識,在解碼的時候,再將空格去除。

如何利用:在使用 style 屬性或標籤的時候使用,或者也可以在引入外部 CSS 文件的時候,將引入的文件內容進行編碼

二、弄清楚瀏覽器解碼順序

瀏覽器解析順序:

示例HTML代碼:
<a href="j&#x61vascript: //%0&#x61;&#x00025;61l\u0065rt(1)">click me</a>

解釋:
1.首先瀏覽器接收到HTML代碼,會先開始進行HTML解析,構造DOM樹,粗略的講就是識別 <> 這些標籤,賦予其特殊含義,區別於純文本內容。
注意此時並不會做任何解碼操作,所以構造 &#lt;img src&#x3d;"javascript:al\u0065rt(1)">是不會彈窗的,因爲沒有識別到標籤,它相當於就是一個純文本,具體來說就是:標籤屬性名和賦值符號不能編碼,但是標籤屬性的值可以編碼

2.DOM樹構造完成,開始HTML解碼,變成了<a href="javascript://%0a%61l\u0065rt(1);">click me</a>

3.唉,碰到鏈接類屬性 href 了,儘管發現了是javascript僞協議,瀏覽器也會直接 URL 解碼一次,然後就變成了 <a href="javascript://al\u0065rt(1)">click me</a>

4.解碼後,因爲是 javascript 僞協議,所以 JS 解析器便開始工作了,解析成了 <a href="javascript://alert(1)">click me</a>,注意在識別協議的時候,協議是不能被任何編碼的,除非在識別之前已經被解碼了,不然的話是不能被識別出來的的,比如說 href="j%61vascript:alert(1)" ,冒號被編碼也不行,瀏覽器雖說會 URL 解碼,但是並不會解碼之後再識別一次這是什麼協議,於是不管是 http 協議還是 javascript 僞協議也好,此時都發揮不了作用而且,此時 href="j%61vascript:alert(1)" 中的冒號括號也不能被 js 編碼,否則不會彈窗

5.然後就順利彈窗了

6.當然,並不是所有時候都是這種解碼順序,要依據具體情況而定。

7.演示一下如何自己進行編碼:
可以看到上述例子瀏覽器解碼順序爲 HTML實體解碼 -> URL解碼 -> JSUnicode解碼 <-----> 於是便反過來編碼 JSUnicode解碼 -> URL解碼 -> HTML實體解碼
假設要編碼的內容:<img/src/onerror=alert(1)>,可以先思考一下改如何編碼,再往下看

首先JSUnicode編碼 : <img/src/onerror=\u0061\u006c\u0065\u0072\u0074(1)>,加不加雙引號包裹onerror後面的內容無所謂,加也好,不加也好,最好不加,因爲雙引號被過濾了的話,會更麻煩,依據前文所述,此處的注意點有:不能編碼括號 (),還有一點很奇怪,彈窗提示的 1 字符也不能被編碼,否則不會彈,除非加引號包裹起來。
其次HTML編碼 : <img/src/onerror=\u0061&#x5C;&#x75;006c\u0065\u0072\u0074&#x28;1)>此處的注意點有:不能編碼標籤的 <>、屬性、等號=
最後URL編碼 : %3Cimg/src/onerror%3D%5Cu0061%26%23x5C%3B%26%23x75%3B006c%5Cu0065%5Cu0072%5Cu0074%26%23x28%3B1%29%3E

最後一個問題:這句payload應該插在哪? 一般是反射型的XSS直接便可以見到效果,
有php環境的可以試一下:a.php 內容爲 <?php echo $_GET["a"]; ?>,然後用瀏覽器打開這個文件,後面接 ?a=%3Cimg/src/onerror%3D%5Cu0061%26%23x5C%3B%26%23x75%3B006c%5Cu0065%5Cu0072%5Cu0074%26%23x28%3B1%29%3E,即可彈窗

如圖:

注意點總結:

1.轉義編碼應當只出現在標示符部分,不能用於對語法有真正影響的符號,也就是括號,或者是引號、等號、冒號

2.瀏覽器是不會在html標籤裏解析js中的那些編碼的!所以我們在οnerrοr=後面放js中的八進制、十六進制編碼(jsUnicode編碼除外)是不會解析 你放進去是什麼 解析就是什麼!而另一方面,如果想用這種方式來替換掉圓括號,或者引號,會判定爲失敗。同時,主要注意的方式,上邊這種直接在字符串外進行專一的方式,只有Unicode 轉義方式被支持,其他轉義方式則不行。其實,這樣的策略是正確的,因爲對於JavaScript,轉義編碼應當只出現在標示符部分,不能用於對語法有真正影響的符號,也就是括號,或者是引號。其實,這樣的處理方法,反而是比CSS 更加合理的。

3.HTML解析器在建立文檔樹的時候會針對節點內的Entity編碼(即實體編碼)解碼後傳輸。

4.使用DOM 操作,對DOM Tree 造成了改變,會調用到 HTML 解析器重新對其解析,意思就是,用 DOM 操作創建了節點標籤什麼的,會重新調用 HTML 解析

5.在一個頁面中,可以觸發 JS 解析器的方式有這麼幾種:
直接嵌入< script> 代碼塊。
通過< script sr=… > 加載代碼。
各種HTML CSS 參數支持JavaScript:URL 觸發調用。
CSS expression(…) 語法和某些瀏覽器的XBL 綁定。
事件處理器(Event handlers),比如 onload, onerror, onclick等等。
定時器,Timer(setTimeout, setInterval)
eval(…) 調用。
可以想一下這個 <script>\u0061\u006c\u0065\u0072\u0074\u0028\u0031\u0031\u0029</script>,爲什麼這個不彈窗呢?????????????????
不清楚可以看一下參考文章的第一篇!!

另外一些例子:
以下兩個表示相同:
<img src="http://www.example.com">
<img src="ht&#x74;p&#x3a;//www.example.com">
因爲在識別協議之前,已經HTML解碼了,所以並不會出現識別協議失敗

下面兩個例子代碼不會執行,因爲,編碼的是標籤本身的結構而非節點內的內容:(這一點非常重要)
<img src&#x3d;"http://www.example.com">
<img s&#x72;c="http://www.example.com">

 

 

更多幹貨 請點擊這裏

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