Skip to content

Latest commit

 

History

History
319 lines (206 loc) · 15.9 KB

README.md

File metadata and controls

319 lines (206 loc) · 15.9 KB

叶子的新歌 Writeup by MaxXing

很荣幸能以出题人的身份出现在本届 PKU GeekGame 里. 虽然这不是我第一次给 CTF 类比赛出题, 但这是我第一次尝试在 CTF 题目中加入剧情, 总体来说出题的体验确实还不错.

等等, 你体验不错个毛啊, 你考虑过做题的同学们的体验吗 (x

因为是第一次给 GeekGame 出题, 所以稍微研究了一下其它出题人撰写的题面, 然后也按照类似的欢乐的风格来入手了.

不过, 题目本身并不像题面一样欢乐, 不好意思啦.

题面中出现了一些喜闻乐见的梗, 比如:

  • 四轱辘爱抖露/太好听了⑧: LoveLive (然而我并不是拉拉人).
  • 无人问津的阴雨霉湿之地: 世末歌者, COP 创作的中文 Vocaloid 歌曲.
  • 三个 flag 的名称: 三首和 “梦” 有关的冷门东方曲 (我是车车人哒).
  • Word 保存图标的手办: 经典网络烂梗.
  • 叶子和小雨的名字: 随便起的. 虽然群里有拉拉人说是叶月恋, 但我觉得硬说的话可能更像是不能说的秘密.

本题的源代码及其他相关内容见 src/newsong 目录.

Flag1 - 夢は時空を越えて

拿到附件之后简单检查一下, 通过播放器显示的信息或者文件属性等内容, 我们不难发现, 这个 MP3 的专辑名称叫做 “Secret in Album Cover!!”:

macOS 的预览画面中可以很明显地看到专辑名称信息

这暗示着专辑封面里藏了东西, 我们可以想办法先把专辑封面提取出来. 这里可以使用 ffmpeg, 先看一下专辑封面是什么格式:

ffmpeg -i LeafsNewSong.mp3

得到:

  Stream #0:1: Video: png, rgba(pc), 1000x1000, 90k tbr, 90k tbn, 90k tbc (attached pic)
    Metadata:
      comment         : Cover (front)

是 PNG 格式的, 于是我们可以:

ffmpeg -i LeafsNewSong.mp3 -an -vcodec copy cover.png

这样, 专辑封面就提取到了 cover.png 中.

当然, 在提取专辑封面的过程中, ffmpeg 会输出 MP3 文件的 metadata, 我们可以注意到 comment 里藏了一段文本:

    comment         : 你还记得吗?小时候,我家和你家都在一个大院里。放学以后,我们经常一起在院子里玩。你虽然是个女孩子,但总是能和男孩子们玩到一块去。
                    : 
                    : 夏天的时候我们挖蚯蚓、捉蚂蚱;冬天,院子里的大坡上积了一层雪,我们就坐在纸箱子压成的雪橇上,一次次从坡顶滑到坡底。那个时候你还发现,坐在铁簸箕上滑得更快。
                    : 
                    : ——当然,那次你也摔得挺惨的。

这段文本和剧情相关. 在后续解题的过程中, 你可能会继续发现若干段和剧情相关的文本.

拿到专辑封面之后, 我们可以继续深挖. 通常在 misc 类题目中, 与图片相关的内容无非就几类, 针对本题中的 PNG 图像, 最常见的应该就是 LSB 隐写了. 于是扔给 stegsolve 试一下 (网页版):

提取时的设置

最终可以提取出另一个 PNG 图像:

提取结果

这个图像上最显眼的部分应该就是这个二维码了, 不过显然它并不是 QR code, 查阅相关资料我们可以得知这是一个 Aztec code, 读取后得到结果:

Gur frperg va uvfgbtenz.

这看起来像是一段乱码, 但观察可以发现这段乱码中出现了大小写字母, 空格和 . 符号, 所以肯定不是 base64 或其他类似编码. 通常这种看起来很像英文句子的乱码可以往凯撒密码的方向思考, 于是稍加尝试可以发现, 这段文字中的所有字母按字母表顺序向前 (或向后) 移动 13 位即可得到一段有意义的英文句子:

The secret in histogram.

这种编码方式叫做 ROT13, 在上届 GeekGame 的签到题中也曾出现过 (可见上届的签到题有多亲民).

这句话提示我们, 要从 histogram 中寻找秘密. histogram 是直方图的意思, 如果你熟悉图像处理的话, 你就会了解图像直方图这种东西: 我们可以统计图像中不同颜色/亮度的像素, 然后以横轴为颜色/亮度的值, 纵轴为当前种类下的像素数量画出一个直方图.

我们不妨查看刚刚提取出来的灰度图像的直方图 (网页版):

灰度图像的直方图

发现这居然是一个... 条形码?!

需要注意的是, 如果你使用 Photoshop 查看图像的直方图, 你可能会遇到这种情况:

看起来很乱

根本看不出这是一个条形码. 这是因为 Photoshop 为了提升加载速度, 默认并不会使用完整的图像数据来计算直方图. 点击右上角的警告图标, 直方图才会变成整齐的样子. 当然就算是这样, 你可能也很难看出这个直方图里藏了个条形码, 因为这个直方图的面板太小了, 而且前景是白色的... 所以你也许可以换用其他的一些专门查看图像直方图的工具, 或者干脆写个脚本算一下.

我们可以直接用条码读取的软件/网站来扫描这个条码 (别用微信), 得到:

xmcp.ltd/KCwBa

这明显是一个 URL (感谢 xmcp 提供的 host 服务), 我们可以尝试访问一下, 得到:

你还记得高中的时候吗?那时在市里的重点中学,我们是同桌。我以前还怪讨人嫌的,老是惹你生气,然后你就不和我说话,我就死乞白赖地求你,或者讲笑话逗你。

不过,你笑起来好可爱,从小就好可爱。此后的一切,也都是从那个笑容开始的吧。

真的,好想回到那个时候啊。

Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook.
Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook.
Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook.
...
Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook.
Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook.
Ook. Ook! Ook. Ook? Ook. 

上半部分是第二段剧情文本, 下半部分是一大串 Ook 组成的意义不明的内容, 仔细观察, 这些 Ook 之后的标点符号似乎还不太一样. 遇事不决, 我们可以直接把这段内容中的某些部分放在搜索引擎里搜一下:

Google 搜索 Ook

第一个结果就是解码这种内容的页面. 实际上, Ook! 是一种类似 Brainfuck 的 esolang, 它使用若干种不同的 Ook 序列, 重新编码了 Brainfuck 的几种运算符. 执行一下这个 Ook! 程序, 我们可以得到 flag1:

flag{y0u_h4ve_f0rgott3n_7oo_much}

Flag2 - 幻夢界

在解 flag1 的过程中, 我们读取了 LeafsNewSong.mp3 中的 metadata:

Input #0, mp3, from 'LeafsNewSong.mp3':
  Metadata:
    TSS             : Logic Pro X 10.7.0
    iTunNORM        :  0000072C 00000736 00003208 00003140 00009E92 0000501A 00006703 00007E86 00007678 00007E1F
    iTunSMPB        :  00000000 00000210 000007A5 00000000002709CB 00000000 002350D1 00000000 00000000 00000000 00000000 00000000 00000000
    title           : 叶子的新歌
    artist          : 叶子
    album           : Secret in Album Cover!!
    TRACKTOTAL      : aHR0cDovL2xhYi5tYXh4c29mdC5uZXQvY3RmL2xlZ2FjeS50Ynoy
    lyrics          : 空无一人的房间
                    : 我望向窗外
                    : 想回到昨天
                    : 
                    : 琥珀色的风
                    : 能否将 回忆传到那边
                    : 闪烁的星
                    : 照亮夜空 连成我的思念
                    : 
                    : 你 在梦的另一边
                    : 站在 日落的地平线
                    : 背离这世界而去
                    : 想 在回不去的时间里
                    : 遇见你 遇见你 遇见你
                    : 遇见你 遇见你 遇见你
    comment         : 你还记得吗?小时候,我家和你家都在一个大院里。放学以后,我们经常一起在院子里玩。你虽然是个女孩子,但总是能和男孩子们玩到一块去。
                    : 
                    : 夏天的时候我们挖蚯蚓、捉蚂蚱;冬天,院子里的大坡上积了一层雪,我们就坐在纸箱子压成的雪橇上,一次次从坡顶滑到坡底。那个时候你还发现,坐在铁簸箕上滑得更快。
                    : 
                    : ——当然,那次你也摔得挺惨的。
    encoder         : Lavf58.45.100

仔细观察, 除了专辑名称暗示了有秘密藏在专辑封面里, 还有一个 tag 的内容比较可疑:

    TRACKTOTAL      : aHR0cDovL2xhYi5tYXh4c29mdC5uZXQvY3RmL2xlZ2FjeS50Ynoy

TRACKTOTAL 的值很明显是一段 base64 编码后的内容, 我们可以对其解码, 得到 URL:

http://lab.maxxsoft.net/ctf/legacy.tbz2

访问后可以下载到 legacy.tbz2, 这个压缩文件解压后会得到两个文件: foryou.txtTo_the_past.img. 先看看 txt 里说了什么:

我有一张很久很久以前的软盘。说起来以前的操作系统还能装在软盘里,把软盘放进电脑就可以启动,很神奇吧?我给你看过这张软盘,但你总说这是Word保存图标的手办……什么跟什么啦!

现在已经没有带软驱的电脑了,甚至连带光驱的电脑都没有了。以前软盘里的那些东西,也许再也启动不了了吧。

时间过得好快啊,转眼间,就来到了现实。

这是第三段剧情文本, 但其中多次强调了 “把软盘放进电脑启动”.

我们可以看一下 To_the_past.img 到底是个什么文件:

$ file To_the_past.img
To_the_past.img: DOS/MBR boot sector, code offset 0x3c+2, OEM-ID "GeekGame", root entries 224, sectors 2880 (volumes <=32 MB), sectors/FAT 9, sectors/track 18, serial number 0x0, label: "TO_THE_PAST", FAT (12 bit), followed by FAT

file 命令告诉我们, 这是个 FAT 格式的磁盘镜像, 并且还包含 DOS/MBR 引导扇区, 也就是说它是可以被引导的. 根据剧情文本的提示, 我们可以把这个镜像放在虚拟机或者模拟器里启动一下:

使用 Bochs 启动软盘

得到 flag2 (可能需要手敲):

flag{th3_Sun5et_h0r1zon_0815}

同时, 我们还可以得到密码 ItsMeMrLeaf, 虽然此时我们暂时还不知道这个密码有什么用.

Flag3 - 夢と現の境界

在 flag2 中, 我们已经得到了一个软盘镜像, 于是自然而然地, 我们可以使用 mount 命令或者一些解压缩软件查看它的内容.

软盘镜像中包含了一个 zip 压缩包, 和一个文本文档. 尝试解压缩 zip 文件, 但发现需要密码. 于是去看文本文档:

备忘

密码是:宾驭令诠怀驭榕喆艺艺宾庚艺怀喆晾令喆晾怀

就直接得到密码了... 吗?

试一下发现密码不对, 说明这里面可能还套了一层. 遇事不决, 再次去搜索引擎搜索这段意义不明的文字 (什么叫真正的小北问答啊?):

Google 搜索意义不明的汉字

发现这是人民币装箱的冠字号, 从搜索结果里我们可以找出文字和数字的对应关系:

艺=1 驭=2 令=3 怀=4 庚=5 诠=6 宾=7 晾=8 喆=9 榕=10也就是0

于是替换得到解压缩密码 72364209117514983984, 注意这里的 应该被替换成 0. 解压缩后, 又得到了另外三个文件: left.bin, right.bin 和一个 readme 文本文档. 先看看 readme 怎么说:

我以前很喜欢玩红白机,当然,现在也很喜欢。超级马里奥、魂斗罗、坦克大战、马戏团、冒险岛……一玩能玩一天。

小时候家里有一台红白机,也经常叫你一起玩游戏,只不过,我记得你不喜欢这些东西。你最喜欢在4399玩找不同,而且你还玩的特别棒,简直就是找不同滴神。

呜呜,红白机已经属于时代的眼泪了。

这是第四段剧情文本, 这段文本里反复提到了 “找不同”. 我们再来用 file, binwalk 或者 16 进制编辑器看一下这两个二进制文件, 然而一无所获. 不过从 16 进制编辑器里应该可以看出, 这两个文件的内容大体上是相同的:

使用 16 进制编辑器查看 bin 文件

于是我们可以根据文本的提示来在这两个二进制文件里找不同, 也就是 diff 两个二进制文件的内容.

这里我使用的方法比较暴力: diff 命令本身是没办法直接对二进制文件操作的, 所以我们首先用 xxd 命令提取两个文件文本格式的 16 进制, 然后再 diff 文本:

diff <(xxd -p -c 1 left.bin) <(xxd -p -c 1 right.bin)

我们期望得到纯的 16 进制的文本结果, 然后将这个文本结果再次转换为二进制, 并输出到文件, 于是对其稍作处理:

diff <(xxd -p -c 1 left.bin) <(xxd -p -c 1 right.bin) | sed -E "s/[0-9]+[a-z]+[0-9]+|> |< //g" | xxd -r -p - > out.bin

检查一下输出的 out.bin:

$ file out.bin
out.bin: NES ROM image (iNES): 2x16k PRG, 1x8k CHR [V-mirror]

发现这是一个 NES 的 ROM, 也就是一个红白机的游戏 ROM. 结合之前的剧情文本, 叶子喜欢玩红白机游戏, 这个看上去也挺合理的. 我们用 NES 模拟器载入这个 ROM:

载入 NES ROM

看起来是一个超级马里奥兄弟一代 (Super Mario Bros.) 的改版 ROM. 按照叶子的思路, 我们可以把它打通关. 附一些友情提示:

  1. 超级马里奥是可以跳关的, 通常的最速通关路线为 1-1, 1-2, 4-1, 4-2, 8-1, 8-2, 8-3, 8-4.
  2. 模拟器是可以在任意位置 S/L (存档/读档) 的, 如果你手残的话, 可以借助 S/L 的力量.
  3. 如果你依然手残, 你可以开金手指, 建议搜索引擎找一下.
  4. 如果你还是手残, 你可以去一些 TAS 录像的分享网站, 找超级马里奥一代的 TAS 录像 (比如这个 HappyLee 打的录像), 然后用 FCEUX 之类的模拟器播放, 这样你就完全不需要操作游戏了. 这个 ROM 只修改了标题画面和某些文字, 并没有修改关卡的内容, 所以超级马里奥一代的录像也是能在这个 ROM 里回放的.

通关后的画面如图:

通关 NES ROM

游戏提示我们访问 lab.maxxsoft.net/ctf/leafs, 遂访问之:

输入密码

输入之前软盘启动的时候我们得到的密码: ItsMeMrLeaf, 即可得到最后一段剧情文本, 以及 flag3:

说了那么多的回忆,不如,再来聊聊现在吧。

那天和你表白之后,我们正式在一起了。回想起那段日子,整个世界都是彩色的,在校园里的每一天,我和你都很开心。

但,如果你没有在8月15号出去练琴,如果你没有经过那个十字路口,如果那辆卡车没有超速。

如果。

如果这个世界上真的有如果。

从那之后到现在,你已经昏迷整整三年了。

大夫说,你失去了所有的记忆,再也想不起我们的从前,变成了一个无意识的植物人。

但我依然相信,只要我每天都在床边陪着你,和你讲以前的故事,奇迹就一定会发生。

如果你在那个悠长的梦里,看到了这条消息,请一定记得:

从你的世界里醒过来,然后——


回家吧。


flag{W4ke_up_fr0m_7h3_L0NG_dre@m}

啊, 是悲伤的故事呢...