2017年南航CTF校赛

CTF校赛

本来想趁着学校大佬们都去打天翼杯,然后校赛混个奖什么的,然而,哈哈没有然而,确实被我们混到了,排名第四,校内队伍第二。 作为第一次参加这种 比较 正式的比赛也是一个好的开始。

最出乎意料的是,这次比赛比预想中难了好多好多好多。差点心态就炸了,不过还好队友们相互鼓励还是坚持了下来。

现在将这次比赛过程记录如下:

MISC1 ++–

看到问题立马想到了BrainFuck,然而打开一看却是各种颜文字…

参考文章: https://qing.su/article/119.html,

注意到BrainFuck的结构,观察前部结构:

( ͡° ͜ʖ ͡°)‘由’+‘替代;

( ͡°(‘由’[‘替代,对应地,’) ͡°)‘由’]‘替代;

ᕦ( ͡°ヮ ͡°)ᕥ‘由’>‘替代。

之后观察后面的结构:

(> ͜ʖ(∩ ͡° ͜ʖ ͡°)⊃━☆゚.*)‘由’.‘替代;

(♥ ͜ʖ♥)‘由’-‘替代;

(∩ ͡° ͜ʖ ͡°)⊃━☆゚.*‘由’<‘替代。

至此,我们可以得到正确的BrainFuck表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
++++++++++
[>+>+++>+++++++>++++++++++<<<<-]
>>>>++++++++++.
+++++++.
--------------------..
++.
+++++++++++++++++.
--------------.
+++++++++++++++++++++.
-------------------------.
++++++++++++++++.
<------------------.
---.
>----.
--------.
+++++++++++++++.
------------------.
++++++++.
------------.
+++++++++++++++++.
<.
>+++++.
--.
++++++++++.

在网站: https://sange.fi/esoteric/brainfuck/impl/interp/i.html 上解密,得到flag

MISC3 recover

(吐槽一下,在chrome输flag,没有选中的话是看不见的。。。)

下载后发现是个png图片,但打不开

第一反应是去改文件头,还是选择先strings一下

然后就有了点惊喜

瞄了一眼已解决列表,卧槽,已经7个队伍了,论抢一血的重要性哇

话说300分是不是多了点。。。。。。

web50

因为每道题的一血(第一个做出来的)有额外加分嘛,然后就准备抢一血。 刷新网页,点开sign-in题,右键源码,找到flag,提交,失败…而且输入框也有问题,不能显示。 然后过了几分钟,应该是被主办方修好了,我们运气不错拿到了一血。

web100

题目是sign-up,点开题目地址,主要有注册登录注销三个功能。试了一下随便注册一个账号都可以登录。一时没有其他思路就用awvs扫了一下,扫出来一个index.php.bak和scehma.sql文件,基本确定应该是属于源码泄露的题。然后对着源码开始审计,发现需要修改一个字段,试着用 me’ union select 1# 注入失败,一直到比赛结束都没做出来… 感觉这里应该是有过滤。

web150

题目循环检测alert并删除,试了各种编码无效,去做web300的时候才想到jsfuck编码,可以绕过检测并且由js解析。

当然要先闭合前边的引号,后边可以闭合或直接注释掉。

web200

这道题就是真的坑了,参数 ?file=flag 没有显示任何内容,试着%00截断返回错误信息,包括文件包含路径include_path=’/usr/local/php’和当前路径/app/xxx/index.php

然后当我输入绝对路径就会显示

you want to search with root path, huh?

输入相对路径就显示

you want to search with apparent path, huh?

那个 huh 真是巨嘲讽,各种尝试都失败了,最后也没做出来,赛后才知道只需要用 php://filter/read=convert.base64-encode/resource=flag 就可以了,,我记得我当时这样试过,但貌似哪里出错了就放弃了。还是经验不够。

web300

这就是这次比赛最开心的一道题了,进去之后发现正则匹配对输入进行了过滤,’[^[]!+]+/g’,也就是说只能使用 []!+ 四个字符进行构造,eval(input)可以对input进行js解析,综合题意,只要可以使用eval(input)构造出’alert’字符串即可。

一开始当然直接jsfuck,然后由于 () 被过滤掉了就fail了。然后各种困惑,各种google之后,get到jsfuck的编码方式,就解开了本题。记录如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
以下内容基于
[] => []
然后!可以将类型转化为布尔型
![] => false
!![] => true
+可以将类型转化为整形
+![] => 0
+!![] => 1
!![]+!![] => 2
然后+[]可以转化为字符串
![]+[] => 'false'
类似于数组取下标
(![]+[])[+!![]] => 'a'
然后就可以类似的从'false', 'true'中读出'a','l','e','r','t'。
em...但是...题目过滤了小括号。需要绕一下
![]+[] => 'false'
[![]+[]] => ['false']
[![]+[]][+[]] => 'false'
[![]+[]][+[]][+!![]] => 'a'
最后用加号拼起来即可。
这题最后一半靠蒙,\笑哭\笑哭

截图如下:

结语

开心,也有点小遗憾吧,路还很长啊。