不乱于心,不困于情。
不畏将来,不念过往。如此,安好。

浏览器解析与编码绕过

0x00背景

学习了这么久,我才发现根本不会绕过,以前以为就是简单的编码转换就好了,乱编一通。经过大佬分享资料之后,才算弄懂。记录,加深理解。

0x01浏览器解析

浏览器的解析可以分为3步:

1. HTML解析(HTML解析器)

2. JS解析(JavaScript解析器)

3. URL解析(URL解析器器)

这3个解析器协调工作,首先浏览器接收到一个HTMl文档时,会触发HTML解析器对文档进行词法解析,完成HTML解码和DOM树的建立。接下来JavaScript解析器介入开始对内联的脚本进行解析,包括解码操作。如果浏览器遇到需要URL的上下文,URL解析器也会介入开始解析解码。(URL解析会根据文档中URL的实际位置不同而在不同的时间解析,例如遇到Onclick事件需要触发才会执行的代码会跳过,等到事件被触发时才会被解析)

举个栗子:

  <html>

<head>

<script type=”text/javascript”>

function open_win()

{

window.open(“javascript:alert(1)”);

}

</script>

<body>

<input type=”button” name=”Open window” onclick=”open_win()”>

</body>

</head>

</html>

在这个html文档中,解析的顺序就是:HTML解析–>JavaScript解析(触发onclick事件)–>URL解析–>JavaScript解析

因此可以看到,如果对以上文档的open函数的参数(“javascript:alert(1)”) 进行编码的话,应该是URL编码(当然,只要JavaScript被正确解码之后,后面的alert也可以使用JavaScript编码)。

0x02 常见编码

HTML字符实体:< 编码为&lt; &#60;

JavaScript编码:<编码为unicode码\u003C

URL编码:%加上字符的ASCII编码对应的2位数字

因此在进行编码绕过的时候,要根据当前输入点的位置与输入的内容进行正确的编码绕过。

以上面的代码为例:

如果只是将javascript:alert(1)  整体全部进行URL编码

window.open(“%6A%61%76%61%73%63%72%69%70%74:%61%6C%65%72%74%28%31%29”);

那么是绕不过去的,因为整体编码就连协议类型(JavaScript)一起编码了,浏览器在进行URL解析的时候就会默认为无类型,所以只会按照URL的规则进行解析,但是不会涉及到JavaScript解析器,所以在这里这一条命令只像是被一句文本而已。

如果只编码 alert(1) 的话就能正确执行,如下:

window.open(“javascript:%61%6C%65%72%74%28%31%29”);

在这里当URL解析器介入开始解析的时候,能够识别出接下来的内容为JavaScript代码,所以就会再由JavaScript解析器进行解析。

如果对整体进行Unicode编码的话也能正常解析执行。因为URL解析器运作时JavaScript解析器已经把javascript:alert(1)解析完成。

window.open(“\u006a\u0061\u0076\u0061\u0073\u0063\u0072\u0069\u0070

\u0074\u003a\u0061\u006c\u0065\u0072\u0074\u0028\u0031\u0029”);

如果对整体进行HTML实体编码,一样无法正确解析执行。因为这个函数是在onclick事件之后才会被解析执行,此时参与解析的只有JavaScript和URL解析器,HTML解析器已经不再参与到这个函数内的解码过程了,因此HTML实体编码无法被解析执行。

window.open(“javascrip:alert(1)”);

同样的,类似如下场景,将输⼊入数据编码成HTML字符实体并将其放在script块中,也⽆无

法成功解析alert(1),因为script块中的编码解析不会调用HTML实体解析器。

alert(9);

<script>&#97;&#108;&#101;&#114;&#116&#40;&#57;&#41;&#59</script>

若是如下情景,那么可以成功执行javascript:alert(1),因为整个编码文本是放在HTML的标签里面的,整个解析过程为HTML解析->URL解析->JavaScript解析,在URL解析器作前,HTML解析器已经把字符实体转换成了javascript:alert(1)。

<a  href=”&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#

108;&#101;&#114;&#116;&#40;&#49;&#41;”>tkswifty</a>

同理,如下情景也可以成功执行:

<a href=” &#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;:%61%6C%

65%72%74%28%32%29 “>tkswifty</a>

0x04 细节:

(1)在字符串串中,Unicode转义序列列(\uXXXX)将永远不不会破坏字符串串的上下文,因为只能被解析成字符串常量。(JavaScript解析时只有标识符名称不会当字符串解析,控制字符(单双引号、换⾏行行符等)仅会被解析成标示符名称或者字符串串)

Examples:

<input type=”button” name=”demo” onclick=”alert(1)”>

对alert进行Unicode编码:

<input type=”button” name=”demo”  onclick=”\u0061\u006c\u0065\u0072\u0074(1)”>

可以解析执行

对alert(1)进行Unicode编码:

<input  type=”button” name=”demo” onclick=”\u0061\u006c\u0065\u0072\u0074u0028\u0031\u0029″>

无法解析执行

(2)URL解析过程的一个细节:不能对协议类型进行任何的编码操作,否则URL解析器会认为其无类型。

(3)RCDATA元素有个特殊情况,在浏览器器解析RCDATA元素的过程中,解析器器会进入“RCDATA状态”。在这个状态中,如果遇到”<“字符,会转换到”RCDATA小于号状态”。如果”<“后没有紧跟”/”和对面的标签名,解析器器会转换回”RCDATA状态”。常见的RCDATA元素:<textarea>和<title>

Example:

<textarea>中,唯一能被解析器认作标签的就是</textarea>,在其中新建标签,也不会有脚本可以执行。

<textarea><script type=”text/javascript”>alert(1)</script></textarea>

具体效果:

具体效果:

(4)当某些函数的执行改变了当前页面的DOM树结构,HTML解析器会再次执行解析。

赞(0)
未经允许不得转载:seo优化_前端开发_渗透技术 » 浏览器解析与编码绕过