原始paylaod
javascript:alert(15)
unicode编码函数名alert
javascript:\u0061\u006c\u0065\u0072\u0074(15)
url编码unicode编码部分
javascript:%5c%75%30%30%36%31%5c%75%30%30%36%63%5c%75%30%30%36%35%5c%75%30%30%37%32%5c%75%30%30%37%34(15)
最后在html编码全部
<a href="javascript:%5c%75%30%30%36%31%5c%75%30%30%36%63%5c%75%30%30%36%35%5c%75%30%30%37%32%5c%75%30%30%37%34(15)"></a>
回顾编码过程
payload->unicode编码处理->url编码处理->html编码处理
payload的效果
随便个html文档
<html>
<head>
<title>
测试用
</title>
</head>
<body>
<h1>what a fuck shit!</h1>
<hr>
<a href="javascript:%5c%75%30%30%36%31%5c%75%30%30%36%63%5c%75%30%30%36%35%5c%75%30%30%37%32%5c%75%30%30%37%34(15)"></a>
<br/>
</body>
</html>
点我后的效果
分析下浏览器解码过程
<a href="javascript:%5c%75%30%30%36%31%5c%75%30%30%36%63%5c%75%30%30%36%35%5c%75%30%30%37%32%5c%75%30%30%37%34(15)"></a>
解码过程
-
首先HTML解析器来对这段html文档进行词法解析。字符引用(&#x..实体编号)被解码。
解码后:<a href="javascript:%5c%75%30%30%36%31%5c%75%30%30%36%63%5c%75%30%30%36%35%5c%75%30%30%37%32%5c%75%30%30%37%34(15)">点我</a>
-
在html词法解析完成后,然后URL解析器开始对href值进行URL解码
解码后:<a href="javascript:\u0061\u006c\u0065\u0072\u0074(15)">点我</a>
-
由于是javascript协议资源,javascript引擎对unicode编码的字符串进行解码,最终变成原始payload形式,js语句执行
解码后:<a href="javascript:alert(15)">点我</a>
知识来源
http://bobao.360.cn/learning/detail/292.html
html解析的几个点:
- 解析器在解析字符引用(实体名称、实体编号:“&开头的编码”)后不会转换到“标签开始状态”。正因为如此,就不会建立新标签。因此,xss能够利用字符实体编码来转义用户输入的数据,从而确保用户输入的数据只能被解析成“数据”,而不转成html标签。
URL解析的几个点:
- URL资源类型必须是ASCII字母(U+0041-U+005A || U+0061-U+007A),不然就会进入“无类型”状态。例如,不能对协议类型进行任何的编码操作,不然URL解析器会认为它无类型。该原则对协议后面的“:”(冒号)同样适用。(不能对“javascript:”进行编码)
- URL编码过程使用UTF-8编码类型来编码每一个字符。
JS解析的几个点可以记下:
- JavaScript解析器会对Unicode转义序列和Hex转义序列的解码
- 转义序列放在JS的3个部分:字符串中,标识符名称中和控制字符中
- Unicode转义序列出现在JS字符串中:当Unicode转义序列存在于字符串中时,它只会被解释为正规字符,而不是单引号,双引号或者换行符这些能够打破字符串上下文的字符。因此,Unicode转义序列将永远不会破环字符串上下文,因为它们只能被解释成字符串常量。同理出现在控制字符中
- Unicode转义序列出现在JS标识符名称中(函数名,属性名)时,它会被解码并解释为标识符名称的一部分。
- Unicode转义序列只有在JS标识符名称里不被当作字符串,也只有在标识符名称里的编码字符能够被正常的解析。