zoukankan      html  css  js  c++  java
  • 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编码)

    http://192.168.149.143/xss/example1.php?name=

    在这里我们通过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

  • 相关阅读:
    combo,raido
    块级作用域问题ES5 & ES6
    基本类型和引用类型_深拷贝和浅拷贝
    由数组扁平化切入generator函数
    Promise基本用法
    原生ajax请求之前端
    ExtJS组件window
    ORACLE(+) 号的用法,及与逗号运算符的差别
    centos7发布json中文显示乱码
    centos7 svn在repository在的情况下重装恢复
  • 原文地址:https://www.cnblogs.com/mrhonest/p/14041035.html
Copyright © 2011-2022 走看看