前言

之前发了《一些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设计的那个原题,因为我尝试做了些改动,发现都不能很好的达到预期的效果。另外3个是,根据香草设计的题的解题思路,做了些改动。

有兴趣的朋友,可以先不看文章,自己尝试的做一做题目,有答案的话可以发到我的邮箱 px1624@qq.com 并附上自己的ID,说不定下篇文章里面就会有你的绕过思路被收录了额。

先来看看第14题:

还是老规矩,先看下源码。

一共是有3个函数,前面2个分别是url编码和url解码的功能,没啥多大意义,这里主要看下第三个函数。

看完后,可能大家很快的就会给出一个payload如下:

http://px1624.sinaapp.com/test/xsstest14/?returnurl=javascript:alert(1)

然后去测试发现,并不能弹窗,会报错下图这个。

这时可能就比较懵圈了,所以要去了解opener的相关知识,可以参考这里:
https://developer.mozilla.org/zh-CN/docs/Web/API/Window/opener

在了解了opener的相关知识后就知道,直接去在这个页面去构造的话,压根就不存被打开窗口的页面,那么opener肯定就是null,所以就会报错这个。

那么我们首先思路肯定就是,需要去构造一个页面去打开这个14题的页面,这样才会存在opener,然后你可能会去这么写。

<input type="button" value="test" onclick="window.open('http://px1624.sinaapp.com/test/xsstest14/?returnurl=javascript:alert(1)')" />

然后测试后发现,并没有成功,报错这个了。

因为这时候的opener的页面肯定是你自己的,那么opener.location.href就会存在跨域问题。

具体流程如下:

你的页面 --> window.open("http://px1624.sinaapp.com/") --> opener.location.href (跨域报错)

所以若要解决这个问题,我们需要思路变成这样。

你的页面 --> window.open("http://px1624.sinaapp.com/") --> (把opener变成目标域名页面) -->  opener.location.href (成功弹窗)

那么如何把opener变成目标域名页面呢?

要达到这个目的,我们就需要open后立马location跳转走,跳转到目标域名的页面,这样就可以解决跨域的问题了。

由于opener 是一个 window 的引用,而新窗口的window.open打开操作,会有窗口创建、有内容渲染,时间上会比location要慢的。所以等到新窗口去调用opener.location.href 的时候, opener 的location 已经变了,从你的页面变为了目标域名的页面,这样就不会因为跨域导致报错了。

简单来说,就是打了个时间差,你可以像下面这么理解。

考试的时候,有监考老师在监考,你趁着他没注意的时候,偷偷的瞄了一眼答案。然后他可能预估打你会作弊,但是当他转身去看你的这个过程中,是需要时间的,这个时间你已经偷偷的把答案瞄到了。这样他转身是需要一系列的动作过程的,肯定是比你瞄一眼答案用的时间久,这样就打了个时间差成功作弊了。

这里我直接给出一个,比较具体的payload代码:

这里有一点要注意,window.open和location的url,一定要用https不能用http,不然也会存在跨域问题。我当时在做这个题的时候,就是犯了这个疏忽,然后payload构造好,就一直没成功。

这里可能有人或许会问,为啥payload要写成这么麻烦,还要去点击呢?
直接执行open_win函数不就行了么?

其实是因为window.open函数的原因,这个函数如果自动去执行的话,浏览器是会直接进行拦截的。不然你打开一个页面,给你直接弹100个广告出来,你是一种什么感受,哈哈。

但是浏览器是不会拦截用户点击触发的window.open的,这里的机制主要是判断是否有用户操作。所以我们只需要把整个页面 设置为 可点击,所以将button的css属性设置成了整个页面。

将以下payload保存为html,打开html文件,点击页面任意位置即可触发。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script>
function open_win() {
 window.open("https://px1624.sinaapp.com/test/xsstest14/");
 location="https://px1624.sinaapp.com/test/xsstest14/?returnurl=javascript:alert(14)";
}
</script>
</head>
<body>
<input type="button" value="点击任意位置" onclick="open_win()" style="width:2000px;height:1000px;background-color:white;border:none">
</body>
</html>

效果如下图,整个页面任意位置点击触发。

下面看看第13题,先看下源码。

可以看到这道题的源码特别的简单,大概意思就是判断如果没有传入参数sss,就跳转到px.php这个文件。
而在px.php这里,你发现可以写入字符,而且可以解析标签,然后感觉这不是很简单啊,但是测试后发现,长度限制在了7个字符,貌似啥也干不了。

这也是这题目设计的第一个知识点(坑),如果不注意看源码,直接在这个跳转页面去测试的话,那可以说就走远了,这种我在前面的题目设计中,也都有用过。
可能有的人说,这种知识点(坑)没啥意义,谁会注意不到呢?你还真别说,还真有蛮多人就卡在这里直接GG思密达了。

下面继续说思路,从这个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

具体后续的分析,文章篇幅有限,还是放在后续的第八篇里专门讲下吧,有兴趣的朋友,可以参考上面的CSP相关知识,自己再去尝试下能不能成功。

总结:
在上面的解法思路中,用到了opener和location的一些特性等。可以看到,其实主要还是思路要对,同时基础知识要过硬,这样才能在XSS漏洞这方面做到“人挡杀人,佛挡杀佛”的操作。

尾巴:
截至发稿前,仅有几个人给出了部分答案。

目前共设计有16道题,修改下方链接的xsstest1为xsstest1~xsstest16即可。
http://px1624.sinaapp.com/test/xsstest1/

点击收藏 | 1 关注 | 1
  • 动动手指,沙发就是你的了!
登录 后跟帖