上次发了篇《强防御下的XSS绕过思路》的文章,有很多人私信问我,能不能来一些XSS绕过实例分析,这里我选了些N年前的BAT的XSS实例来聊聊构造和绕过思路。当然这些实例,都是已经公开并且修补完毕的,我这里是只是以此为原型,并做了一定的修改,进行了一些XSS题目的设计而已。
先一次性把17道题发出来(xsstest1~xsstest17自行修改)。
大部分的题都是一题多解,尽量给出多种思路,或者最短的解法。)
http://px1624.sinaapp.com/test/xsstest1/
有兴趣的朋友,可以先不看文章,自己尝试的做一做题目,有答案的话可以发到我的邮箱 [email protected]并附上自己的ID,说不定下篇文章里面就会有你的绕过思路被收录了额。
◇1、 首先看第一题,源码如下图,只有短短的几行代码而已
这个题目看似简单,不过没有js基础的人却不容易做出来。熟悉js的人,可能一眼就能看出答案了。然后用传统的测试方法去测试的话,比如给一定的字符输入去看输出点,这样的方法也是不行的。
有人看到代码里的location.hash,然后就会像如下方式去测试,结果就会发现不管你输入啥东西,都没有任何的输出点。如下图:
这是因为这道题是一个DOMXSS,用这样的调试方法是不行的,如果要调试的话,就要用到js的断点调试。
具体断点调试的方法可以参考这个文章 https://www.toolmao.com/342.html
1.2 这里我给出3种比较常用的方法
1.2.1 第一种方法:观察法,就是直接看代码的逻辑,然后构造即可。
看代码逻辑核心就是这句
setTimeout("aa('"+x+"')",100);
然后可以看到,我们只需要构造出下面的代码,就可以执行XSS。
setTimeout("aa('"+"',alert(1),'"+"')",100);
具体可以在控制台调试
那么问题就变得很简单了,直接替换一下x就等于
"',alert(1),'"
就行了。由于双引号表示的是字符串,所以x的内容就是
',alert(1),'
即可,那么我们去试试
1.2.2 第二种方法:js断点调试。一步步的去输入不同的内容,断点调试看代码输出逻辑。
先用谷歌浏览器F12,然后给如下位置设置断点。
任意输出字符串,断点调试,查看输出代码逻辑。鼠标放变量上,就可以看到变量当前的值。
可视化调试的话,只需要保证js的语法正确就可以了。
这种方法对于代码高度压缩,或者逻辑比较复杂的情况下,还是特别方便的。
1.2.3 第三种方法,故意输出特殊字符,导致js语法错误的调试。
如下图,输入点我故意输入一些特殊字符,然后Console发现有错误。
然后点击进去查看这个错误,可以看到直接进入了关键函数的语义解析状态。然后这里就很简单了,直接对照自己的输入内容,然后去构造下就可以了。
比如下面这样
这个题的答案很多,不过貌似最短的就是
#',alert(1),'或者#');alert(1)//
这样了。
很多人盲目的迷恋fuzz,所以以此为开头主要是为了给初学者分享一些实用的测试方法,以及说明一下看代码的重要性,这点在后面的题目里体现的淋漓尽致。
◇2、第一题还是比较简单的,甚至有些人直接盲测都给测出来了,下面看看第二题。
很多人习惯看到个按钮就去点下抓包啥的,那么这样只会被调戏而已。
第二题的源码如下
可以看到,我这里的第一题和第二题都是没有向服务器进行任何请求的,所以建议大家在测XSS的时候,一定要先看下代码逻辑,别一上来就在那瞎点瞎抓包。
第二题的代码逻辑可以看到,首先获取了location.search的内容,然后以&进行了分割获取变量,然后将变量的前2个进行了传值,赋值到了aa函数里。最终aa函数执行了
$("#xx")[x]($("#xx")[y]());
其中是对 id为xx的标签进行了两次dom操作,第一次是读取,第二次是写入。也就是代码中的div,然后div中写了一个img的XSS代码,但是被html实体编码了。
2.1 这里我直接给出答案,只需要执行
$("#xx")["html"]($("#xx")["text"]());
所以直接给赋值就行了
这里解释一下为什么会这样,在控制台里测试下,就知道了。
可以看到,text()函数会把html编码后的代码给还原回来,这个其实也是这个题的考点。也是很多程序员的很容易踩的一个坑。
这里的答案,第二个参数必须为text,第一个可以是很多,比如html、append、constructor、appendTo、insertBefore等等,很多能执行dom操作的函数都可以。
以前有人总结过mxss问题,个人觉得可能有一部分mxss的问题,就是因此产生的吧。mXSS攻击的成因及常见种类 http://mottoin.com/detail/3430.html
◇3、第二题虽然这个技术点很多人是并不知道的,但是因为出题的代码我写的比较简单易懂,所以还是有些人直接盲测给测出来了,下面看看第三题。代码如下:
主要考察的是同步输出的时候的构造思路,这里对输出点做了html编码的过滤,防止可以直接写入script标签的这种行为。
当然php代码做题的人是看不到的,所以他们只能看到前端的源码,如下:
可以看到,第三题的这个代码并没有location.hash或者location.search,那么肯定就需要猜变量了,作为出题的人肯定不会出那种完全不给线索猜不到题,所以变量肯定就是px或者xss呗,测试下发现变量就是px
很多人猜到了变量,就觉得这很简单啊,然后构造了一番就发现,怎么构造貌似都不行。因为是2个点同步输出的,所以一般思路的构造,会导致不是前面语法出错,就是后面语法不行。很多人使出洪荒之力,耗费了很久时间,还是发现不能成功执行XSS。
这里我直接给出思路,这里主要考察的是运算符的使用。
这样语法就是同步正确的了。
当然,这里不光是乘号,比如加号
还有减号
或者其他运算符也都是可以的
具体JavaScript运算符可以参考这里
https://www.w3school.com.cn/js/js_operators.asp
◇4、下面来看看第四题:
这个题属于第3题的升级,蛮多人就卡到这里过不去了。具体代码如下
可以看到,直接把这里提到的所有运算符都给过滤掉了。
https://www.w3school.com.cn/js/js_operators.asp
那么这个时候运算符全部被过滤了,又应该怎么进行构造,从而绕过限制呢?
由于篇幅原因,下篇文章我会为大家继续解析,欢迎大家关注微信公众号:不忘初心px1624
尾 巴
目前最新情况是,大部分的人做出来了1~3题,然后卡到第4题这里,还有蛮多人做出来了1~5题,卡到了第6题。其实卡住了的话,是可以跳着去做其他题的,因为整体来看,第6题应该是最难的了。
ID:gainover 解出了全部10题。并且是目前唯一解出第6题的人,以及第4题给出了目前最短payload的解法(13个字符)。
ID:香草 解出了1~4题,以及7~10题。并且给出了通杀9和10的payload。
ID:p1g3、zeddy、Huuuuu 、w8ay 解出了1~5题。p1g3、zeddy、Huuuuu 还做出来了7~8题,但是三人的第8题给的答案,都不能过xss filter。
ID:w8ay、Huuuuu第4题给出了不同于其他人的解法。
ID:zeddy第7题给出了不同于其他人的构造思路。
其他已经做出未被提及的,可以将自己的答案和ID发我qq邮箱:px1624.qq.com