xss编码绕过详解(更像是在介绍实体编码和JS编码的解析过程)
原文:https://blog.csdn.net/qq_41631096/article/details/104747992
怕作者删除,先保留
---------------------------------------------------------------------------------------
注:本文通过研究各种情况下实体编码和JS编码是否生效,进而总结了哪些情况下能够进行编码后,javascript代码依然能够正常执行。
解析顺序是这样的,URL 解析器,HTML 解析器, CSS 解析器,JS解析器
URL的解码是在后台服务检测之前的,可以理解为后台收到URL后会自动进行解码,
然后才是执行开发人员编写的对URL中的值的检测函数,首先URL编码作用不在于绕过后台检测,但是当我们是GET方式提交数据时,而我们提交的数据中进行了实体编码,也就意味着存在&,#这样的特殊字符,这时就需要对这些特殊字符进行URL编码,这样才会保证正常解析,如果不进行URL编码的话,就会把+认为是空格了,而&也会是被认为用来连接URL中参数的连接符,故需要进行URL编码。如果是以POST方式传递值,就不需要进行URL编码了。
着重谈
实体编码(HTML解析器)&#十进制; 或者&#x十六进制;
JS编码(JS解析器) \u00十六进制
一、HTML解析(只要是DOM节点里属性的值,都可以被HTML编码和解析)
浏览器接收到页面数据,于是开始进行HTML 解析,构造DOM树。HTML 的分析器只能识别特定的词法规则,才能构建起DOM 树,这一块,HTML 不会做解码的工作,因为它做不了。
<img src%26%23x3d%3B"test"> (对=号进行了一次实体编码后再进行了一次URL编码)
因为正确的语法是 src=value 只有这样的时候,HTML解析器才会认为src是标签img的一个属性,而value是这个属性的值。
举例:(注意:以下列子都是以GET方式传递值,所以需要进行URL编码)
在这里我们通过GET方式传给name参数的值:
编码前:
对字符串test先进行一次实体编码,再进行一次URL编码(进行URL编码的原因已经在文章开头讲述过了)
于是就成了如下形式
进行访问,查看结果:
我们审查元素(审查元素所看到的就是经过解码后的结果)
查看网页源码:
可以看到src的值都是实体编码,这也证实
这也证实URL解码是在后台服务器上做的,而不是在浏览器,然后浏览器构建完DOM树后,进行了实体编码解析,于是看到了我们审查元素时所看到的结果
如果我们对"test"(包括test两边的双引号)进行一次实体编码再进行一次JS编码会怎么样
审查元素如下,发现多了一对双引号
查看网页源代码却是正常的,并没有多双引号,双引号的实体编码是"
这里应该是因为浏览器存在一个自动纠错的功能
现在我们对="test"这一部分进行一次实体编码再进行一次JS编码
没有像正常那样出现一个图片访问错误的图标
审查元素,发现实体编码都未进行解析
查看源码
这里就说明img的标签是已经正常构成的,但是它的src属性却并没有正常构成,因为=号被编码后,导致构造DOM树时,属性src不符合语法规则,无法被识别,所以src的值也无法进行实体编码解析
如果对src进行上述编码,经测试也无法进行实体编码解析,在这就不在赘述
小结:所以如果想要能够进行实体编码解析,就必须不能破坏语法结构,比如不能对标签名称、<>=等具有语法结构的特殊字符进行实体编码,可以对比如对标签之间的文本进行实体编码、对标签的属性的值进行实体编码
二、JS解析器,只有进入JS解析环境,才会进行JS编码解析,并且位于JS解析环境的,不会进行实体编码解析
测试:
编码前:
http://192.168.149.143/xss/example1.php?name=
进行访问,结果如下:
触发了弹框,但是发现内容依然是实体编码
说明了test并没有进行实体编码解析
查看源码:
下面我们对test进行JS编码(只能是unicode编码,即\u00十六进制)
编码前
http://192.168.149.143/xss/example1.php?name=
进行访问,结果如下:
可以看到正常显示为了test,说明JS编码被解析了
script之间的就是JS解析环境
对alert进行JS编码
结果能够正常触发弹框
笔者还作了如下尝试:
1、将alert(“test”);中的(进行JS编码
结果无法触发弹框
2、将alert(“test”);中的"进行JS编码
结果无法触发弹框
3、将alert(“test”);中的;进行JS编码,事实上把这个;去掉一样能触发弹框
结果无法触发弹框
可以发现对这几个特殊字符进行JS编码后,却无法触发弹框(这里为什么无法触发弹框,本人暂时也不太清楚,这里到底是否进行JS编码解析,也不太清楚)
因为这里的alert可以算作是之间的文本节点(文本节点这种说法可能不太准确,但是这里因为是JS解析环境只能进行JS编码解析),就像是位于
之间的文本节点
笔者还进行了如下尝试:(这里有点偏向 文章所述 的第一条 实体编码解析 的验证)
1、对script中的任意几个字母进行实体编码+URL编码,比如cr
这种情况下,浏览器不会对实体编码解析,但是却会认为<script>这是一个标签,还自动给加了一个闭合标签</script>
2、对script这整个字符进行实体编码+URL编码
这种情况下,
3、对script前的<进行实体编码+URL编码
这种情况的结果与第2种情况一样
触发JS解析环境的还有javascript伪协议、onerror等
下面再测试下javascript伪协议
正常的一个标签a通过javascript触发JS弹框
现做如下尝试:
1、对javascript:alert(/test/);中的test进行JS编码
发现JS未进行解码,这就有点神奇了,这不应该是JS解析环境吗,继续往下看
补充:这里未能进行JS解码解析,感觉有点困惑,于是尝试了
javascript:alert(‘test’);即将test两侧的/换成了单引号,再对test部分进行JS编码
结果正常显示成test
审查下元素
看来上面无法进行JS编码解析的原因是test两侧的/造成的,但为什么会造成这种情况,暂时不太清楚
2、对javascript:alert(/test/);中的test进行实体编码+URL编码
发现实体编码进行了正常解析
3、对javascript:alert(/test/);中的alert进行JS编码
alert进行了JS编码解析,审核元素看下
4、对javascript:alert(/test/);中的alert进行实体编码+URL编码
进行了实体编码解析,审查元素看下
根据3,4两个测试,发现alert既可以JS编码解析又可以实体编码解析
5、对javascript:alert(/test/);中的javascript进行JS编码
直接报了这样一个错误,相当于是把编码部分也当成了链接的一部分,而不是javascript协议
6、对javascript:alert(/test/);中的javascript进行实体编码+URL编码
进行了实体编码解析,触发JS弹框
7、对javascript:alert(/test/);这一个整体进行实体编码+URL编码
进行了实体编码解析,触发JS弹框,这是不是说明这里虽然是用到了javascript伪协议,但是
javascript:alert(/test/);这一部分却依然是看做标签a属性href的值,从而能进行实体编码解析
小结:因为javascript:alert(/test/);这一部分依然可以看做是标签a属性href的值,于是当我们对其任意字符进行实体编码后,依然能够正常实体编码解析,并触发javascript伪协议;
可以对javascript:后面的部分做js编码,因为当触发javascript伪协议后,就会进入JS解析环境,
然后对alert(/test/);的编码解析情况就像是位于之间那样
测试on事件
举例:
现做如下尝试:
1、将alert(1)整个部分进行实体编码+URL编码
结果:成功弹窗
2、将alert(1)的整个部分进行JS编码
结果:不弹窗
3、将alert(1)的alert进行JS编码
结果:成功弹窗
小结:这里的情况就像是位于javascript伪协议冒号后面一样,同样都可以进行实体编码或JS编码,
但是进行JS编码时,不能对括号、引号都具有构成函数特殊意义的特殊字符进行JS编码,但可以对函数的名称比如alert进行JS编码。
总结:实体编码要在不破坏DOM树的构成,对于有语法结构的标签名、属性名、标签名就不能进行实体编码,对属性的值,标签之间的文本节点能够进行实体编码,而JS编码只能对位于JS解析环境内字符进行编码且不能是括号、双引号、单引号等构成特殊意义的特殊字符,比如alert(1)中的括号就不能进行实体编码,而且在JS编码环境中不会进行实体编码解析,但有一个例外,在javascript伪协议中,比如test,即可以把javascript:alert(‘test’);这一部分看成是标签a的属性href的值,从而能够进行实体编码会被正常实体编码解析,又可以对alert或alert中的字符进行JS编码,但对alert中的字符编码没什么实际作用,如果是javascript:alert(document.domain);这样的,对document.domian进行JS编码是不可行的,会报JS上的语法错误,不过能够进行实体编码,因为是先进行实体编码解析,后再进入js解析环境。
那么对于XSS编码绕过以上的编码解析该如何起作用:
1、如果过滤了javascript,则可以考虑将javascript进行实体编码绕过
(待补充)
参考:https://www.jianshu.com/p/5b72458a5258