0×00 简介
0×01 解码过程总述
0×02 浏览器中的词法分析
0×03 HTML编码与HTML解析
0×04 常见误区
0×05 浏览器有趣的容错行为
0×06 结语
*原创作者:VillanCh
0×00 简介
编码问题一直是一个痛点,在wooyun有一篇XSS编码的文章,讲到一些痛点,既然准备再次完成一篇对XSS中的编码讲解,同时也对得起这个文章的名字,本文就比较系统的讲一下浏览器Lexer中HTML编码处理的问题与XSS的html编码原理剖析。
0×01 解码过程总述
在开始XSS之前,我们如果不清楚编码解码的过程,将会对XSS造成非常大的困难,不懂得编码而乱插一气,如果你是自动化工具还好但是如果你是手动XSS,那么你可就遭殃了,运气好做出来,运气不好就怎么样也解决不了编码问题了。
了解编码过程首先从浏览器解析来讲吧
对浏览器解析HTML有过了解的同学,肯定是清楚浏览的的这些工具原理,一般来讲浏览器通过Lexer-Parser来解析生成Dom树然后再对CSS元素进行渲染,最后执行javascript(浏览器脚本),但是为什么要讲这一部分呢?原因就是这和解码的顺序是有关系的!
举一个简单的例子吧:在HTML(非XHTML)环境下如果你的xss输出点在这个字符串实际上只为了显示,而不执行,js代码的执行是放在HTML编码之后,而且必须位于可以执行的地方对么?大家想一下,如果放在标签内,没人指示执行JS代码,而且显示这个时候HTML解析器只是把它显示出来并不会执行(如果读者这里有点懵逼,那么请返回看0×01部分)。
然后为什么标签属性值的部分是可以执行的呢?很简单,因为onxxxx的函数都是时间处理函数,的确属于HTML标准的属性值,但是大家可以理解为这是JS特定函数或者特定功能的执行入口,那么在解析的时候,首先把HTML标签属性的值当作数据解析以后(解析HTML代码),然后交给JS引擎,然后执行。这样就可以得到JS的执行结果。
0×05 浏览器有趣的容错行为
我们接下来还是以一个标签为例。来总结一下浏览器是有多么强大的容错性。
对于这样一个标签,我们多多少少看起来还有点别扭。但是经过0×02的讲解,我相信大家脑子里应该是已经把它分解成了很多个token,而且,可以很轻易的分辨出这个tag是完全可以正常工作的。首先我们从开头一点一点来解释:
1. 在IE浏览器中,你可以在img中间加入NULL字符,而且还可以解析成功。
2. 在img和src还有src=s和title之间的两个边界,你完全可以用别的符号来替换边界
有图为证:
换成\t仍然可以解析成功,也就是并不是必须用空格或者\t的对吧。换成\n照样可以成功:
至于还有什么符号还可以,嗯哼,这就需要读者自己尝试了(什么难道你要自己一个一个试?)
1. 大家注意我在onerror和class参数之间没有空格或者其他分隔符,但是仍然可以执行成功,为什么?这个问题我在前面部分多次提到。
2. 属性的值的边界应该用什么来确定?单引号,双引号,反引号,还有呢?这里也是读者可以自己动手去尝试的。
0×06 结语
读者要明白,浏览器之间都是有差异的,尤其是IE和其他类型的浏览器,那么具体的差异的内容,大家可以fuzz一下,当然有一些资料推荐给大家使用的:《web application obfuscation》,《web之困》。本文简单谈一谈HTML编码这些问题就已经有了这么长的篇幅。如果有机会,笔者将在以后的文章中为大家讲解一下其他的编码部分(URL编码和JS编码)