浏览器解析规则

URL编码:

一个百分号和该字符的ASCII编码所对应的2位十六进制数字,例如“/”的URL编码为%2F(一般大写,但不强求)

HTML实体编码:

  • 命名实体:以&开头,分号结尾的,例如“<”的编码是“<”
  • 字符编码:十进制、十六进制ASCII码或unicode字符编码,样式为“&#数值;”,例如“<”可以编码为“<”和“<”

JS编码:js提供了四种字符编码的策略

1、三个八进制数字,如果不够个数,前面补0,例如“e”编码为“\145”
2、两个十六进制数字,如果不够个数,前面补0,例如“e”编码为“\x65”
3、四个十六进制数字,如果不够个数,前面补0,例如“e”编码为“\u0065”
4、对于一些控制字符,使用特殊的C类型的转义风格(例如\n和\r)
5、jsfuck编码

CSS编码:用一个反斜线()后面跟1~6位的十六进制数字,例如e可以编码为“\65”或“65”或“00065”

HTML解析器能识别在文本节点和参数值里的实体编码,并在内存里创建文档树的表现形式时,透明的对这些编码进行解码

浏览器的解析规则:浏览器收到HTML内容后,会从头开始解析。当遇到JS代码时,会使用JS解析器解析。当遇到URL时,会使用URL解析器解析。遇到CSS则用CSS解析器解析。尤其当遇到复杂代码时,可能该段代码会经过多个解析器解析。

比如:<a href="javascript:window.open('http://www.baidu.com')">test</a>

这段代码,HTML解析器首先工作(注:此时,若href=”字符串”中的字符串存在字符引用,会对其解码)。然后URL解析器开始对href值进 行URL解析。进行URL解析时,URL资源类型必须是ASCII字母(U+0041-U+005A || U+0061-U+007A),不然就会进入“无类型”状态。即,javascript:是不能进行任何js编码的。解析了javascript:之后, 会由JS解析器进行解析。JS解析器针对一些编码,其只有在标志符名称里的编码字符才能够被正常的解析。解析完window.open以后,又会由URL 解析器进行解析。想了解各解析器的特性,可参考这篇文章深入理解浏览器解析机制和XSS向量编码

JS解析器不会解析和解码字符引用,而针对JS的一些编码其会视情况而定。

可以看到,该代码经过了HTML->URL->JS->URL 四重解析。由于不同的解析器能够分别对一些编码格式进行解析,所以我们可以通过生成特定格式的编码代码,令其在依次解码后能够正确执行,从而绕过WAF。

如:

<a href="&#x6a;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;:%61%6c%65%72%74%28%32%29">test</a>

该代码能够正确执行。

首先,经过HTML解析之后,代码会变成

<a href="javascript:%61%6c%65%72%74%28%32%29">test</a> 

此时,由于javascript已经生成,不违反URL解析规则。所以,URL解析正常。解析了javascript,最终进入JS解析器。注意,URL解析器还完成了URL解码工作。

<a href="javascript:alert(2)">test</a> 

所以,JS最终解析的代码时alert(2).成功执行。

总结来说,各种编码在XSS中的利用非常灵活,我们需要在充分了解浏览器的解析原理合理构造合理编码顺序的代码,最终构造出Payload。

猜你喜欢

转载自www.cnblogs.com/zzhoo/p/12560694.html
今日推荐