HCTF2017过去了已经快要2个半月了…时间飞逝,临到年关才有空提笔写写去年的得失,断断续续居然写了快半个月,其实很多故事都没什么特别的,还记得去年提笔写HCTF2016的时候,只不过是因为学校的事情有些抑郁,深夜随便写写吐槽一下,也算消解了很多无用的情绪。没想到的是,居然有很多人看到了那篇在我看来很无趣的深夜吐槽,给了我们很多鼓励,这里也谢谢那些愿意支持我们的人,现在的Vidar真的来之不易…
下面就随便聊聊天,聊聊HCTF2017,聊聊我去年的一些得失,也算是给这个技术博客增添一些个人情绪色彩。
聊聊协会
在开始聊HCTF之前,还是想聊聊协会的事情,2017年的Vidar-Team经历很多挫折,先是我们协会自己的实验室被回收做学院新引进的教授办公室,我们失去了使用了超过8、9年的协会办公室,在经历了超过4个月的流浪(没有固定的地点)之后,我们终于争取了一个新建的小房间,整个历时超过一个学期…最后,在通信学院总算是争取了一个小房间落脚。
在经历了通信学院在整个去年的反复无常之后,我们选择寻找计算机学院作为我们的出路,同时也开始将分割成3部分(通信学院、计算机学院、网安学院)的协会整合起来,以Vidar信息安全实验室为标识,开始向校级社团转型。
当然,转型当然不是一帆风顺的,除开计算机学院以外,通信学院和网安学院在这件事情上一直秉持为自己学院好的原则,以至于通信学院一再要求我们脱离计算机学院,脱离Vidar,以杭电通信学院的名号自持,而网安学院呢,直接脱离管制,解散了网安学院,改为扶持自己的协会(赛博协会),时间走到今天仍然没有什么定论,而我们知道的是,Vidar-Team会一直坚持下去,我们都在为之不断做着努力…
聊回HCTF
赛前
说到HCTF,去年我们在办HCTF上吃了很大的亏,所以我们今年在很早的时候就开始筹备HCTF2017,提前接触计算机学院作为依托,这次HCTF是依托于计算机学院的,以计算机学院作为法人代表。
紧接着开始沟通赞助方,全年和赛宁的合作遇到很多问题,幸运的是,今年从一个朋友那里接触到了现在的赞助方Veda,经过了很多轮的沟通,我们答应了一部分宣传的条件(细节就不谈了),在保留赞助额度的情况下,保留了最大限度的自主权,虽然很艰难,但是我们还是迈出了这一步。
在敲定赞助之后,我们决定办一场完全自主的HCTF,在比赛筹备前,我们首先需要敲定各种规则,测试效果比较好的雷打不动的规则包括反作弊规则和动态分数规则,需要好好思考的就是神秘规则问题。
说起神秘规则,从2015年开始,HCTF开始寻找一些超出CTF本身的东西,在不影响公平公正的前提下,寻找一些更有趣的玩法,让参加比赛的人,也能意识到,除了CTF本身,HCTF更有一种Hack game的感觉。
从2015年的金币制,到2016年的下层制,其实2016年的规则已经演化的相对成熟,但是我们想要增加更多多元化的东西,比如,假设一个队伍只有Web手,那么他们也能愉快的做题。
于是闯关制度就诞生了,将分类分为Web、Bin两个大方向,然后加入部分misc和密码学题目到Extra中(之所以叫做Extra,是因为这两个方向的题目我们没能力出到Web和Bin级别,况且misc本身就是一些在生活中遇到的一些有趣的东西,趣味可能更大于技术),然后每个方向分多层下层。
在赛后回顾这个规则的时候发现,这个规则的设定很不成功,出现了很多问题,由于将题目分开之后,每个方向的题目大约只有10题左右,所以每层题目的每个题目的难易程度以及数量,对开层的难度都产生了巨大的影响,而且由于实现没有对所有题目都全知全解,并不知道在二层放了一个需要长时间刷的脚本题目,在Web的2->3层出现了巨大的问题。幸运的是,起码没有造成不可挽回的错误。
再敲定规则之后,我们进一步确定了今年要在ctftime上办比赛的想法,所以从比赛筹备前就开始决定全英文的出题方式,没想到的是,学弟的口袋精灵题目因为题目太大无法切换到全英文,所以只能硬着头皮上中文,再加上题目本身的特殊,所以导致整个比赛对外国选手及其不友好,几乎所有的外国队伍在level2之后放弃了比赛,这也是比赛中很严重的一个败笔。
除了神秘规则以外,有些值得一提的就是反作弊系统,由于准备周期不足,所以原本有一些思路开始的Web题目反作弊,只能被迫押后,沿用了旧的反作弊系统,整个比赛中,我们只准备了有限份的bin,再加上不希望封禁账号通过注册小号来解除封禁的初衷,我们仍然在比赛开始之后关闭了注册。
ps:这里还出了插曲,由于ctftime没有即时同步的功能,我们没能把这个信息同步到ctftime,导致很大一批外国朋友没能参加到比赛中。
在确定了一切之后,首先就是HCTF平台的开发,比较幸运的是,我们找到了一个学弟算是比较专业的开发,在初赛前几个月开始,由学弟@Sora以及@Aklis两个人完成了HCTF平台的开发,并在比赛期间负责平台的维护。
ps:比赛过程中遇到很多问题,基本都是由sora以及ak维护解决的。
除了平台以外,剩下的大部分精力就会花费在题目上面,说到题目上来,其实有很多值得一说的东西,从2017年开始,或许是ctf打了太多年,见了太多题目,我逐渐开始思考一个优秀的ctf题目应该给人们带来什么?
这里推荐一篇@火日师傅曾经写的wphttps://pwnhub.cn/media/writeup/114/6337cb8f-76ce-4949-8ac5-70aeee34f7a5_c95a4129.pdf
在wp的结尾,火日师傅提到了一些关于ctf的东西,我觉得,ctf这种形式越来越火,但是真正会出题的比赛并不多,一道优秀的ctf题目,应该能够给我带来一些特别的东西。
- 一个很棒的渗透思路
- 一个很特别的利用思路
- 一个没接触过的知识点
从这样的出发点出发,然后再加上一些一定不能触碰的雷区,这里也是火日师傅提到的,不要出弱智知识点,不设置无意义的障碍(就比如,一个很难的注入题目,再好不容易绕过注入点之后发现后面又是一长串流程)、给予合适的题目引导,不要让题目让别人看起来莫名其妙,毫无意义。
在纠结了很久之后,我挑了3个我在2017年的学习中遇到的比较有意思的东西,babycrack是来自一次对chrome的恶意拓展的逆向经历,当时的那个恶意扩展把恶意代码放在图片里,通过类似lsb的加密方式把代码放在图片里,扩展中的代码只包括对图片的解码和执行,因此这样的方式也在一定程度上防止了恶意代码被发现,我觉得是一个很有趣的东西,所以我就出了babycrack,但是由于中间的逻辑混淆在完成混淆的时候比较复杂,导致其中的一个条件写反了,成了永真条件,也导致了多解的问题,这点很抱歉。
A World Restored & A World Restored Again是一个我看过的uber案例,很有意思的一个漏洞,特别简单,但是很有意思。当你在一个站点发现了一个任意url挑战漏洞,你会不会深究这个跳转是怎么实现的呢?
在很多现在的站点,为了前台流程比较符合人类习惯,一般都会在挑战前有一个提示,为了能有这样的一个提示,跳转只能通过js来完成,假设这里过滤不严谨,那么就会产生dom xss,有趣的是,因为像这样的o2auth的站点我第一次写,无意中写了一个token泄露的漏洞,于是again就上线了,很有趣的样子。
最后的Deserted place这个题目是来源于我曾经在研究csp的时候,接触到的一种很有趣的攻击方式SOME,在实际场景中特别少见,但是利用方式却又很有趣,所以我就完成了这样一个题目。
虽然整个题目的难度不高,但是我希望我的题目给做题目的人带来了一些东西,比做题更多的一些东西。
就这样,比赛中虽然出现了很多意外,但是初赛还是顺利的完成了。
下面公布一些没公开的数据吧。
初赛数据
初赛题目一共28题,分别为Web 12题,Bin 11题,Extra 5题。除Bin第5层的题目以外,所有的题目均有队伍成功完成。
初赛报名队伍共1013只,参加比赛并获得分数的队伍超过540只。
RedBud在开赛1小时第一个进入Bin level2,FFF-PKYou在开赛22小时第一个进入Bin level4.
ROIS在开赛3个半小时第一个进入Web第三层,Nu1L在开赛16.5小时第一个进入Web第四层,ROIS在开赛21个小时第一个进入Web level5,同样的,ROIS也是第一个触发了补偿机制进入Bin level3。
在比赛中,ROIS在开赛25小时完成了Web leval1-4所有题目,并在开赛38小时ak所有Web题,Orz
在比赛结束后,我们同样收集了一部分选手的意见。
比赛时长这个问题纠结了很久,36小时和48小时都有他的道理,所幸的是大部分人还是比较认可48小时制
争议比较大的一点,我们内部也在讨论这个问题。
平台问题在赛前争议比较大,但是从结果看来并不影响比赛
动态积分制从实施开始就好评如潮
今年的规则无疑还是比较失败的
反作弊制度还不错
决赛
实话实说,因为2016年的决赛被迫取消,15年的时候,决赛的很多事情参与度不高,所以几乎17年算是我第一次真正办决赛,对于我们的学弟来说,他们可能连15年的经验都没有,还是遇到了很多问题。
只能说没办过比赛,可能真的不知道会遇到多少问题。
在赛前,我们其实准备了决赛的特别规则,但是实在精力不够,放弃了这个计划,改用了最普通的规则,大家玩一玩就好。
首先就是平台问题,决赛平台要求和初赛不同,主要的问题还是出在了沟通问题上,一般意义上来说,决赛的check应该是通过check池的方式实现,当主控check down之后向平台发送请求,平台将该主机的check结果改为down,每个round清空一次这个状态,清空时根据当前结果扣分。
这样一来,check结果就是实时返回给选手,也不会出现多次扣分的情况。
由于沟通的问题,平台直接开放接口给主控,由主控直接扣分,这样以来,在主控存在一定问题的情况下,就会不停的出现各种问题,比赛期间关于check的误扣几乎都是因为这个问题而诞生的。
其次是网络问题,正常来说,我们需要使用多层交换机,隔离不同选手的网段,这样到达选手题目机器的ip就是一致的,没办法通过ip来区分不同的选手。但由于我们的设备是租借的,没有借到合适的设备,导致只能将选手机放在大网段下。
说说主控脚本,说到主控我可能会气死,我决定跳过这个话题,直接说说check的事情。
比赛中比较神奇的事情就是,整个比赛的分数都是向下的,因为我们过于严格的check脚本,导致很多队伍的check结果从头到尾都是down的,大幅度影响了比赛的进程。
整个比赛中的题目,easyblog可能是最最普通的一题,但他最不同的一点就是,如果你不能使用通防,不能对题目进行破坏式的patch,你还能守护好自己的服务器吗?
整个check对大部分的正常功能都做了测试,其中的主要思路包括,我们随机生成了包含部分关键字的随机字符串,在部分上传文件和写入字符串的点,通过比较上传前后的文件内容来检查是否存在恶意过滤。
整个比赛期间,我们不断的检查check脚本,除了其中部分几次导致所有队伍扣分是check脚本的问题,其他所有时候check脚本都没有出过问题。
并且在比赛结束前,Fp、A8和NU1L都成功的在check done的情况下修复了已知所有漏洞。