浏览器解析与编码顺序及xss挖掘绕过全汇总

在以往的培训和渗透过程中,发现很多渗透人员尤其是初学者在挖掘xss漏洞时,很容易混淆浏览器解析顺序和解码顺序,对于html和js编码、解码和浏览器解析顺序、哪些元素可以解码、是否可以借助编码绕过等情况也基本处于混沌的状态,导致最终只能扔一堆payload上去碰碰运气。这篇文章就把浏览器解析顺序、编码解码的类型、各种解码的有效作用域以及在xss里的实战利用技巧做一个系统总结,让你深度掌握xss挖掘和绕过。

文章结构如下:

1、前提:编码相关1.1 URL编码 标准的url结构我们都清楚,像这样:

scheme://login:password@address:port/path?query_string#fragment

比如:

http://example.com/test.php?uid=27&content=on#main

可以看到,像:?/=这些字符是浏览器用来解析URL用于语义分隔的保留字符,那么问题来了,如果URL中某个部分的名称用到了这些字符,就会破坏语法,影响正常解析,于是就有了url编码,它以一个百分号%和该字符的ASCII对应的2位十六进制数去替换这些字符,如常见的空格编码为%20,百分号%编码为%20,等于号=编码为%3d,等等。

1.2 HTML编码 跟url的问题类似,一些字符在 HTML 中也是是预留的,像<这样的对于HTML来说有特殊意义的字符,在浏览器中会被解析成各种标签,如果要作为纯文本输出这个字符,就需要用到字符实体。

HTML编码类型:

说到编码的时候,大多数初学者看到&#x;这些字符通常会一头雾水,其实我们见到的所谓“编码”有两种,共同点是以连接符&开头以分号;结尾,中间字符有:

英文字符;#后接十进制数或#x后接十六进制数。如<、<和<都可以被解码成常见的尖括号<:

再具体一点,lt叫做实体名称,60和x3c叫做实体编号,效果其实是一样的,只是实体名称更容易记忆,但就浏览器的支持性来说实体编码要好一些。常见的实体如下:

(注:在<被过滤的场景下很多人会尝试使用<来绕过,这样输出的尖括号会被解析成文本格式,而不是作为标签执行,很少的情况下可以利用成功,下面会有案例讲到。)

1.3 JS编码道理同上,js常见的反斜杠方式编码处理

\b退格符,\t制表符,\v垂直制表符等;三位数字,不足位数用0补充,按8位原字符八进制字符编码;两位数字,不足位数用0补充,按8位原字符16进制字符编码,前缀 x 四位数字,不足为数用0补充,按16位原字符16进制Unicode数值编码,前缀 u 。如\145、\x65和\u0065都代表字符e。

2、浏览器解析顺序:2.1 数据包处理过程: 首先要了解我们在构造xss包的时候发生了什么:

1、在浏览器的地址栏中输入url,发送http请求头和数据;

2、数据包通过网络传输到达远程web服务器,服务器接收到url,分析请求头,根据它找到对应资源,经过后端代码进行处理(过滤,校验),然后给前端返回响应头和数据;

3、浏览器接收到响应的数据后,对数据进行解析(下面要说的事)

2.2 浏览器解析顺序 主要分为两个过程:

1、 浏览器接收到响应数据后,解析器先对HTML之类的文档进行解析,构建成DOM节点树,同时,CSS会被CSS解析器解析生成样式表。

2、 解析html标签过程中遇到 尾部的script脚本中改变了DOM节点树,通过对

操作新增了一个,所以通过调换

对value值进行编码:

效果都是一样的,xss挖掘中这样的编码适用于js代码环境中alert等函数被过滤的情况。

3.4 浏览器的解码顺序: 首先要强调是一点是:浏览器的解码顺序和解析顺序是两码事。浏览器一般的解码顺序是先进行html解码,再进行javascript解码,最后再进行url解码,需要注意的是这里的url解码和我们发送到服务器的url解码不同,那个过程是由服务器来完成的,而不是浏览器。

明白了这个顺序,我们就可以理解是无法弹框的,因为script标签内无法解析HTML实体编码。

2个tips:

1、 在闭合,就要提早放弃。

2、 属于外部标签,是一种特殊的标签,它使用XML格式定义图像,支持XML解析。因为xml支持在标签内解析HTML实体字符,所以在XML中(会被解析成(,是可以被解析的。

前端技术繁多,还有很多其他小tips,在这里不一一列举。

3.5 实例解析例1:

根据上面讲的浏览器解码顺序,我们可以提交payload:

第一步 在html中所以解析成:

第二步 因为事件触发函数后的字符串也是js代码,经过js解码成:

例2:

当下大多数网站对xss的防御是对用户输入使用html实体编码,大多数情况下可以达到效果,但有些场景下并不能生效,一种经典的情况就是,服务器将用户输入的htmlencoded值直接动态输出到客户端javascript(事件处理器)中:

id=textbox>

如果input处用户输入a onclick=alert(document.cookie),结果会输出为:

很容易理解,根据上述讲到的浏览器解析顺序,用户输入——>后台代码编码——>浏览器(HTML解析器)解析——>传到js代码执行。

下面这个也是在现实渗透中发现的一个案例,核心也是在经过解码为value值后传递给了innerHTML,将其二次解析成HTML格式内容。所以总结起来绕过这种编码的关键就是需要注意输入输出的上下文,看输入是否进行了二次传递、处理。

4、xss的挖掘和绕过思路 xss的挖掘思路的核心是:关注“输入”和“输出“”,也是大多数漏洞产生和挖掘的核心。基本的思路和流程如下:

简单来讲分为三步:

1、探测输出点

输入处使用容易辨识的特征值明确输出点,如“aaaaa”,“11111”等等都可以,确定是单点输出、多点输出,以及是否存在二次输出的情况。

2、根据HTML结构构造payload

这一步需使用第二章的内容,明确输出点的位置在HTML标签文本内、标签属性中、标签事件中、

Copyright © 2022 九州天命装备站 - 装备获取&角色养成活动 All Rights Reserved.