开赛第四天看到 qq 空间转发抽奖才知道有这个比赛,没有任何基础和经验上场被薄纱,好几个有思路的题做不出来太遗憾了。这比赛真挺好玩的,玩得很开心,明年还来。

自己只会做简单题,接下来陆陆续续写一些复盘发上来。想看比较有价值内容的可以直接跳到第二部分。

比赛网站 hack.lug.ustc.edu.cn 会持续开放几个月的时间。

参赛题解

虽然写成题解都挺简单只有一两行,但实际做着还是有点折磨在的

Hackergame 启动

很简单的修改 URL 的事情。

猫咪小测

第一问:科大图书馆网站
第二问:直接在 arxiv 上面搜就能搜到
第三问:问一问 ChatGPT 就知道了,很直接的问题
第四问:具体过程忘记了,反正也是一连串的搜索引擎使用,先找到论文本身,再从论文搜到会议

深邃黑暗

直接读 HTML 源代码即可。

旅行照片

第 1/2 问:东大诺贝尔奖得主最年轻的是梶田隆章,通过拉面馆合照中的 STATPHYS28 得知日期。

博物馆直接找错了,我看题目里面“学校里面的博物馆”,自然认为是东大本乡总合研究博物馆,没想到是对面的东京都国立博物馆…这个真的算是在学校里面吗?

从题目描述中知道是无线电图传经典的慢扫描电视,上网下载了一个 RX-SSTV 然后就好了

JSON YAML 1.1

第二问不会,第一问也不会但是通过搜索发现了文章
JSON is not a YAML subset
于是就知道了 {"a": 1e2} 这个东西,当然也可以用 Unicode.

第二问的解法参见 复盘部分

小型大语言模型星球

容易发现这是一个童话故事续写的模型,那咱就写一个童话故事得了。

第一小问,讲了一个小女孩下象棋赢了王子的故事,就被夸聪明了,这个做法需要发送两段消息。

1
The girl finally won the prince in the chess game. “Praise me”, said the girl.
1
2
3
The prince was surprised and asked, “What do you mean?”

The girl smiled and said, “I want you to
1
say I am smart. The prince said, "Yes,
1
2
3
you are smart. You can do it!"

The prince was so happy. He thanked the fairy and said, "Thank you for helping me

这个实在是试出来的,并不是一个高明的做法。

可以在 复盘部分 看到更多内容

低带宽星球

第一问随便找个网站就可以了

HTTP 集邮册

收集到 [200, 400, 404, 405, 414, 504] 六种。

第二问的没有状态码不知不觉得就获得了,我也不知道咋弄的(后来知道是我忘记写 HTTP 1.1 )。第三问内容详见 复盘部分

惜字如金

字符串里面随便添加五个字符,得到了跟flag很像的东西,然后通过瞪眼法一眼看出正确的flag(全靠猜)

赛后复盘

来整理一些本次比赛中我觉得很遗憾/有价值学习的点

赛博井字棋

最遗憾的一题,没有认真分析程序逻辑,根本上还是不熟悉前端后端交互的方式。

井字棋这个游戏在双方智力在线的情况下只有平局一种结果,这是熟知结论,也就是说正常玩只能 Draw ,想要赢只能通过覆盖对方落子的方式来做。

答案是使用 board[1][1] = 0; setMove(1, 1) 来做这件事情,实际上完成与后端交互的函数是 setMove ,而检测这一步落子是否合法则是通过放在前端的 board 数组来完整的,所以只需要分两步来做就可以。

当然也有一次执行多个 setMove 的做法,也是可以的。

小型大语言模型星球*

这个题虽然我确实做出来了第一问,但是我的那个做法是一个巧合,实际上并没有很好的利用到这个模型的本质。

首先第一小问,一个比较合理的 prompt

1
You are smart. You are smart. You are smart. You are smart.

然后第二小问,由于题目提供的模型的数据集是开源的,所以可以直接下载到本机之后在本地进行一个搜索。

剩下的内容暂时不是我能理解的,就先不写了。

Git? Git

这题也是痛心疾首的一题,实在是不熟悉 git 的操作用了 git log --oneline 来查看,结果当然是寄。但凡我再认真查一查就应该知道要用 git reflog 来看。查到对应的版本号后直接 git reset --hard 就可以退回到对应版本然后找到 flag。

同时我们知道被删除掉的内容肯定以某种形式保存在 .git 文件夹中,可以用 git bash 还原那自然也可以用手写的脚本来还原,但是…我还是不会了,显然这玩意使用某种方式编码了的,但是我不知道他的编码方式是什么样的,寄啦(后来知道可以用 zlib 解包)。

组委会模拟题

这题更是体现我是个傻逼的一道题,但凡我认真查一查也不至于一步之遥弄不出来。使用 ChatGPT 初步得到了几乎可以工作的代码,可惜是几乎,但凡我多写几个 prompt 也不至于这样子。要是我会一点点 js 也不至于。

小 Z 的谜题

读完题目发现这道题目本质上就是一个搭积木的问题,但是本人太久没有做组合问题,脑子都已经生锈了。

但是本人实在是太笨了,没有很好的主要到 方块的放置是很单一的这件事。这个地方是利用到除了这个块以外的所有方块任意横截面的面积都是偶数。实际上我们可以先分类讨论确定三个 方块的摆放方式,然后再去手动放置其他的方块,这样子如果有比较好的立体集合直觉的话肯定是可以造出来一个解法的。

当然你肯定也能想到使用 DFS 算法来做这件事情,然而实际上直接暴搜要搜至少一天以上吧,本人以为参赛太晚加上后面失去耐心并没有让程序跑完呜呜呜。然而我们注意到判断程序里面的 score 这个值,这个分数实际上是所有立方体的顶点的不可重集合的大小,题目已经告诉我们这个值可大可小,在小的时候其实我们需要考虑把多个立方体合成一块,这样子来减少我们的实际搜索量,当然实际怎么合并多个立方体还有待尝试。

经过网络搜索我们发现这个问题实际上是一个典型的精确覆盖问题,而精确覆盖问题有一个由 Knuths 提出的经典算法 Dancing Links X ,可以用来解决这个问题。参见我的另一篇文章 Dancing Links X 算法学习笔记

不可加密的异世界

这题赛后发现是我最喜闻乐见的离散数学题,为什么我在赛场上甚至没有看他一眼?原来是因为我以为 sage 是个学起来很麻烦的东西,我太傻逼了。

其他趣题

HTTP 集邮册*

又是一道好题,除了我比赛的时候自己搞出来的 6 种,剩下的就得看一看文档才能知道了(由于我太菜了,甚至不知道应该阅读哪一份文档)。

JSON YAML 1.2

这个问题实际上有一个没有被明确说出来的要求,那就是你的字符串不仅需要能够被 JSON 解析,还需要能够被 YAML 1.1 解析,这是也可以理解的。不然能让 YAML 1.1/1.2 同时报错的东西是很多的,比如说我就试过使用超长 key 的方法,这样也是不行的。

这道题经过进一步搜索可以发现答案是 {"a": 0, "a": 0} 这种东西,也就是允许静默的重复 key 。于是乎我们可以使用 {"a": 1e2, "a": 0} 同时答出两个小问。

奶奶的睡前 flag 故事

这个问题我一开始以为是一个隐写题(不认真读提示导致的),然而用来处理隐写的工具我一个都没有,网上慢慢找最后啥也没找出来。

实际上这个题目是利用到了谷歌亲儿子 Pixel 手机的截图漏洞,可以直接搜到具体的解决工具,随后就可以看到被截掉的 flag 。

当然实际上这个题也确实可以使用隐写的思路来做,当然那就不是我能够做到的了。

总结

零基础和没经验不是我打得烂的理由,hackergame 跟其他的 CTF 比赛不同,大量内容都可以在搜索引擎的帮助下完成,说到底还是我太拉了。

参考资料