【prompt(1) to win】 Level 2 - frowny face



题目

function escape(input) {
    //                      v-- frowny face
    input = input.replace(/[=(]/g, '');

    // ok seriously, disallows equal signs and open parenthesis
    return input;
}     

解题报告

正则把输入内容中所有 =( 过滤了。

= 被过滤了不是什么大问题,XSS 直接放在 <script> 标签一样可以执行,关键是 ( 被过略了。

此处可以利用 <svg> 标签【会对标签中的内容优先做实体编码解析】的原理进行绕过。

在网页编码中,以 &#ASCII; 称为实体编码,其中 ASCII 可以用十进制或十六进制表示。如 ( 的 ASCII 编码为 40 (或十六进制 0x28) ,那么 &#40;&#x28; 就是 ( 的实体编码。

因此这题可构造这样的 payload 实现绕过:<svg><script>prompt&#40;1)</script>

它的工作原理为:

  • 在 HTML 中,原本 <script> 标签属于 Raw text elements ,其内部文本遵循着不转义的规则。
  • 但是 <svg> 标签属于 Foreign Elements ,即使在HTML语境下也不会受到 HTML 规则的影响,而是遵循 <svg> 自身的解析规则。
  • <svg> 直接继承自 XML,一般情况下,它的解析规则为:除非被 CDATA 包围,否则实体编码都会被转义。

这题也可以利用 javascript 的 eval 函数实现绕过,payload 如下:

<script>eval.call`${'prompt\x281)'}`</script>


答案下载


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