Berd's Playground

_(:з」∠)_

@FENGberd2 months ago

01/1
04:33
CTF

HarryYu 的 2020 新年解密 Writeup

0x00 题目地址

在群里看到这个解密游戏, 感觉很有意思就玩了一下, 还是挺好玩的. 看了一眼红包都领完了, 正好失眠就来写个 Writeup.

URL: https://harrynull.tech/2020/

顺便放一张截图

0x01 第一题 – Morse

刚刚拿到这题看着这个空白页面和满屏幕的 LOLOLO 我还是懵了很久的, 想了半天发现 LO 如果输入拼音只会有“咯”这一个字, 就把答案当成 了…

没想到关键点藏在 WebSocket 的发送时间上, 难怪页面开头说了一句 “建议在较好的网络环境下游玩以获得最佳体验”. 当时只当是网络不好可能造成 WebSocket 掉线, 没想太多. 知道和时间相关就好办了, 很容易猜测到可能是 Morse, 写一个简单的 JS 输出 WebSocket 的发送时间:

采集到几分钟的数据应该就足够了, 将数据粘贴到文本编辑器进行分析, 发现时间长度大致分为 1s, 2s, 3s, 6s 几种. 根据出现频率不难猜测 6s 对应的可能是一个完整的发送周期结束, 据此进行分割再观察.

在一个周期中, 可以看到 L:3 出现了多次, 但频率并非很高, 猜测 L:3 指示的是两个字符的间隔, 据此进行分割后不难推断出 O:1 对应点, O:2 对应横, L:1 对应两个电码的间隔, 而 L:2 可能是网络波动造成的. 根据上面的分析对电文进行替换, 得到下图

不难看出红框中的数据应该就是服务器真正想发送的, 其他不匹配的数据都存在网络波动造成的干扰. 将这段 Morse 进行解码, 得到一串字符 e5afb9

由于我是先做了后面几个题才知道第一题是 Morse 的, 这时就猜测这串字符可能是某种编码, 而三个字节的编码很容易联想到 UTF-8.

作者: 对

解码得到第一题的答案, 完成

0x02 第二关 – 二分法查找冲突

这一关的设计比较有意思, 中间延迟是服务器做的, 而且每次连接的冲突编号都不一样, 不能进行爆破.

写一段小 JS 帮助我们进行批量选择

然后使用二分法进行查找就行了, 这里给一下大致思路, 不上图

  • 将数据持续分为 A B 两块, 持续排除其他 ID 直到两块各包含一个冲突 ID
  • 保持 A 的选择状态不变, 在 B 中用二分法查找出精确的 ID
  • 在 B 中只选中冲突 ID, 然后在 A 中使用二分法查找冲突 ID
  • 最后得到 A 和 B 中各自的冲突 ID, 勾选并提交即可

提交正确的两个选项后服务器就会返回口令, 完成

0x03 第三关 – WebASM!

这关的解题思路比较反常规. 一开始进入页面只有一个密码输入框, 查看源代码发现调用了 WebASM 校验密码.

常规思路应该是对这个 lvl3.wasm 进行逆向, 而我也确实这么搞了一下.

甚至还写了一点伪代码

但是这个算法看起来并不容易逆推结果, 于是换个思路. 由于页面中调用了 .charCodeAt(0) 来做输入, 而且有明确的提示输入只是一个汉字, 而在 UTF16 中汉字只有 20991 个, 不妨直接套一个 for 循环进行爆破.

按下回车的瞬间就出结果了, 轻松愉快, .

0x04 第四关 – Whitespace!

这关的提示挺明显的, 首先页面进去只能看到一行提示, 查看源代码才发现前面有一段空白.

前半段 Hint 告诉我们要找奇怪的语言, 可以在 https://esolangs.org/wiki/Language_list 找到一个比较完整的列表, 看到这一串空白明显就是某迷惑 Whitespace 语言.

随便找一个在线 IDE: https://vii5ard.github.io/whitespace/ 输入代码查看汇编, 得到数字 21915+1=21916

再结合 UTF-16 的提示, 直接使用 String.fromCharCode() 即可得到结果, 完成

HarryYu 的 2020 新年解密 Writeup