sir

0CTF blog bypass csp nonce

赛后复现的一个题,用到了很多技巧,复现的过程收获很大,这篇文章从一个新手的角度来分析这道xss题目。

网站有几个功能

网站的csp规则为:

很有意思的是这里用了两个csp规则,csp1和csp2都有

两个CSP分开写,是同时生效并且单独生效的,也就是与的关系。

换个说法就是,strict-dynamic 表明我们可以运行动态生成的js, 假设我们通过动态生成script标签的方式(dom xss),成功绕过了第二个CSP,但我们引入了<script src="hacker.website">,就会被第一条CSP拦截,很有趣的技巧。

nonce的绕过我们一般是去寻找一些dom xss的点

我们再查看文章链接的地方发现网站引入了第四个js: article.js

很明显的dom xss

网站部分源码为:

获取id为effect即input输入框的值,effects变量是在config.js中定义的,

即根据我们输入的内容选择对应的js特效,但是这里输入值并没有白名单过滤(不要相信用户的输入),导致我们构造恶意的js内容

思路:

  1. 我们首先需要覆盖掉config.js
    , "><script a= 利用标签悬挂攻击我们可以覆盖掉config.js(因为nonce是动态生成的,获取到管理员的nonce也没用)

  2. 如果我们可以覆盖effects变量,那我们就可以向body注入标签了,这里需要一点小trick。

构造也比较巧妙

我们如果插入这个,就可以成功覆盖config.js和effects的内容

image.png

effect参数这里服务端限制只能写入70个字节,bypass csp1的unsafe-inline的很多方法都用不了了。

大佬给出的payload:

还是可以通过xhr访问站内的链接/flag
,将flag存放在name窗口中,那么我们如何将flag传出来呢?

login?next=这个点可以存在一个任意跳转,通过这个点,我们可以绕过submit的限制(submit的maxlength是前台限制,可以随便跳转

这个漏洞有什么用呢? 无法写js,没法传出document对象

这里我们再次用到一个Tricks,一个特殊的跨域操作

http://www.cnblogs.com/zichi/p/4620656.html

这里用到了一个特殊的特性,就是window.name不跟随域变化而变化,通过window.name我们可以缓存原本的数据。

我们在我们的vps上挂一个html

直接弹出name是没有任何内容的,但是我们通过该网站login?next调到我们的服务器上时会有什么变化呢,我们访问:http://202.120.7.197:8090/login?next=http://lj.s7star.cn/xss/name.html

成功弹框前一个网页的name数据

image.png

那么我们如何将我们http://202.120.7.197:8090/article/3879 网站的name发出来呢?

我们再我们vps上再挂个html:

我们添加了一个iframe指向我们的文章,因为该网站并没有设置x-frame-options选项,因此可以被嵌入,因为浏览器会保存cookie,因此iframe里面的页面无需登陆就可以访问到。

在我们的vps网站上测试,虽然因为同源策略限制我们无法访问iframe里面的dom,也无法直接获取iframe的name值,但我们可以改变window.href调到我们的首页来,此时iframe已经和我们的vps同源,我们就可以将name带出来并且访问成功了.

知道怎么带出来后我们就可以顺利写出poc了.

上面这段就不难理解了,先用iframe指向含有xss的文章链接,通过location.href跳到我们的vps上面来,并将name带出来,获取iframe的name窗口值并发送到我们监听的端口上。

最后提交我们的链接:

image.png

参考:

https://lorexxar.cn/2018/04/05/0ctf2018-blog/

https://blog.cal1.cn/post/0CTF%202018%20Quals%20Bl0g%20writeup

喜欢 0