先了解一下什么是XSS ! ! !

  • xss

     

    (跨站脚本攻击)

     

跨站脚本攻击(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。


Tip:本文主要说明XSS的代码构造,如果对XSS的概念方面还不懂得话,建议先去学一下XSS的基本原理。


什么是XSS-Filter呢,其实说白了就是一种安全过滤机制,是一段构造好的函数。他会对我们用户的输入进行

检测,按照事先设定的白名单或者黑名单对提交数据进行拦截,转义和过滤等处理。


我在虚拟机中搭建了php环境,安装了phpcms,先看看它里面用的XSS过滤代码吧。

文件名字是global.func.php,然后全文搜索XSS就会找到如下类。


/**

 * xss过滤函数

 *

 * @param $string

 * @return string

 */

function remove_xss($string) { 

    $string = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S', '', $string);


    $parm1 = Array('javascript', 'vbscript', 'expression', 'applet', 'meta', 'xml', 'blink', 'link', 'script', 'embed', 'object', 'iframe', 'frame', 'frameset', 'ilayer', 'layer', 'bgsound', 'title', 'base');


    $parm2 = Array('onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate', 'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange', 'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavailable', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate', 'onfilterchange', 'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete', 'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset', 'onresize', 'onresizeend', 'onresizestart', 'onrowenter', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop', 'onsubmit', 'onunload');


    $parm = array_merge($parm1, $parm2); 


for ($i = 0; $i < sizeof($parm); $i++) { 

$pattern = '/'; 

for ($j = 0; $j < strlen($parm[$i]); $j++) { 

if ($j > 0) { 

$pattern .= '('; 

$pattern .= '(&#[x|X]0([9][a][b]);?)?'; 

$pattern .= '|(&#0([9][10][13]);?)?'; 

$pattern .= ')?'; 

}

$pattern .= $parm[$i][$j]; 

}

$pattern .= '/i';

$string = preg_replace($pattern, ' ', $string); 

}

return $string;

}

开头的filter_xss函数只要使用时调用就可以了。即使如上过滤很严格的话,也依然存在被绕过的可能,因为触发XSS的情况太多了,方法也很多,下面就介绍种方法。

(1) html标记<>进行基本操作

当我们可以随意插入<>且不被转义和过滤的时候,就可以构造出<script>alert(‘xss’)</script>,其中alert(‘xss’)可以替换为任意的shellcode

(2) 利用HTML标签的属性

HTML标签的属性如img的src属性,等等,都支持js代码伪协议形式,所以js解释器都可以起作用,这样看来我们又多了好多种构造代码的方式

如:<img src=”javascript:alert(‘xss’);”>

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

但在实际情况中并不是所有的构造都可以成功弹窗,因为并不是所以的浏览器都支持js的伪协议执行,而且也并不是所有的标签属性都可以拿来用,一般只有引用了文件的属性才能够用,例如href, lowsrc, bgsound, background, value, action, dynsrc这样的资源引用才可以。

(3)    空格回车及制表符绕过

      如果关键字JavaScript被列入黑名单,我们就可以用空格,回车,以及制表符来绕过黑名单

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

      上面的JavaScript中的空格实际上并不是空格键实现的,而是制表符Tab添加的,当然利用空格实现关键字的拆分也是可行的,同样回车也可以。

     至于原理的话,编程语言一般以分号作为一条语句的结束标识,js也是如此,但是作为一种弱类型语言,分号在一行语句完整的情况下是可以省略的,但如果这样写:

<img src=”javas

Cript:

Alert(/xss/)” width=100>

因为js引擎发现第一行<img src=”javas并不完整,所以会继续处理下一行,发现没有分号同时语句也不完整,所以他依然默默坚持着,最后终于来到了>这里,惊喜的发现语句完整了,到此js语句也成功执行。

(3) 标签属性转码绕过

这个和字符编码绕过有点类似,所以在最后说,这边提一下。

(5)  产生事件绕过

事件是什么呢?事件是用户或浏览器自身执行的某种动作,比如我们鼠标单击产生的click事件,鼠标指针穿过被选元素或其子元素产生的mouseover事件等等,响应事件的函数叫做事件处理函数即事件监听器

例如

<input type=”button” value=”click me” onclick=”alert(‘click me’)” />

此代码创建了一个值为click me的按钮,用户单击该按钮即触发onclick事件,随后执行事件中的js代码。

如此我们可以构造如下跨站代码

<img src=”#” onerror=alert(/xss/)>

Onerror事件只在src路径错误时触发,由于#路径不存在所以可以成功执行js代码,所以构造成功的关键在于事件本身的触发条件何时能够满足,说白了就是只要满足触发条件保持着恒为假或者真就可以了。

常用可触发事件列举如下

OnResume

OnReverse

OnRowdelete

OnRowInserted

Onseek

OnsynchRestored

OnTimeError

Ontrackchange

Onurlflip

Onrepeat

Onmediacomplete

Onmediaerror

Onpause

Onprogress

Onoutofsync

等等就不列举了,百度搜索就有

(6)  利用CSS跨站

       优点:隐蔽性高

       缺点:各浏览器无法通用

       例:

       <div style=”background-image:url(javascript:alert(‘xss’))”>

       <style>

            body {background-image:url(“javascript:alert(‘xss’)”);}

       </style>

      利用css我们也可以外联我们自己的css文件,<link rel=”stylesheet” href=http://www.xxx.com/xxx.css>,这样执行跨站脚本很方便,而且不容易被察觉。

还有@import也可以外部引入,有兴趣的可以自行百度。

(7) 扰乱过滤规则

      1、转换大小写

      2、大小写混淆

      3、单引号代替双引号

      4、不使用引号

     5、构造不同的全角字符来绕过过滤规则

     6、用/**/来注释字符,以此插入垃圾字符来绕过,这点和SQL注入的绕过MySQL数据库的方法有点像,除了/**/外,还有\和\0

     7、css中的关键字也可进行关键字处理,如将expression的e转换成\65

其他类型

例:

<img/src=”javascript:alert(‘xss’);”>

此段代码在IE6中可以正常执行


(8) 利用字符编码

      1、如果对便签属性被过滤,可以将代码用ASCII码进行替换

      如<img src=”javascript:alert(‘xss’);”>替换为

     <img src=”javascrip&#116&#58alert(/xss/);”>

     2、十进制转码,十六进制编码,八进制编码


(9)拆分跨站法

     剑心大大曾经就介绍过这种方法

     网站留言板允许用户多次留言,这样我们就可以将跨站代码拆分开来,并用变量将这些‘’碎片‘’存储,最后用eval函数合并显示执行代码,这和缓冲区溢出的shellcode的利用方式有异曲同工之妙。

     其实还有更多的拆分合并的方法让我们去发现,我相信这是一个十分有趣的过程!


最后:本文篇幅有限,仅仅是介绍了几个切入点,有兴趣的可以沿着这颗树继续延伸下去,利用好百度,我想另外一个跨站世界在等着你!


  Qug   V安全资讯