从 XSS Payload 学习浏览器解码
xss payload
1.<a href="%6a%61%76%61%73%63%72%69%70%74:%61%6c%65%72%74%28%31%29">1</a>
2.<a href="javascript:%61%6c%65%72%74%28%32%29">2</a>
3.<a href="javascript%3aalert(3)">3</a>
4.<div><img src=x οnerrοr=alert(4)></div>
5.<textarea><script>alert(5)</script></textarea>
6.<textarea><script>alert(6)</script></textarea>
7.<button οnclick="confirm('7');">Button</button>
8.<button οnclick="confirm('8\u0027);">Button</button>
9.<script>alert(9);</script>
10.<script>\u0061\u006c\u0065\u0072\u0074(10);</script>
11.<script>\u0061\u006c\u0065\u0072\u0074\u0028\u0031\u0031\u0029</script>
12.<script>\u0061\u006c\u0065\u0072\u0074(\u0031\u0032)</script>
13.<script>alert('13\u0027)</script>
14.<script>alert('14\u000a')</script>
15.<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)">15</a>
基础部分(前六个)
第一个,很明显没有执行
原因是编码部分是URL encoded "javascript:alert(1)",里面没有HTML编码内容,不考虑,其中href内部是URL,于是直接丢给URL模块处理,但是协议无法识别(即被编码的javascript:
),解码失败,不会被执行。
URL规定协议,用户名,密码都必须是ASCII,所以编码就无效。
第二个,经过用户交互之后是可以实现的
解析流程:
先HTML解码,得到<a href="javascript:%61%6c%65%72%74%28%32%29">,href中为URL,URL模块可识别为javascript
协议,进行URL解码,得到<a href="javascript:alert(2)">,由于是javascript协议,解码完给JS模块处理,于是被执行
第三个,经过测试,也是不行的
原因是编码部分是URL encoded `:`,里面没有HTML编码内容,不考虑,其中href内部是URL,于是直接丢给URL模块处理,但是协议无法识别,解码失败,不会被执行。
第四个,经过测试,也是不成功的
原因是这里对<>进行了实体编码,这里包含了HTML编码内容,反过来以开发者的角度思考,HTML编码就是为了显示这些特殊字符,而不干扰正常的DOM解析,所以这里面的内容不会变成一个img元素,也不会被执行。从HTML解析机制看,在读取<div>
之后进入数据状态,<
会被HTML解码,但不会进入标签开始状态,当然也就不会创建img
元素,也就不会执行。
第五个,经过交互,也是不能实现的
原因是这里依然是对<>进行了实体编码,而<textarea>是RCDATA元素(RCDATA elements),可以容纳文本和字符引用,注意不能容纳其他元素,HTML解码得到<textarea><script>alert(5)</script></textarea>于是直接显示,RCDATA`元素(RCDATA elements)包括`textarea`和`title`
第六个,经过交互,也是不能实现的
原因是<textarea>是RCDATA元素(RCDATA elements),可以容纳文本和字符引用,注意不能容纳其他元素,HTML解码得到<textarea><script>alert(5)</script></textarea>于是直接显示
高级部分
第七个,经过交互测试,是可以的
原因是,这里对 ` ' `进行了实体编码,这里onclick中为标签的属性值(类比2中的href),会被HTML解码,得到<button οnclick="confirm('7');">Button</button>然后被执行。
第八个,经过交互,是不可以的
原因是onclick中的值会交给JS处理,在JS中只有字符串和标识符能用Unicode表示,'显然不行,JS执行失败
第九个,也是不行的
原因是script属于原始文本元素(Raw text elements),只可以容纳文本,注意没有字符引用,于是直接由JS处理,JS也认不出来,执行失败。原始文本元素(Raw text elements)有<script>和<style>
第十个,经过测试是可以的
原因是函数名alert
属于标识符,直接被JS执行
第十一个,经过测试,是不可以的
原因是在JS中只有字符串和标识符能用Unicode表示
第十二个,经过测试,也是不可以的
原因是这里\u0031\u0032
在解码的时候会被解码为字符串12
,注意是字符串,不是数字,文字显然是需要引号的,JS执行失败。
第十三个,经过测试是不可以的
原因是在JS中只有字符串和标识符能用Unicode表示,'显然不行,JS执行失败
第十四个,经过测试是可以的
原因是\u000a在JavaScript里是换行,就是\n,直接执行,相当于在源码里直接按一下回车键,后面的代码都换行了,这个无关紧要。
第十五个,经过交互,是可以的
原因是首先进行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)">15</a>,然后在href中由URL模块处理,解码得到<a href="javascript:\u0061\u006c\u0065\u0072\u0074(15)">15</a>,最后经过Unicode解码得到<a href="javascript:alert(15)">15</a>,交互后可执行。