事情太多来不及写了,先放个简化版的合集在这里吧,如果大家特别需要某道题的官方WP的话我再写吧(应该也不需要吧,毕竟我出的题真的真的不算难吧?)
很简单的一道题,按照提示走就是了。我没想到很多人因为不仔细看输出而认为这道题有问题。
不过这道题确实一开始有点问题,因为出的时候还没部署网站,我不知道访问UCATFLAGS网站用的是http协议,所以一开始条件4加的协议名是https;感谢UNION SELECT team_name FROM teams – 的队员指出这一错误。
以及出这道题的代码真不好写,算是我出的题里第二难写的了吧。
其实这道题最初是想出成一个猜口令的形式的,但是我觉得代码太难写+感觉flag比较长不太好猜就改了。
想必大家一定很喜欢这道题吧,喜欢的话下次再来点类似的(bushi
这道题考察大家有多了解自己朝夕相处的国科大玉泉路校园。这道题的idea是我出的,然后我跟Sikesibian花了半个下午在校园里拍照,他提供了几个比较阴间的点位。
测试这道题的同学当时也做破防了。
这道题最开始没想出成这样,而是想出成一道比较典型的图寻题。原来的想法是找几个中科院的研究所,给出其附近的百度地图全景模式街景截图,找到地点后将研究所英文简称拼成flag。
考察异形代码阅读,严格来讲似乎该放到RE?
读懂代码就行了,然后逆着推过去就好了。
正常的代码如下:
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "8#350*.?\"G&30DC?H1N>Jpw!Q^j\"~87340/.-\"!&%0/\"#'&-,)";
char tmp[100];
char flag[100];
int len, i;
puts("Please Input The Flag:");
scanf("%s", flag);
len = strlen(flag);
if (len >= 100) {
puts("Too Long!");
return 0;
}
for (i = 0; i < len; i++) {
tmp[i] = flag[i] ^ flag[i + 1] ^ len ^ (len - i) ^ 1;
tmp[i] += i < 22 ? '!' : i > 22 ? 0x1E : 0;
tmp[i] += 11 & '0';
tmp[i] += tmp[i] < 32 ? 29 : 0;
if (tmp[i] ^ str[i]) {
puts("Incorrect!");
return 0;
}
}
printf("Congratulations! The flag is %s.\n", flag);
return 0;
}
这个题当时放出来的时候确实有点问题,为了保证加密后flag仍然是可打印字符,我加了一个三目运算符进行判断,让ascii码在小于32时加上一个32。但我和测试的同学都没意识到这行代码引入了一个分支,导致解出的flag不唯一。感谢指出这一错误的各位同学。
上面放出的源代码是修改之后的版本,此时后面那个三目运算符已经不会对运算结果产生影响了,写个脚本逆过去即可。
给个C语言的解题代码吧:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char/*STRING*/str[]="8#350*.?\"G&30DC?H1N>Jpw%Ubn&?Q^j\"~87340/.-\"!&%0/\"#'&-,)(wv32LM`";
char flag[50];
int len = 29;
int main() {
int i, len = 29;
printf("%d\n", strlen(str));
flag[len] = 0;
for (i = len - 1; i >= 0; i--) {
if (i < 22)
str[i] -= 33;
else if (i > 22)
str[i] -= 34;
flag[i] = str[i] ^ flag[i + 1] ^ len ^ (len - i) ^ 1;
}
printf("%s\n", flag);
return 0;
}
话说有人看出来readme.c的代码画的是杆旗子吗?
由于我出的题比较多(一共十八道题),大部分题目都没怎么测试过(实在抱歉,因为来不及了),但我没绷住的是,没测试的题目基本都没出问题,反而是找人测了的几道题在比赛中出了比较大的问题(下次一定多找几个人多测测)。
考察代码编写能力。写代码模拟填写数独的过程即可。
半送分的题目吧,本来想考一个大模拟的,但题目出完之后才发现出的太简单了,以至于我一度想要放弃这道题。
考察使用频率分析法破解古典密码。
加密的文本是先用移了13位的移位密码/凯撒密码然后再套了层Atbash码。本质上仍然是一种单表替换密码,没有改变字母的出现频率,所以对这类单表替换密码都可以用频率分析法很轻松地破译出来。
频率分析法有些简单的技巧:
加密的文本解密后会告诉你如何用键盘进行加密。这里展示的(用键盘上两个相邻按键进行替换)只是键盘密码的一种,键盘密码可以玩出很多花样。
我觉得这道题还是挺好玩的。
考察图片隐写术。
图片中的文本依次用红色、绿色、蓝色上色,并且flag的颜色比较诡异,都是在提醒你去看RGB值。右键->打开方式->画图,取色后可以查看选中色块的RGB值,然后你会发现每个区域,三项数值中总有两项相等并且大于等于128,余下一项小于128;取小于128那一项转ASCII码即可。
这是我出的第一道题。
我觉得这个题出的不是特别好,主要是隐写之后的颜色太诡异了,不够美观,混淆度也太低。我一度也想放弃这道题。
考察凯撒密码变体,送分题。
对flag加密,但每一个字符移位恒比前一个字符多1。结合flag开头必为“ucatflags”,再观察字母序即可发现这一点。
至于为什么叫这个鬼名字。。。其实是因为我想不出来这道题叫什么,吃饭的时候跟Sikesibian讨论,然后聊着聊着想起电影《猩球崛起》的主角也叫凯撒,变异的凯撒也是凯撒,然后就这么定了。
最开始题目送上去的名字叫“古典密码1”。
考察多层古典密码嵌套。解开一层会得知下一层的加密方式,一层一层解下去就行了。
最外层是最经典的位移为3的凯撒密码。为了避免混淆,我特意在“caesar”后面加了一个3(艹,我才发现我“caesar”拼错了)。
第二层是培根密码,用的是26个字母的那个版本。“ | ”是用来区分两个相邻的培根密码的。 |
第三层是手旗旗语,注意有数字出现,所以其实会有numerical的旗语。空格是用来区分旗语的。
第四层是Polybius密码。
第五层是Atbash码。
这五层的加密方式在我给的文档里都有。
这道题的命题代码是最难写的。
这道题的flag是cleopatravii,这是“埃及艳后”的名字。这道题引用了一个著名的传说:凯撒访问埃及时,埃及艳后把自己裹在一张名贵的地毯里送给凯撒,而凯撒用剑将地毯挑开。