Hackergame 2023 游记
开赛第四天看到 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 | The prince was surprised and asked, “What do you mean?” |
1 | say I am smart. The prince said, "Yes, |
1 | you are smart. You can do it!" |
这个实在是试出来的,并不是一个高明的做法。
可以在 复盘部分 看到更多内容
低带宽星球
第一问随便找个网站就可以了
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 比赛不同,大量内容都可以在搜索引擎的帮助下完成,说到底还是我太拉了。