前 言
之前发表了《一些BAT的XSS实例》系列五篇技术文章:《一些BAT的XSS实例(一)基础篇》《一些BAT的XSS实例(二)进阶篇》《一些BAT的XSS实例(三)中级篇》《一些BAT的XSS实例(四)高级篇》《一些BAT的XSS实例(五)最终篇》
很多朋友表示看得意犹未尽,问我还有没有续集。刚好最近有朋友发了我一个twitter上某大神出的题,我看了看感觉很有意思,所以改了下细节出了两道题来作为该系列的续集,进行下思路的分享。
先把设计的2个题目发出来
http://px1624.sinaapp.com/test/xsstest11/
http://px1624.sinaapp.com/test/xsstest12/
有兴趣的朋友,可以先不看文章,自己尝试的做一做题目,有答案的话可以发到我的邮箱 [email protected]并附上自己的ID,说不定下篇文章里面就会有你的绕过思路被收录了额。
首先是11题,先看下源码。
可以看到这道题的源码特别的简单,可能很多人对 location.pathname 不太熟悉,这个没关系,我们可以去翻下手册看看。 可以参考以下链接:
https://www.runoob.com/jsref/prop-loc-pathname.htmlhttps://developer.mozilla.org/zh-CN/docs/Web/API/Location/pathname
也就是说,这个location.pathname就是返回的url中domain后面的那部分路径。 这里肯定有人想,那很简单了,我直接在location.hash中写入xss代码,然后eval执行不就可以了么。不过仔细看就会发现,其实location.pathname 返回的是路径,既然是路径,那么肯定是不包含location.hash、location.search这些数据的。 既然这样不行,那么就只能是在URL路径里去构造了,但是测试后就会发现,只要你添加了数据,就会404无法访问。
原因很简单,因为不存在当前的目录,所以就会访问失败。所以这里我们的思路就是一定要让这个路径是合法的。
http://px1624.sinaapp.com/test/xsstest11/1111111111/../
所以需要向上面这种思路去构造,这样目录问题就合规了。 但是测试发现,这么写的话,URL中目录解析的优先级是比较高的,所以这么写去访问的话,会先进行目录解析,然后执行的还是之前的那个目录。 访问URL就会默认解析回去到/test/xsstest11/目录,这样的话,就还是不能写入任何字符进去,断点调试也可以证明这点。
所以有没有什么情况,解析的时候这个目录不是优先解析的呢?这里就要引出这道题的最关键的点了。那就是nginx对%2f的解析特性。 这个具体资料可以参考下面链接:
http://blog.phpdr.net/nginx-auto-decode.htmlhttps://stackoverflow.com/questions/8264239/nginx-unescapes-2f-to-a-forward-slash-how-can-i-stop-it
可以看到
nginx会自动把%2f解析成/ 斜线, 但是IIS和apache就不会
所以这个题就是考的这个特性(知识点),如果不知道这点(或者知道但是没有想到)的话,这个题基本上是做不出来的。 然后看看这个URL是不是nginx,方法很多,抓包其实就可以看到。
这样我们继续前面的思路。
http://px1624.sinaapp.com/test/xsstest11/1111111111/../ 用%2f代替后面的2个/ 符号 http://px1624.sinaapp.com/test/xsstest11/1111111111%2f..%2f
这时候再去访问,发现URL已经不会提前将其解析到/test/xsstest11/目录了,断点可以看到,已经成功写入了相关字符进去了。
下面只需要eval的时候javascript的语法OK就行了,就目前的情况看,语法是有明显错误的。这明显是不满足javascript语法的,所以我们需要构造一个满足条件的语法。
这里就是考验我们,如何去巧妙的利用 / 斜线符号,使得js语法完整,我们直接能想到3个最常见的思路。
思路1: //构造js注释 /*另一种js注释*/
思路2: /正则表达式/
思路3: 6/3 将斜线/作为除号去使用
我这里直接给出其中一种构造思路,利用js注释和正则表达式进行构造。 /*/..%2ftest/xsstest11/*/alert(11);/..%2f../
http://px1624.sinaapp.com/*/..%2ftest/xsstest11/*/alert(11);/..%2f../
为什么这样就可以了呢? 这里我大概给解释下吧。
首先 /*/..%2ftest/xsstest11/*/alert(11);/..%2f../这个目录要是存在的。 /*/..%2ftest/xsstest11/*/alert(11);/..%2f../目录,把%2f改成 / 斜线符号,
也就是 /*/../test/xsstest11/*/alert(11);/../../
然后 ../ 代表的是上级目录,所以这一堆目录跳来跳去,实际就是等于 /test/xsstest11/ 目录,这是一个真实存在的目录,所以不会404无法访问。 接着就是要满足javascript语法没问题。
/*/..%2ftest/xsstest11/*/alert(11);/..%2f../ 在javascript解析的时候, /*/..%2ftest/xsstest11/*/ 这一部分是被注释掉的,所以等于是 alert(11);/..%2f../
然后alert(11) 会被解析弹窗,后面的 /..%2f../ 会以一个正则表达式的形式进行返回。
如下图,这样看着更直观。
如果上面内容都消化掉了,下面接着再看看第12题,先看下源码。
可以看到,其实和第11题的源码是差不多的,但是多了个if的判断。测试后你就会发现,第11题的方法不能用了。
如果直接 /*/..%2ftest/xsstest12/*/alert(12);/..%2f../ 这样去套用的话,会发现是不行的,因为这个if过不了。
由于这里长度的限制,你会发现当前路径的前面基本上是写不了任何东西的了,不然这个if判断就不能成立。
所以需要思考其他构造的思路。
首先我们先把正确的路径构造出来,如下
http://px1624.sinaapp.com/test/xsstest12/alert(12)/..%2f
当然,上面提到过,这种情况下
/test/xsstest12/alert(12)/..%2f
这部分由于不符合javascript语法,肯定是会报错的。
所以需要对其进行构造,先将其进行拆解,构造如下
/test//xsstest12/alert(12)/..%2f
对比上面你会发现,就是加了1个 / 斜线的符号进去,这样做的目的是,/test/这是一个正则表达式,然后这样就可以把后面的 / 都作为除法运算符去处理。
所以前面的这些路径的语法就没有问题了,但是存在一个问题,就是后面这里有小数点,所以还是会语法错误。
所以需要继续进行构造 理论上来说,把后面的部分直接注释掉应该就可以了,像这样
/test//xsstest12/alert(12)//..%2f
但是测试发现,SAE在对于路径中有//的解析是有些不同的,因为这个payload我在本地搭建的环境,测试是没问题,但是在SAE中就不行,会因为解析不到目录从而404
测试后发现,在SAE中后面这个//还是会被解析成一个目录的路径,所以必须要再向上跳一层目录,也就是
/test//xsstest12/alert(12)//..%2f..%2f
好了,这样目录和语法问题就都OK了,不过又报错了xsstest12参数没定义,因为这个xsstest12在javascript的语法里,是以变量的形式存在的,所以需要去定义下。
所以构造如下
/test//xsstest12/alert(12);var xsstest12=1//..%2f..%2f
直接定义是肯定不行的,因为浏览器会将空格进行URL编码,然后这里js解析的时候,有了百分号就会语法错误。
这里我们可以用/**/代替空格,
所以就是/test//xsstest12/alert(12);var/**/xsstest12=1//..%2f..%2f
但是替换了之后,等于这里又多增加了2个目录进去,所以后面也需要再加两个 .. %2f 进去,
也就是 /test//xsstest12/alert(12);var/**/xsstest12=1//..%2f..%2f..%2f..%2f
试试最终的效果
http://px1624.sinaapp.com/test//xsstest12/alert(12);var/**/xsstest12=1//..%2f..%2f..%2f..%2f
由于12题是11题的升级版,所以这个payload同样也是适用于11题的。
总 结
通过这2个案例可以看到,在我们的解法思路中,用到了nginx的解析特性、浏览器中目录的解析规则、javascript的注释语句、运算符、正则表达式等知识。以及用到了断点调试、控制台分析、本地代码映射等方法。
可以看到,其实这里并没有什么奇淫的技巧,或者特殊的bypass姿势之类的东西,所用到的都是一些前端基础知识,配合一些基本调试方法而已。
所以我觉得,大家在绕过XSS的时候,主要还是思路要对,同时基础知识要过硬,这样才能在XSS漏洞这方面做到“人挡杀人,佛挡杀佛”的操作。
此题严格意义上来说,并不是BAT的实例,但是也放在了这个系列中了,因为个人觉得,这也算是比较经典的案例了。
尾 巴
截至发稿前,还有几个人也给出了自己的答案,我这里选了几个比较好的,贴出来供大家学习。
ID:Huuuuu 第12题(目前最短的解)
http://px1624.sinaapp.com/test//xsstest12/alert(12);var[xsstest12]=/..%2f/
其中var[xsstest12]这种写法是js中es6里面的解构赋值,有兴趣的可以阅读下方参考链接自行学习,这里就不再过多叙述了。https://es6.ruanyifeng.com/#docs/destructuring
ID:lala第11题(目前最短的解)
http://px1624.sinaapp.com/test/;alert(11)//..%2f../xsstest11/
这个构造思路也是利用注释符//把后面全部注释掉了,再构造合法路径即可。
第10题(目前最短的解)
http://px1624.sinaapp.com/test/xsstest10/?px=`}\%27-{a:`}-alert(1)//${`${`<!--<script>
将模板字符串放在了相对的最外层,这样构造的时候,很多由于字符导致的语法问题就可以基本无视了,遇到复合js模板构造的时候,此构造思路很值得学习。
第3题(比较不同的构造思路),用了两次注释符配合构造。
http://px1624.sinaapp.com/test/xsstest3/?px=*/{alert(1);';/*';//
这个思路和第7题 ID:zeddy的那个思路很像。
http://px1624.sinaapp.com/test/xsstest7/?px=%3C!--%3Cscript%20`)/*\%27%0aalert(1)%0aalert(`*///
当然,所有1~12题的构造思路并非唯一,也可欢迎其他人将自己更好更有意思的答案,发到我的邮箱 [email protected]并附上自己的ID,说不定下篇文章里面就会有你的绕过思路被收录了额。 目前共设计有16道题,修改下方链接的xsstest1为xsstest1~xsstest16即可。