XSS编码与绕过

 XSS编码与绕过 javascript

0x00 背景

对于了解web安全的朋友来讲,都知道XSS这种漏洞,其危害性不用强调了。通常对于该漏洞的防御有两个思路:一是过滤敏感字符,诸如【<,>,script,'】等,另外一种是对敏感字符进行html编码,诸如php中的htmlspecialchars()函数。php

通常状况,正确实施这两种方案之一就能够有效防护XSS漏洞了。但其实也会有一些场景,即便实施了这两种方案,攻击者也能够绕过防御,致使XSS漏洞被利用。html

0x01 绕过场景

下面主要是参考文章http://www.freebuf.com/articles/web/43285.htmljava

场景一:XSS注入点在某个html标签属性中,代码片断以下git

能够看到,这里防御措施采用的是方案一:过滤敏感字符。那么这里若是输入javascript:alert (11),是会被过滤掉的,输出的内容会是:github

这固然不能弹框,常规的xss payload就会失败了。如同参考文中所说的,这里绕过方法有不少中,你彻底不须要使用 > 去闭合html标签,也能够用其余关键字来代替javascript,不过既然说的是编码问题,固然要用编码问题来解决问题。web

这里能够对"javascript:alert(11)"进行html编码来绕过,你能够试试将html编码后的payload传递给name参数,也就是:javascript%3Aalert%2811%29,能够看到熟悉的窗口又弹出来了。缘由就是,浏览器在解析到这段代码时,会对其先进行html解码,而后当触发onclick事件后,会调用js引擎对其进行js编码后执行js代码,因此就看到了弹窗。原文在这里只提到了html编码的方式,其实这里还能够对payload进行js编码。可是要注意的是,这里不能将整个payload进行编码,你要像这样:express

又能够看见弹框了。(是否是略微有点看不懂啊,不要紧,接下来还有更绕的)浏览器

 

场景二:XSS注入点在js标签中,代码片断:安全

这里采用的防御措施是第二套,使用php内置函数htmlspecialchars对敏感字符进行编码。若是输入正常的payload,如:<img src=1 onerror=alert(11)>,是不会有弹窗的,此时浏览器的输出:

这里的敏感字符< >,已经被html编码了,最后在<div>标签里面输出的时候浏览器再使用html解码将其原文显示出来,可是并不会再触发js引擎了,因此也就没有弹窗了,利用失败。

这里使用js编码就能够绕过了,由于浏览器是先js解码而后再html解码,经过js编码后的payload在html解码的时候已是正常的html了,就会触发js引擎,弹框也就出来了。

试试js编码后的payload:

 

看到这里,你心中确定有疑问,浏览器究竟是怎么解码的,为何一会先js解码,一下子又是先html解码?起初我在看到这里时候也一直很纳闷,原文里面并无对浏览器为何这样解码说明缘由,直到我看到这篇文章http://xuelinf.github.io/2016/05/18/编码与解码-浏览器作了什么/。该做者从原理上对浏览器编码解码进行了说明,揭开了个人疑问,这篇文章也主要是说明该问题。

0x02 浏览器编码解码方式

来看看浏览器处理一次完整的http请求,会涉及到的编码解码问题。

  1. 当浏览器发送http请求时,会先对特殊字符进行URL编码后,发送给服务器。
  2. 服务器收到客户端发送来的http请求,会对其进行URL解码后,再进行处理,处理完成后将结果返回给浏览器。
  3. 浏览器接收到html文件后,最早是触发html解析器来解析html,将标签转化为内容树中的DOM节点,此时在识别标签的时候,html解析器是不能识别哪些被html实体编码了,只有当整个DOM树创建起来后,才能对每一个节点的内容进行识别,若是有html实体编码,再对其进行解码。
  4. 在html解析器过程当中,遇到js标签诸如<script>会调用js解释器对js代码进行解析,而js DOM API会对DOM结构进行更改,DOM树节点的更改也会反过来触发html解释器。
  5. CSS解释器也会在html解释器过程当中参与进来,但它不会干扰到DOM树,它会结合<style>标签和CSS文件以及html指令来构建render tree。

以上,就是浏览器解析一次完整http请求所会涉及到的编码解码问题。浏览器在收到html文件后,若是没有js DOM API的参与,那么浏览器会按照html解码àCSS解码àjs解码的顺序解析下去,可是因为js DOM API的存在,解码顺利会被打乱,因此有了上面两个场景中不一样的解码顺序,那么到底为什么要按照这样的解码方式呢?再来具体看看js解释器的处理流程。

当浏览器在处理诸如<script> <style>标签,解释器会自动切换到特殊解析模式,src href后边加入的javascript为URL,也会进入到JS解析模式。而进入该解析模式的时候,该DOM节点已经创建起来了,可是html解释器还并未进行html解码。当触发js解释器后,js会先对内容进行解析,若是有js编码就会进行解码操做,接下来是就是执行里面的js语句。因此此时执行该js语言前的解码顺序为js解码-->html解码。

来看看可以触发js引擎的标签:

  • 直接嵌入< script> 代码块。
  • 经过< script sr=… > 加载代码。
  • 各类HTML CSS 参数支持JavaScript:URL 触发调用。
  • CSS expression(…) 语法和某些浏览器的XBL 绑定。
  • 事件处理器(Event handlers),好比 onload, onerror, onclick等等。
  • 定时器,Timer(setTimeout, setInterval)
  • eval(…) 调用。

既然js DOM API能够更改浏览器正常的解码顺序,那么触发js解释器的方式有哪些呢?

了解了浏览器的编码解码以后,咱们再回头看一下前面的两个场景。

第一个场景中,js语句是在a标签中,在onclick事件触发js解释器以前,DOM树结构已经创建完成了,而且这里也没有DOM API操做,因此浏览器会先对该语句进行html解码,而后再是js解码,因此当咱们对payload进行html编码后,在js解释器解析该js语句时,其已经被html解码了,是正常的js语句,因此可以正常弹窗。

场景二中,payload是在script标签里面,浏览器解析到这里时,会触发js解释器,js解释器会对该语句进行js解码操做,咱们使用js编码的payload被还原成正常的语句。虽然此时整个DOM树已经创建起来了,可是因为DOM API存在,会再一次的调用html解释器,对咱们的payload进行解析,payload里面有js标签,再一次触发js解释器,完成对js语句调用,成功弹窗。

0x03 总结

能够看到,由于浏览器丰富多样的解码方式,对于XSS的防护不能彻底单一依靠编码和过滤操做,须要根据上下文对输入语句,先进行相应的解码以后再进行编码和过滤操做,才能有效的防护XSS。

 

by:会飞的猫

转载请注明:http://www.cnblogs.com/flycat-2016

相关文章
相关标签/搜索