中国科学技术大学第五届信息安全大赛(hackergame2018自我总结)

https://hack2018.lug.ustc.edu.cn

这是我第一次参加ctf(应该也是第一次听说吧),居然随缘拿了6个flag(本来7个,还有一个明明对了不算我对的),也算是入门了吧,也让我对ctf产生了兴趣,以后我应该也会接着参加这类比赛吧(虽然这让我自闭)

1、签到题

------------------------------------------------------------------------------------------------------------

不用找了!签到题我已经放这里了!

------------------------------------------------------------------------------------------------------------

我反正视力好一下子(ctf不相信视力)就找到了地址栏的变化,加上了一个8完成了任务

write-up:这道题目是我设置在 Hackergame 2018 中的第一道题,其目的只是想更精确的统计一下参赛人数,然而没想到本题也成为了本次比赛中命题组给出最多答复次数的题目。
回到题目本身,这道题目有一个输入框,根据提示需要输入 hackergame2018,然而细心的同学已经发现了,无论是通过输入还是粘贴的方法都会缺少一个数字 8。image-20181016015633115

解决问题的方法至少有以下几个:
解法一:观察地址栏
Hackergame 需要视力!只需要观察到地址栏中 ?key=hackergame201 ,将其改为 ?key=hackergame2018 并回车就可以得到 flag。image-20181016015820553

解法二:审查元素
使用 Chrome 浏览器,在输入框上右键点击审查元素(Inspect)可以看到:image-20181016020015148

一个叫做 maxlength="13" 的东西,我们双击它,修改为大于等于 14 的数字或删除即可。
最后得到 flag:flag{Hackergame2018_Have_Fun!}

2、猫咪问答

------------------------------------------------------------------------------------------------------------

铲屎官:要铲屎吗?@猫咪
猫咪:我是你直接@的?你这是在叫主子?我不想看见第二次。
猫咪:喵的心里没点数?
一只路过的狗:请各位铲屎官注意自己的身份和说话方式。@全体成员

为了不被骂,铲屎官再也不敢问任何问题了,下面这些简单的问题,也只能你自己来搜索解决。

------------------------------------------------------------------------------------------------------------

ps.这道题不就是考用搜索引擎的能力吗?我最擅长了!不难不难。

write-up:欢迎来到猫咪系列题目之猫咪问答。
这道题是一道非常简单的题目,主要是想让同学们学会一些搜索技巧。
解法
下面我们来逐一分析:
中国科学技术大学的建校年份是?
直接搜索即可;
你研究过中国科大学号的演变史吗?现有一位 1992 年入学的博士生,系别为 11 系,学生编号为 26,请问 Ta 的学号是?
搜索“中国科大学号的演变史”,可以找到中国科大的学号演变史,按照 1958 级 - 1996 级的规则生成即可,注意题目中说的是博士生;
视频《诺贝尔奖获得者和杰出科学家祝福科大60华诞》中,出现了多少位诺贝尔奖得主和世界顶尖科学家为中国科大六十周年华诞送上祝福?(数字)
直接搜索“诺贝尔奖获得者和杰出科学家祝福科大60华诞”观看视频即可;也可以选择不看,直接爆破 0~100(合理估计);
在中国科大图书馆中,有一本书叫做《程序员的自我修养:链接、装载与库》,请问它的索书号是?
打开中国科大图书馆主页,直接搜索“程序员的自我修养”即可。
我校 Linux 用户协会在大约三年前曾经举办过一次小聚,其主题是《白帽子大赛,黑客不神秘》,请问这次小聚使用的教室编号是?
直接搜索“白帽子大赛,黑客不神秘”即可,可以找到若干年前 Google Groups 上的活动公告。
zzh 补充:加引号搜索或者加上 LUG 等关键词,也可以在 LUG活动 上找到答案
最后得到 flag:flag{G00G1E-is-always-YOUR-FRIEND}

3、游园会的集章卡片

------------------------------------------------------------------------------------------------------------

提示:flag 仅由 0154agflPYHMGRCNE_{} 这些字符组成。
我们经常被问一个问题:你们是从什么时候开始为 Hackergame 出题的?
其实我们全年都在出题,命题组成员来自各种各样的专业,在各种各样的地方,有各种各样不同的工作,闲暇之余(或者工作不饱和的时候,这个最好删掉)我们最大的乐趣就是互相出题给对方玩。
为了找到有趣的题目,我们需要源源不断的灵感,不管是在巴蜀人家二楼包厢 LUD(注 1) 时,还是在北京食宝街的分米鸡,甚至是在武汉开往合肥的 D2256 列车上,我们会把讨论到的有趣的想法记录下来,作为下一次 Hackergame 的题目。
比如前几天,中国科学技术大学学生 Linux 用户协会在中区游园会摆摊招新(注 2),发现学校居然为每个参加游园会的同学准备了一张精美的集章卡片:

到每个社团的摊位上收集盖章,到达一定数量就有礼品赠送。
突然一位同学灵机一动,不如写上 flag 然后撕碎!
附件就是撕碎的 flag,相信对中国科学技术大学校徽了如指掌的你很快就能将它还原。

------------------------------------------------------------------------------------------------------------

这道题我是用wps word文档拼的哈哈哈……

write-up:致歉:由于使用的字体不好,很多同学反映 flag 上的字母与数字难以辨认,在这里为给大家带来的不便表示歉意!
解答
解法1: 使用 photoshop、powerpoint 等软件将各块碎片拼起来即可见到 flag:

badge

解法2: 将碎片打印出来拼接到一起读出 flag
flag{H4PPY_1M4GE_PR0CE551NG}

4、猫咪和键盘

------------------------------------------------------------------------------------------------------------

谨以此题,献给所有被猫破坏的代码。
众所周知,猫咪最喜欢钻纸箱和趴键盘,其中钻纸箱没有太大的社会危害性,而趴键盘则是对人类的毁灭性打击。
(想象一下这里配了猫钻纸箱和趴键盘的图)
写到一半的代码离奇消失,仅剩的代码也被搞得乱七八糟,愤怒的 D 同学刚要捉住罪魁祸首,准备好好揍它一顿,不料这时猫咪又突w13gcft4n kj87u6,/lp0o9--=l[

------------------------------------------------------------------------------------------------------------

这道题我一个一个单词去复原,经过了1个小时的努力终于成功…………自闭了,太难受了(果然是我想太多了吗?
write-up:欢迎来到猫咪系列题目之猫咪和键盘。
这道题是一道非常简单的题目,主要是想让同学们学会一些文本编辑的技巧。
解法一:一种原始而可靠的办法
经过粗略观察,我们就可以发现这应该是一个 C++ 源代码,而代码被以“若干列”为单位打乱了。image-20181016012607646

我们的思路也很简单,就是先以“若干列”为单位将代码还原。
第一步:打印代码;image-20181016012829431

第二步:裁剪代码;image-20181016012937555

第三步:我编不下去了……image-20181016013016568

当然,只要足够有耐心,这个方法确实是原始而可靠的。
解法二:文本编辑器的进阶技巧
21 世纪,许多编辑器都提供了“列编辑”模式,就我所知,以下常见的编辑器都是支持列编辑模式的:
VS Code
Windows/Linux:
Alt + 鼠标左键 :可以添加多个光标;
Shift + Alt + 拖动鼠标左键:可以选中多列;
macOS:
shift + option + 左键:可以选中多列;
Sublime Text
Shift + 鼠标右键;
鼠标中键;
选中需要进行列编辑的多行,然后按下 Ctrl + Shift + L;
Vim
Normal mode: Ctrl + v
Emacs
直接(或使用 C-x SPC)选定矩形区域的左上角和右下角,
C-x r k 剪切该矩形选区;
C-x r y 插入矩形选区。
任选一款文本编辑器,都可以轻松将代码还原。
还原后的代码大概长这个样:

/*
* name: typed_printf.cpp
* compile: g++ -std=c++17 typed_printf.cpp
* title: type safe printf
* author: nicekingwei
* url: aHR0cHM6Ly96anUtbGFtYmRhLnRlY2gvY3BwZHQtcHJpbnRmLw==
* related knowledge:
* - value and type
* value->value: function
* type->value: parametric polymorphism
* type->type: generic
* value->type: dependent type
* - auto
* - if constexpr
*/
#include <iostream>
// 。。。


根据提示,使用 g++ -std=c++17 typed_printf.cpp 编译并运行 ./a.out 即可得到 flag。

5、Word 文档

------------------------------------------------------------------------------------------------------------

自从加入了 Doki Doki Linux Club (注1),用上了 Linux,D 同学每天都能学到好多新东西。
Linux 好是好,就是没有 Microsoft Office 系列软件,导致看学校的各种通知文件,填申请表等等都变得不那么方便,上次还差点因此错过了 7 号的会议。
突然有一天 D 同学的一个朋友告诉他,其实新版 Office 的文件格式是公开的!
D 同学非常高兴,公开的文件格式或许意味着可以自己写程序来读取和编辑内容,再也不用切换系统或者开虚拟机了。
D 同学追问这个朋友:那么这个文件格式具体是怎么样的呢?
朋友传来一个 OfficeOpenXML.docx。

------------------------------------------------------------------------------------------------------------

我说了,考搜索引擎是难不倒我的哈哈哈……
write-up:这道题是一道非常简单的题目,主要是想让同学们了解一些文件格式的常识。
解法
根据题目中的提示,下载 word 文件,打开提示损坏,修复后可以看见维基百科上关于 Microsoft Office 系列文件格式的介绍。
注意到:
一种以XML为基础并以ZIP格式压缩的电子文件规范
将文件后缀名改为 .zip 或直接强行解压,打开解压后的文件,可以得到 flag.txt,去掉换行之后即为答案。
cat flag.txt | tr -d '\n'
flag 为:flag{xlsx,pptx,docx_are_just_zip_files}
不仅是 docx,还有 xlsx, pptx等的本质都是 zip 压缩包。

6、猫咪银行

------------------------------------------------------------------------------------------------------------

这也是猫咪占领世界的计划之一,通过开设猫咪银行出售 flag 来学习人类割韭菜的技巧。

------------------------------------------------------------------------------------------------------------

出这道题的人是恶魔吧。。。完全没有思路(自闭ing
write-up:欢迎来到猫咪系列题目之猫咪银行。
这道题是一道非常简单的题目,主要是想让同学们了解一些整数溢出的坑。
本题的源代码和分析将很快发布,下面只是解题方法。
解法
简单来说,只需要现兑换 TDSU,购买理财产品,购买时精心构造使得时间溢出为负或者是浮点数,而收益非常大即可。
一个 payload 是:image-20181016123310265

然后时间为负,直接取出即可:image-20181016123347955image-20181016123406691

最后换回 CTB,购买 flag,计划通!
flag: flag{Evil_Integer._Evil_Overflow.}

7、黑曜石浏览器

------------------------------------------------------------------------------------------------------------

请使用最新版黑曜石浏览器(HEICORE)打开。

------------------------------------------------------------------------------------------------------------

这道题真真是太有意思了,我先是学会了改UA,还学会了查看网站源码……
write-up:欢迎大家来到本次比赛的明星题目——黑曜石浏览器,这道题目是一道非常简单但是很有趣的题目。
首先打开题目,发现提示"请使用最新版本黑曜石浏览器(HEICORE)访问"。
所以我们的思路就是伪装自己是黑曜石浏览器。
解法
上网搜索“黑曜石浏览器 HEICORE”,除了百度以外的所有搜索引擎几乎都能找到该浏览器的官网:heicore.com。
我们打开把玩一阵,发现下载,登陆,注册都是无效的。
而且这个浏览器主页还做了很多恶心人的限制,比如禁用了快捷键,打开控制台就会崩溃,伪造了当前页面的地址为 index.php(其实是 index.html)。
不过我们可以直接通过直接浏览源代码来查看这个页面是怎么判断我们是不是黑曜石浏览器。
方法一:view-source
在 Chrome 浏览器地址栏中输入:
view-source:https://heicore.comimage-20181016121046272

可以找到判断 User-Agent 的核心逻辑,就是判断 User-Agent 是否为:
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) HEICORE/49.1.2623.213 Safari/537.36
User-Agent(UA) 是每个浏览器最大的不同的特征,所以可以猜测题目中的 FLAG.txt 需要我们以这个 UA 来访问。
方法二:curl
curl https://heicore.com
和查看源代码是一样的效果。
然后就是尝试使用这个 UA 访问 FLAG.txt。
方法一:使用 Chrome 控制台image-20181016121448185

点击左上角那个手机平板图标,然后:image-20181016121600175

通过 Edit 添加一个叫做 HEICORE 的设备:image-20181016121711381

UA 就填刚才得到的 UA。
然后回到页面,选择这个 Device,刷新即可(注意此时不要关闭控制台窗口)。image-20181016121811337

方法二:curl
curl http://202.38.95.46:12001/ -H "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) HEICORE/49.1.2623.213 Safari/537.36"
即可得到 flag。
flag: flag{H3ic0re_49.1.2623.213_sai_kou}

8、回到过去

------------------------------------------------------------------------------------------------------------

那些发明Unix操作系统的大叔们怎么编辑文本文件呢?
据记载,他们使用一种叫做ed的神奇编辑器,而Unix Hater's Handbook对此有生动的描述:
Ken Thompson has an automobile which he helped design. Unlike most automobiles, it has neither speedometer, nor gas gauge, nor any of the other numerous idiot lights which plague the modern driver. Rather, if the driver makes a mistake, a giant “?” lights up in the center of the dashboard. “The experienced driver,” says Thompson, “will usually know what’s wrong.”
也许是八十年代的某天,调皮的Lawrence正在使用他的DEC VT终端连接到一台大型Unix主机编辑文件——他是个机灵的家伙,使用ed的时候从不需要看屏幕的输出。只看他正在用ed写本题的flag。写了半天,兴高采烈的Lawrence接了个电话,关上ed才发现自己没有保存。
聪明的你能根据对他键盘的记录,还原出你要找的flag吗?
info ed 命令对于没有使用过ed的你是十分有用的。
Hint1:有多个字符串的话,就从上到下连成一行提交就好啦。
Hint2:flag只接受数字和字母。

------------------------------------------------------------------------------------------------------------

这道题有毒吧,我开始明明做对了的说……然后害我查遍了网上所有ed编辑器的资料也没找到问题所在……qwq
write-up:背景和题目设定
一道简单题目,考察选手对 Unix 环境基本操作的熟悉程度,和对输入输出重定向等的基本理解。 灵感来源于 Unix Hater's Handbook,这也是小 L 同学第一次知道还有 ed 这个鬼畜编辑器。事实上,当你把环境变量 $TERM 设置为一个 terminfo 中没有的终端类型时,比如
export TERM=vt233
那么各种牛鬼蛇神编辑器就都不太能正常工作了——比如新手友好的 nano:
Error opening terminal: vt233.
不过友好的 Vim 会猜测你的终端是 ansi,继而在你的终端模拟器上运行。但如果你的终端模拟器是一个毫不解析控制字符的傻终端呢? 除了用 cat 编辑文件,你还可以用 ed。
ed 虽然已经埋入历史的尘埃,但是它还是 Single Unix Specification 的一部分。
一个典型的解题思路
第一步,看到题面上的提示:*忘记保存文件 *、*ed 编辑器 *、info ed、给定输入序列 第二步,去看看 info ed:
首先,*ed * 是一个 Line Editor(行编辑器),这意味着用户进行的编辑操作无法在屏幕上得到所见即所得的反馈。*ed * 在内存中维护一个缓冲区,用户所有的修改都会存在缓冲区中,直到 * w filename * 命令将其写入文件。
a 命令用于向缓冲区的末尾加入文本,以单独一行的 .(英文句点)作为结束输入的标志。
,p 命令可以向屏幕输出缓冲区的内容。 2 (一个单独的行号)用于选择需要修改的行。 s/old/new 可以替换选择行中的 old 为 new。 2m3 (行号 m 行号)命令可以将第 2 行挪到第 3 行后面。特别的,2m0 表示把第二行放在第一行前面。 q 命令用于退出 ed 编辑器。 值得注意的是 ed 独特的报错方式:一个大大的 ?。特别的,一个缓冲区没有保存的 ed 需要两个 q 命令才可以退出,第一个 q 命令的结果是一个大大的 ?。
第三步,继续看题目的 input_sequence:
q
ed
a
flag{
.
a
44a2b8
a3d9b2[ESC]c
c44039
f93345
}
.
2m3
2m5
2m1
2
s/4/t
q
q
前面的 q 和 ed 是上一次 ed 会话的残留,我们应该先删去。 然后发现他没有保存,所以删去末尾的 q,加上 w flag.txt,变成这样:
a
flag{
.
a
44a2b8
a3d9b2ESCc
c44039
f93345
}
.
2m3
2m5
2m1
2
s/4/t
w flag.txt
q
并且运行
ed input_sequence && less flag.txt
得到 flag.txt 如下:
flag{
t4a2b8
c44039
f93345
a3d9b2ESCc
}
发现一个神秘的 ESCc,那是什么?那其实是一个 转义序列,用来控制终端的行为。在本例中为清屏。值得注意,ESC 并不是三个普通的字母,而是一个不可打印字符,而 less 为了向用户显示,所以写成 ESC,并且用白底标出。所以,如果你直接运行
cat flag.txt
你将不能看到完整的 flag。 所以,本题的 flag 是 flag{t4a2b8c44039f93345a3d9b2}。
可能最后的 Escape Sequence 有些小坑,但是没有这一道小弯弯不就不 DEC VT 终端 了?(大雾

9、我是谁

------------------------------------------------------------------------------------------------------------

高中的时候,为了提高作文成绩,小 T 买了一本关于哲学的大众读物。虽然到最后,书确实是差不多看完了,但是并没有什么用。
在他看完这本书之后的某一天,小 T 做了一个梦,他梦见自己变成了一台服务器。作为阅读那本书的后遗症(之一),他不禁开始思考生命的本源之类乱七八糟的问题。到最后,他在纠结的,只有一件事情:
「我是谁?」

------------------------------------------------------------------------------------------------------------

这道题真是太“哲学”了,我完全没有思路……直接放弃了
write-up:大家好,我是小 T,听说这几天你们都在找我,希望与我一起讨论哲学与文学(大误)。首先非常感谢大家参与 hackergame 2018,这是我第一次为这样的比赛出题,有这么多人回答出了我的题目,我感到非常感动。
废话不多说了。接下来是「我是谁」的 writeup。
这道题是在 hackergame 题目准备末期出的,因为需要一些简单的题目。灵感来源是我在大一上半学期的时候,在「计算机导论」(大致是计算机的简单概念入门课程)课上玩手机的时候——那时候刚好在讲网络——看到了维基百科的 HTTP Status Code 的页面,发现里面有一个非常搞笑的代码,就是你们在这道题里面看到的 418 I'm a teapot。
这就是第一小题(哲学思考)的题解,其实只要在页面上打开开发者工具,在 Network 部分就能看到解答了(致萌新:如果你什么都没看到,刷新一下页面)。只要输入的内容小写之后包含 teapot 这个单词,就能拿到 flag,这里我根本没有打算为难别人。(不过可以试试输入 coffee 会发生什么)
至于第二小题的话……Can I help me?

其实本来是没有第二小题的,但是有人希望我实现 HTCPCP-TEA,于是就……
页面提醒尝试用其他的 methods 来请求页面。我承认这里确实需要一点点脑洞……这里的 method 其实是指 Request method,直接点击链接的话使用的是 GET 来连接的。不过如果你尝试用 POST 来请求页面的话,会有非常清楚的提示:
The method "POST" is deprecated.
See RFC-7168 for more information.
去读 RFC-7168 就行了。根据:
To this end, a TEA-capable pot that receives a BREW message of content type "message/teapot" MUST respond in accordance with the URI requested, as below.
最终使用 BREW 请求页面,且带上 Content-Type: message/teapot 请求头的时候,页面会在 Alternates 响应头给出真正可以泡红茶的 URL。用相同的方式请求那个 URL,就能获得第二个 flag。(其实还隐藏着一些彩蛋,可以试试)
嗯?你说不知道怎么请求?发送特定请求的方式有很多,这道题中可以使用的一种方式是使用 curl 的 -I, -X 和 -H 参数来完成。具体内容可以查看 man curl。用 BurpSuite 等工具,甚至是 Firefox 的开发者工具改请求也都是可以的。
其实第二小题的协议实现还可以再逼真一些,但是出于 Flask 的限制,加上时间有一些仓促,所以没有实现,不然这道题还可以更真(qiàn)实(biǎn)得多。至于有人问是否有实现了 HTCPCP-TEA 的茶壶手办嘛……反正我是没有,不过我很期待有人能做出来。

10、家里有矿

------------------------------------------------------------------------------------------------------------

提示:
1. 本题的浏览器“挖矿”只为演示性目的,几乎不占资源。我们不会以任何形式盗取或浪费大家电脑的算力。
2. 本题如果使用程序求解,对于普通配置的个人电脑,在解法正确且最优的情况下,求解程序的期望运行时间不会超过几分钟。
Z 同学为了赶上区块链的热潮,自己潜心研究工作量证明(Proof of work)算法,并且发布了三种全新的电子货币。不仅如此,他还写了一个矿池。
给专业选手的注释:此题并非 web 题,解题过程不涉及注入、XSS、敏感文件泄露、弱类型等安全问题。

------------------------------------------------------------------------------------------------------------

完全不会。
write-up:这道题是我出题花费时间最多,也是我最喜欢的一道题目。我暑假期间编写题目网站、调节每种 Hash 算法的难度、写解题代码、与其他人讨论是否有非预期解法等等,前前后后花了很多天的时间。
我知道好多人都在等着看这道题的 write-up。我会在这篇 write-up 里把我出题和解题思路的所有细节都讲一遍,包括如何估计期望的穷举时间。可是比赛结束之前看样子是写不完了。现在我只写了大概的解题思路,我会在一两天之内把细节补充完整,请大家耐心等待,谢谢大家的理解。
大概的解题思路(未完待续)
所谓我发明的新的工作量证明算法,就是服务器给出一个后缀 suffix,我需要生成两个随机字符串 nonce1 和 nonce2,使得 hash(nonce1+suffix) 和 hash(nonce2+suffix) 相同的二进制位数量超过某一个值,这个值对于不同的 Hash 算法是不一样的
SHA1
直接在 Google 搞出来的 sha1 碰撞 那两个 pdf 后面加上 suffix 提交即可,因为是 Hash 碰撞,所以所有二进制位都是相同的
MD5
这次使用已有的 md5 碰撞加上后缀会发现不给你 flag 了。期望解法有两种,一种是按照王小云的论文搞出来一个不完全的碰撞(我没研究),另一种是真的穷举。
我是用 C 语言写的穷举程序。为了偷懒,我在 python 解题脚本中生成了一堆 md5 写入一个二进制文件,然后调用 C 程序来穷举,C 程序就只需要算异或和统计二进制位的个数了。在 C 语言中使用 __builtin_popcountll 函数统计二进制位中 1 的个数,一条 POPCNT 指令就可以统计 64 bit,速度很快,一分钟之内有很大概率可以跑出来。听说有的同学还使用了 GPU 穷举,关于优化这块大家就各显神通了。
SHA256
穷举是不可能的,即使你用大型超算都不太可能在比赛时间内跑出来。所以呢?期望解法是从比特币的区块链里面找数据。比特币的工作量证明算法是 sha256,现在区块链里面的每一个区块哈希前面都有大约 80 个二进制 0(多么疯狂啊),所以拿它们来找共同 bit 数很多的哈希值,自带了大约 40 位的加成(因为本来 80 位在期望上也有 40 位是相同的)。你需要想办法下载比特币所有区块的哈希,然后两两配对来看一下相同的 bit 数量。如果达到了题目要求,就是下载它们的区块头部,区块头部的两次 sha256 就是最终的 hash,你需要计算一次 sha256,然后结果就是你要提交的数据。不过,我们还是需要满足一个字符的 suffix 要求,这个只要你不断 getjob,总是可以很快拿到你想要的 suffix 的。

11、秘籍残篇

------------------------------------------------------------------------------------------------------------

Those who bear true belief in flxg shall fear no malbolge!
-- La Divina FLXG Commedia
FLXG 创始人 CWK 修为通玄, 万古罕有. 至今无敢直呼其名者, 皆以西文缩写代之.
据 神 FLXG 曲 载, CWK 为探 FLXG 之密, 曾 排空驭气奔如电, 升天入地求之遍. 上穷碧落下尽黄泉, 两处茫茫而无可见. 后其闭关九年, 又仗三尺长剑, 携一刀生宣, 闯 但丁 旧时幽路. 平荆棘, 暴霜露, 惊恶魑, 斩狱卒, 神鬼莫可当之.
每其行足七千里也, 元气化墨, 即为箧囊所藏, 凝之一字, 现诸纸上. 及至伊甸园, 经义已成十万八千字余矣. 当是时, 人间科技正高速发展, 上帝不得已, 将 2D 天空贴纸更为 3D, 故而旧道不通. CWK 举目四望, 但见群星闪烁. 扪参历井, 方知穷途将归.
归来后, 宣纸已自编纂成册, 即 神 FLXG 曲 (曾藏于滑稽大学博物院, 现已佚失). 其中记载 CWK 种种经历此处且按下不提. 而 Inferno: Malebolge 一章, 以 Malbolge 语言书成. 虽晦涩难通, 所谓佶屈而聱牙, 然真义无穷, 实乃无上之道法.
江湖余此残篇, 而今公示于天下. 可否有所体悟, 且看诸君之造化.

------------------------------------------------------------------------------------------------------------

这道题完全没找到思路……
write-up:滑稽 Art
TL;DR
质因数分解,添加换行符,缩小字体
详解
Malbolge 语言是会忽略空格的,可是为什么 txt 里面有这么多空格呢?
用文本编辑器打开发现,这些字符好像有些规律。调小字体大小后发现有明显的 pattern。
用浏览器打开(firefox 和 chrome 都行,黑曜石也行),调到合适的字体大小,再手动调整宽度,可以看到一个畸变的图案,不过不影响做题,仍然可以读出 flxg。很多人提交记录里面把大写 U 看成小写,估计都是用这种方法做的。
当然官方解法肯定不是这么做的。
使用 wc 命令统计一下字符数,发现一共有 154012 个字节。我们应该可以猜到这个文件是个字符画,但是换行被去掉了所以变得很难看。使用 factor 或者 yafu 对这个数进行质因数分解,发现 154012 = 2 * 2 * 139 * 277。经验上,等宽字体字符画像素上的长宽比和字符数的长宽比大致在 1 : 2 左右。所以我们猜测,这个字符画的长宽大概是 556 * 277 或者 574 * 278。
使用 python 或其他语言,每隔这么多字符打印一次 '\n',在控制台上能看到非常正宗的滑稽图案。flxg 赫然醒目。
天书易解
TL;DR
https://www.matthias-ernst.eu/malbolgereverse.html
详解
其实这道题主要考察选手 Google 能力..。
从出题人的角度,如果要出一道 Malbolge 逆向,出题人会怎么写代码。
其实这道题的关键就在于弄清楚条件判断是如何实现的。Malbolge 语言没有条件跳转语句,所以只能通过跳转表模拟。弄清楚这一点的话剩下的就是时间问题了。
所以通过搜索,能找到 Cat halts on EOF 这个程序的源码。甚至可以找到 https://github.com/zb3/malbolge-tools/blob/master/samples/src/q.hell 。
通过 HELL IDE 反汇编,可以看到这份代码与本题之间的相似程度非常之高。实际上,许多 Malbolge 程序处理 if 判断的方法基本都是同一份代码。
确定本题是由 HELL IDE 编译的又一方法是观察代码的前几个字节。HELL IDE 在编译的时候会增加一些初始化的代码,相当于给内存分成代码区和数据区。仔细与其他程序比较可以看到明显的共同点。
另一种预期做法,污点分析。
可以注意到键盘的输入会相互 ROT 和 CRZ,最终形成一个 Ternary byte,之后的处理就全部基于这个字节上进行,输入数据的其他信息都丢失。所以可以对这个字节进行爆破,自己写好调试器之后十分简单。
(此处省略爆破代码)
做出来题目的同学并不期望能拿到 Key,因为这是一个多对一的压缩过程。这里给一个可行的 Key: ./;'[]-=0 本题 HELL 源代码见 flxg.hell 文件。

12、猫咪遥控器

------------------------------------------------------------------------------------------------------------

提示:flag 格式为 flag{......},只包含字母,其中有且只有两个为大写字母。
今天的 App Store 首页故事是《猫咪占领世界》(详情)。
SERIOUSLY?
D 同学不禁开始幻想被猫咪占领的世界:集中营里成群的铲屎官,密密麻麻的 Nepeta cataria(Wikipedia)农田,随意摆放的纸箱子占满了道路……
想想就可怕,不过 D 同学知道人类还有终极秘密武器可以用——猫咪遥控器,有了猫咪遥控器,再多的猫咪也只会乖乖地听人类的话,哈哈哈哈哈~
下面是制作猫咪遥控器的技术总结,需要的原料有:
5mW 6mm 点状激光二极管一个;
锂电池一个;
导线若干;
然后用导线将锂电池和激光二极管连接起来(这一步的目的是让二极管亮起来,不想二极管亮起来的同学可以不连),一个美味的猫咪遥控器就做好了。
猫咪遥控器的原理非常简单!撸猫学会曾经有论文给出过结论:激光笔指向哪里,猫咪就会跑到哪里。
为了报复猫咪把自己的代码打乱(见:猫咪与键盘),D 同学把猫咪遥控器绑在可以上(UP)下(DOWN)左(LEFT)右(RIGHT)移动的三轴机械臂上,开始使用树莓派(一款基于 Linux 的单片机计算机)控制三轴机械臂,进而控制猫咪在草地上跑来跑去。
附件是树莓派上留下的调试输出信息,我们赶到现场时只剩下这个了。

------------------------------------------------------------------------------------------------------------

我其实想到了……都是我没有写出程序qwq,而且画图不标准……就放弃了
write-up:欢迎来到猫咪系列题目之猫咪遥控器。
这道题是一道非常简单的题目,主要是想让同学们学会一些程序画图的技巧。
根据题目提示,我们需要将控制序列画出来,并且我们根据常识和题目提示,能知道:
UDLR 分别代表:上(UP)下(DOWN)左(LEFT)右(RIGHT)。
解法一:传统而可靠的办法
找一张纸(需要比较大的),花一下午即可。
解法二:使用 JS Canvas
我觉得这是最简单的一个办法,编程和解题都借助常见的浏览器(比如 Chrome)即可完成,我的解题代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Cat Controller</title>
<style>
#path {
border: 1px solid #000000;
}
</style>
</head>
<body>
<canvas id="path" width="1200" height="300"></canvas>
<script>
var seq = "DDDDDDD...DDDLLLLLLLL"; // 题目中的序列
var ctx = document.getElementById('path').getContext('2d');
var x = 0, y = 0;
function move(type) {
switch (type) {
case 'U': y -= 1; break;
case 'D': y += 1; break;
case 'L': x -= 1; break;
case 'R': x += 1; break;
}
ctx.fillRect(x, y, 1, 1);
}
for (var i = 0; i < seq.length; i++) {
move(seq[i]);
}
</script>
</body>

把上面的代码保存为 remote.html,用浏览器打开即可得到路径:image-20181016114941390

flag: flag{MeowMeow}

13、她的诗

------------------------------------------------------------------------------------------------------------

高中时候语文作文从未写满过 50 分的小 T,可能是脑子哪里抽了吧,考上大学之后竟然报名加入了学校的文学社。虽然小 T 写作真的很糟糕,但每周的作品分享会上,他还是坚持与他人一起分享创作,并且看上去……他似乎还是很开心的。
这一周,当小 T 还是像往常一样拿出自己的创作时,她走了过来,递给小 T 一张纸。这是她新写的诗吗?可为什么,纸上全是一些奇奇怪怪的字符?
「这是,什……什么东西啊?!」
她一言不发,只是在离开时,她回过头来,小声说道:
「我要提醒一下你,只纠结于字面意思是很费劲的,而且……你不会得到任何有用的结论。」

小 T 的友人,在听闻这件事情后,经过一段时间的分析,找到了这首诗的编码,并且帮他写了一个很短的程序来解码。只是……从解码出的内容来看,事情远没有他们想像得那么简单。
你能找到她想传达的真正的信息吗?

------------------------------------------------------------------------------------------------------------

我读了好久诗……(自闭)
write-up:当我得知这道题出现了非预期解时,我的内心是崩溃的。如果您是用非预期解完成的题目(表现为:得到了 flag,但完全不知道为什么),请先查询资料,思考一下为什么会存在这个非预期解,然后继续看这篇 writeup。顺便想给某站点的站长致以亲切友好的问候。
预期题解
运行 helper.py 可以得到诗的内容,但比较明显的事情是,重点不在这个脚本可以解码出的诗上——如果是的话,我没有必要再去绕一大圈编码再写解码脚本发给你;而且题干里面也是有暗示的。
「我要提醒一下你,只纠结于字面意思是很费劲的,而且……你不会得到任何有用的结论。」
我都这么说了啊……
helper.py 里面的 begin 666 <data> 是什么?搜索引擎可以很快告诉你,这是 uuencoding 编码。可以看到,这个脚本将文件的每一行当作一个被 uuencoding 编码后的文件进行解码。如果你去试一下,会发现一大部分明文行重新编码之后获得的字符串和原文件在末尾的地方不一样。那么很明显,这里有问题。
Uuencoding 编码的结构是这样的:
<length character><formatted characters><newline>
第一个是长度字符,通过长度 + 32,再转成 ASCII 的方式出现(比如说,有 3 个字符,就是 chr(3 + 32),即 #)。之后每三个字节(字符)为一组,以如下的方式编码:Uuencoding 编码方式

(摘自维基百科对应页面)
但不是每一行的字符都是 3 的倍数,那么如果最后一组没法填充的话(即长度乘 4 模 3 不为 0),那么对应部分就会填 0。那么我们想要隐藏的东西能不能就这样塞在填 0 的部分里面呢?答案当然是可以的,不然就没有这道题目了。
获得 flag 的做法中其中一种是一行一行用位运算的方式把 flag 的每个比特拼起来;另一种特定于这道题的方式是:直接扩大每行第一个长度字符到正确的值,具体的原因见下。
非预期题解
那么非预期题解是怎么回事呢?在出题的时候,因为 flag 很长,为了让「诗」短一点,把所有能用的比特都用上了,但是:
如果最后一组只有一个字符,那么最多能填 16 位。
只有两个的话,就是 8 位。
发现什么问题了吗?它们都是 8 的倍数,即一个字符位数的倍数。在大多数的实现中,解码都是正常的,但是如果有 uuencoding 解码的实现忽略了表示长度的第一个字符,并且你找到了这个实现,那么……就可以无脑获得 flag。
(对我来讲)悲痛欲绝的是,想找到这个不太正常的实现并不难。

这是我出题时候的疏忽,向各位道歉。
修复版本
这是修复了「她的诗」非预期解的版本:https://github.com/taoky/her_poem_fixed_version。如果您用了非预期解完成原题,我强烈建议再试一下我微调后的题目。

14、猫咪克星

------------------------------------------------------------------------------------------------------------

通知:已发布备用地址。
众所周知,猫怕黄瓜

你知道猫咪为什么怕黄瓜吗?
有一种说法是这是猫对蛇的原始恐惧,也就是说,如果一个东西足够像蛇,那么猫咪就会怕它。
进一步,如果你足够像蛇,猫就会怕你。
下面我们来扮演蟒蛇(Python)去吓猫。
蟒蛇是一种非常容易使用的编程语言,考验你像不像蟒蛇的标准就是给你一些 Python 3 表达式。如果你能正确计算出来,你就通过了验证。
赶快使用命令 nc 202.38.95.46 12009 来开始吧
备用地址:nc 202.38.95.47 12009

------------------------------------------------------------------------------------------------------------

真的不会,我算了好久……(我30s最多算5个
write-up:欢迎来到猫咪系列题目之猫咪克星。
这道题是一道非常简单的题目,主要是想让同学们学会一些 Python 编程技巧。
TODO:连接远程服务器的若干种方法、如何通过替换库函数解题
先贴上解题程序,明天补细节

#!/usr/bin/env python3 -u
import sys
tricks=[
"__import__('os').system('find ~')",
"__import__('time').sleep(100)",
r"print('\x1b\x5b\x33\x3b\x4a\x1b\x5b\x48\x1b\x5b\x32\x4a')",
'exit()'
]
def removetricks(s):
for t in tricks:
s = s.replace(t,'None')
return s
input()
for i in range(100):
print(i, file=sys.stderr)
expr = input()
print(expr, file=sys.stderr)
ans = eval(removetricks(expr))
print(ans, file=sys.stderr)
print(ans)
print(input(), file=sys.stderr)

以上保存为 sol.py 然后执行 socat exec:./sol.py tcp:202.38.95.46:12009 即可

15、猫咪电路

------------------------------------------------------------------------------------------------------------

#大蒜日报社 科大分社 电
10 月 4 日,膨胀社的一篇报道在科技圈引起了轩然大波,据膨胀社报道:芒果,亚驴逊,超巨等多家公司被一个不到铅笔尖大小的西恩芯片植入了后门,其中客户不乏有米国政府敏感部门。
同时,膨胀社报道中提到的所有公司(芒果,亚驴逊,超巨)等都在极短的时间内积极予以否认:我不是,我没有,别瞎说啊.jpg
一方面是经过膨胀社 2000 名记者和多层编辑花了十几个月来组稿的报道,另一方面是罕见的多家大公司的驳斥,这其中的真真假假,吃瓜群众根本看不透。

虽然我们目前还没有搞到这个芯片的样本(搞到之后可能会加一道新题),但是我们准备了一个简单的红石电路给你逆向。
为了避免重新发明一个电路模拟器,我们使用了 Mojang AB 公司一款带有电路功能的著名沙盒式建造游戏 Minecraft 存档作为本题目的解题资料。
技术上来说,我们通过 Minecraft (版本:1.12.2) 存档提供了一个 40 个输入的红石电路,他们共同影响着信标的颜色,如果你通过调整输入,成功使得信标变绿,说明你已经破解了这个电路,请以 flag{1010101010100010...0101010} 的格式提交你的答案(1 代表激活,0 代表不激活)。
进入 Minecraft 之后的温馨提醒:
为了防止你没有红石电路基础,我们在出生地设置了一系列红石电路教程,希望可以帮上忙;
为了防止你问这道题和猫咪有什么关系,我们在出生地放了一只猫(并且已经驯服);
按 / 键可以键入控制台命令,但是请不要键入 /kill,因为这样你会死;
请不要通过 /gamemode 0 把自己的模式改为生存模式,否则你的电路会被苦力怕炸毁;
请在解题结束后及时关闭该沙盒式建造游戏,否则你会花很多额外的时间;

------------------------------------------------------------------------------------------------------------

mc什么的最简单了,我一下子就做完了!
write-up:欢迎来到猫咪系列题目之猫咪电路。
这道题是一道非常简单的题目,主要是想让同学们学会一些电路逆向技巧。
基本概念:
红石元件:(引用部分来源:minecraft wiki)
红石元件能够接受红石信号并作出反应(例如移动、发光等),例如活塞、红石灯、发射器等。红石元件是在红石电路里具有一定使用目的的方块,大致分为三个大类,部分电路提供能量来源,例如红石火把、按钮、拉杆、红石块、压力板等。
电源为整个电路或部分电路提供能量来源,例如红石火把、按钮、拉杆、红石块、压力板等。
传输线将电能从电路的一部分传递到另一部分,例如红石粉、红石中继器、红石比较器等。
机械接受电能并作出反应(例如移动、发光等),例如活塞、红石灯、发射器等。
充能:
红石元件与部分方块能够被充能或解除充能。如果说一个方块被“充能”了,则这个方块就可以作为电源,能向毗邻的“用电”方块供电以使其工作。(“毗邻”是这样定义的:一个方块是正方体,正方体有6个面。也就是说与一个方块的任意一个面接触的方块最多可能有6个,称之为“与该方块毗邻的方块”)。
当非透明方块(例如石头、砂岩、泥土等)被电源 (或是中继器、比较器)充能,我们称这个方块被强充能了(这个概念与充能等级不同)。强充能的方块可以激活毗邻的红石线。绝大多数电源可以强充能自身。
当非透明方块仅被红石线充能,我们称这个方块被弱充能。被充能的方块(无论强度如何)都可以影响毗邻的红石元件。不同的元件产生的反应不同。您可以查看这些元件的具体描述。
没有不透明的方块可以直接为另一个不透明方块充能,因为中间必须有红石粉或其他红石元件。透明方块不能被任何东西充能。“强”与“弱”充能仅适用于不透明的方块,而不适用于红石粉或其他红石元件。
被充能的方块(强或弱)会影响相邻的红石组件。不同的红石组件对其反应有所不同。
传输:
火把高塔与火把梯:红石火把能够充能其上方的方块与相邻的(包括下方的)红石线,这样,纵向传输便成为可能(向上与向下的设计不同)。
“中继”信号指的是将信号加强到完全信号强度。最简单的方法就是使用红石中继器,包括如下变种:
瞬时中继器: 在不引入延迟的情况下中继信号。
双向中继器: 可以从来回两个方向中继信号。
“二极管”指只允许信号单向传输的电路,通常用于防止电路反向干扰引起的状态改变或延迟紊乱,也可以用于防止大型电路中的线路彼此串扰。常用的二极管包括红石中继器、一格高的荧石与无法向斜下方传输信号的倒置台阶。
很多电路已经具有单向性,因为它们的输出端不会接受输入信号,例如以附着在方块侧面的红石火把作为输出的电路。
逻辑电路:
有时,你需要判断输入信号,经过一定的算法产生一个输出。这类电路即为人们耳熟能详的逻辑门(“门”只让满足“逻辑”的信号输出)。
本题目即为使用逻辑电路,将选手输入的 40 位信号转换成为一位信号,用该信号驱动活塞移动染色玻璃,达到使信标变色的目的。
逻辑门:
与门:两个输入信号均为真时输出为真,其余为假
或门:两个输入信号均为假时输出为假,其余为真
非门:将输入信号反向(即真变为假,假变为真),(由于红石火把附着方块被充能时红石火把会熄灭,因此使用红石火把构建非门。)
异或门:两个输入信号相同时输出信号为假,相异时为真
同或门:两个输入信号相同时输出信号为真,相异时为假
与非门:两个输入信号均为真时输出为假,其余为真
或非门:两个输入信号均为假时输出为真,其余为假
逻辑门在红石电路中的构建在题目出生点均有演示,minecraft wiki 中也有说明
题目解析:circuit
电路采用树形结构,每四个输入信号一组,将每组信号内部的四个输入信号作运算,再将十组的输出信号之间进行运算得到最终控制信标颜色的信号。
因此较为简便的解法是对每组分别求解。可以通过控制信标颜色的最终信号推导每组的输出信号,再对每组内部进行分析,求出使得该组输出信号正确的输入组合,然后顺序拼接得到 flag.
flag{0110101000111100101111111111111111111010}

(未完待续)

猜你喜欢

转载自www.cnblogs.com/packy/p/9905365.html