发布于 ,更新于 

Project NANO: Official Writeup


#00 一些废话

新年好!自从我们发布 Project NANO 解谜项目到现在,已经过去了大约八个月的时间了。 截至发稿时,解谜平台总访问量约 1.92w ,合计 21 人通关,祝贺各位! 值此 2021 年到来之际,我们正式发布该项目的官方题解以供各位观赏。 注意:该题解由各位出题人合作编写,因此可能会出现风格上的种种不同。

多废话两句:
1. 在题解的开头会贴出关卡到达人数,该处已经为综合 Cookie 与访问 IP 的去重人数。要了解我们的详细技术细节请移步另一篇文章。
2. 如果渲染出现问题,请尝试在左边栏中关闭夜间模式。

#01 色块与编码

作者 Endpoint 到达人数
@FlyingSky /Entry 714

拿到题面,很简单:8 个色块。
然后通过 Ctrl + A 全选,可以发现一个神秘的 3983153e.log 。
经过尝试,发现将其接在 https://clang.pp.ua/ 后面可以访问,得到了一个神秘的 log 文件 ,这种获取信息的方式贯穿了整个 Project NANO。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ZeroMe Logs  Mar 26, 2020.

泠 16:32:12
你知道三原色是什么吗?

霂 16:32:17
红黄青。

泠 16:32:25
我说光的。

霂 16:32:31
……RGB啊!

[时序碎片: 51 51]

根据 3983153e.log 可得 红-绿-蓝 顺序。(bmp 文件中是 蓝-绿-红) 想方法获取色块的 RGB 值并拼接,得到 65 87 69 83 79 77 69 46 32 110 101 120 116 32 58 32 47 116 119 111 102 111 111 116 。 (或者按序读取每个色块 16 进制颜色代码得 415745 534f4d 452e20 6e6578 74203a 202f74 776f66 6f6f74) 按 ASCII 转为字符串得 AWESOME. next : /twofoot,/twofoot 即为下一关。


  1. /Entry/3983153e.log
  2. /color
  3. /3983153e
  4. /entry
  1. /RGB
  2. /rgb
  3. /3983153e
  4. /51_51
  5. /5151

#02 语法小课堂

作者 Endpoint 到达人数
@FlyingSky [转载] /twofoot 149

题面:

本关的题目就在画面上 什么?你没看到吗?或许… 你需要去配眼镜了(讨打)

「题目就在画面上」指当前浏览器地址栏,路径为 /twofoot,有语法错误。改正为 /twofeet 即为下一关。 注:本题目参考自https://www.csie.ntu.edu.tw/~b94102/game/game.htm ,向原作者致以诚挚的谢意。


  • 在到达此关后误入最多的地址是:
  1. /...
  2. /no_hint
  3. /black
  4. /hint
  5. /No hint!

#03 B口令

作者 Endpoint 到达人数
@FlyingSky /twofeet 135

题面:

********,你有听说过吗? 它里面有首歌挺好听的,但只有短短的几秒。 你能帮我找到原曲吗?谢谢啦。 给,这是一个视频,供参考。

1
=EA=93=9Du=E7=BD=AE=E8=BF=99h=CE=B1=D0=B8g=E8=AF=9D=C2=A2=E2=87=92=F0=9D=9F=99=F0=9D=9F=A8=D1=85=F0=9D=9F=BA=F0=9D=9F=A3=F0=9D=9F=A3=F0=9D=9F=A8=F0=9D=9F=BDrY=E2=87=90=C2=A2=E8=BD=AC=E7=A7=BB=E4=BE=84b=C3=AC=C5=82=C3=AEB=C3=AFLi..d=D0=B0k=CE=B1=C3=AC=C2=A2d=D0=BEge=E2=87=90.=E2=87=90=E5=A5=BD=E6=A9=A1b=E1=88=80=E9=92=9B=E5=AF=B9j=C3=AC=D0=B8g=EF=BC=9F

拿到了密文,通过在搜索引擎搜索可知,这是 quoted-printable 编码,一种常用于邮件中的编码。 解码后得到:

1
ꓝu置这hαиg话¢⇒??х?????rY⇐¢转移侄bìłîBïLi..dаkαì¢dоge⇐.⇐好橡bሀ钛对jìиg?

(这种编码和 URL 编码非常相似,因此也可以把 = 替换为 % 进行 URL 解码) 鼻音错了?这种细节就别在乎啦(x

回到正题,不太对劲是因为省去了 B 站视频新采用的 BV 前缀(还不知道?这里扔个知乎链接),补齐得 BV16x41167rY,得以前往 bilibili 的对应视频。 对视频中的音乐进行听歌识曲,可得此曲为 Tears From Heaven。(实测网易云音乐可以,在 01:50 左右) 根据「答案用下划线代替空格,全小写」,/tears_from_heaven 即为下一关。 题目灵感来源于无垠的跨年红包:https://flyhigher.top/develop/1519.html 文案则来源于 abc 的 TG 频道:https://t.me/abcthoughts/1338


  • 在到达此关后误入最多的地址是:
  1. /unturned
  2. /unturned_theme
  3. /if_i_had_four_hands
  4. /=EA=93=9Du=E7=BD=AE=E8=BF=99h=CE=B1=D0=B8g=E8=AF=9D=C2=A2=E2=87=92=F0=9D=9F=99=F0=9D=9F=A8=D1=85=F0=9D=9F=BA=F0=9D=9F=A3=F0=9D=9F=A3=F0=9D=9F=A8=F0=9D=9F=BDrY=E2=87=90=C2=A2=E8=BD=AC=E7=A7=BB=E4=BE=84b=C3=AC=C5=82=C3=AEB=C3=AFLi..d=D0=B0k=CE=B1=C3=AC=C2=A2d=D0=BEge=E2=87=90.=E2=87=90=E5=A5=BD=E6=A9=A1b=E1=88=80=E9=92=9B=E5=AF=B9j=C3=AC=D0=B8g=EF=BC=9F
  5. /if_i_had_four_hands_4

#04 Emoji 域名

作者 Endpoint 到达人数
@abc1763613206 [转载] /tears_from_heaven 110

灵感取材自中科大的 Hackergame 2019,并做了适当弱化。 打开题面,是一则特殊的 Emoji域名。

打开网页之后见到一个 ?(:thinking:) 的 emoji ,鼠标移上去后会弹出剩下的域名。 照例有一段隐藏的 log :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
ZeroMe Logs  Mar 31, 2020.

abc 22:31:12
小猪啊,隔壁让我出道签到题。
不然对别人来说,一开头就整个开幕雷击,也太自闭了。

Piggy 22:32:10
思考

abc 22:33:34
诶,小猪你好喜欢思考啊,你看我弄来了什么?

Piggy 22:35:58
思考
看上去你这个域名确实存在,浏览器访问的话似乎又提示不存在,真是一个令人费解的问题。

abc 22:36:41
呐,给你看篇文章,你研究研究这个域名哪里还能藏东西……

[解锁新的文章碎片: aHR0cHM6Ly9oZWxwLmFsaXl1bi5jb20va25vd2xlZGdlX2RldGFpbC8yOTcyNS5odG1s]

[时序碎片: 30 31]

隐藏的 log 中出现了一段所谓「文章碎片」,很容易就可以看出这是 base64 编码。 解码后是阿里云的添加 DNS 解析记录教程 ,从而可以判断会在域名解析记录中做名堂。 域名中什么类型解析记录会藏东西呢?一个惯用的地方就是 TXT 记录吧。 在排除了 think 和 thinking 后,我们可以把重心转移到 emoji 本身。 emoji 怎么当域名呢?其实就是 Punycode 啦! 可以找转换工具,不过如果你懒的话,直接塞进浏览器里就可以转换了。

转换出来后,使用 nslookup 或是 dig 之类的域名记录查看工具进行 TXT 记录查询即可。 使用 nslookup 进行查询的示例如下,可得出下一关即为 [/Simp1E_Dec](https://clang.pp.ua/Simp1E_Dec)。


  • 在到达此关后误入最多的地址是:
  1. /think
  2. /aHR0cHM6Ly9oZWxwLmFsaXl1bi5jb20va25vd2xlZGdlX2RldGFpbC8yOTcyNS5odG1s
  3. /xn--wp9h
  4. /?
  5. /bd12b4bc

#05 被诅咒的文本框

作者 Endpoint 到达人数
@Piggy @abc1763613206 /Simp1E_Dec 97

哪个男孩不想在题面中的文本框和提交按钮里折腾一下呢?

照例找 log 文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ZeroMe Logs  Apr 1, 2020.

abc 00:21:22
小猪啊,现在这里又有一个文本框,出题人告诉我输入密钥就能通关。

Piggy 00:22:10
是啊,我只知道密钥是 Talion ,但是好像输不进去的样子。

abc 00:23:58
对,有什么东西阻挡住了,得想办法移走他。

Piggy 00:24:42
......

[时序碎片: 31 35]

从 log 文件 87bbdc78.log 中得知「密钥是 Talion」,所以只要想办法把 Talion 输入并提交即可。此题的解法十分多样:

使用元素审查器

观察网页源码,发现当画面中呈现的文本框 .input 获得焦点(被点击等)时会将焦点转移到 .fake-input。

因此,直接在浏览器开发者工具中按选中 .fake-input 后按 Delete 删除。 这样,.input 可以直接从键盘输入了,但只能输入五个字符 Talio。进一步观察发现 .input 有一项属性 maxlength="5"。将 5 改为 6,即可输入完整的密钥 Talion。最后,点击 Submit 按钮,进入下一关。

使用浏览器控制台 (I)

.input 虽然不能获得焦点从键盘输入,但可以从控制台强制设置它的内容:

1
document.querySelector(".input").value = "Talion";

(或者在元素审查器中先点击我们想要输入内容的文本框,再使用 $0.value = "Talion") 接着点击 Submit 按钮,即可进入下一关。

使用浏览器控制台 (II)

浏览整个 HTML 源码,发现除了最后的颜文字,最重要的就是第 82 行的:

1
const path = magic("\xef\xbb\xe4\xb1\xd9\xc2\xd3\xfc\xf7\xf9", inputBox.value);

虽然不能直接在 .inputBox 输入内容,但是我们知道输入完 Talion 后 inputBox.value 肯定也是 "Talion"。所以在控制台里调用 magic("\xef\xbb\xe4\xb1\xd9\xc2\xd3\xfc\xf7\xf9", "Talion"),就可以得到答案 /R3a1_Entry。

解码神秘代码

网页源代码的第 92 行开始有一段「magic」代码:

1
2
<script data-description="magic">
゚ω゚ノ= /`m´)ノ ~┻━┻ //*´∇`*/ ['_']; o=(゚ー゚) =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); // ...

将这一段代码的前一小截放进搜索引擎,可知这是通过 aaencode加密的一段 JavaScript。通过 aaencode 解密工具得到原始的 JavaScript 代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
(() => {
var l = y => y.length;
var g = String.fromCharCode;
var z = o => o.charCodeAt.bind(o);
var f = (t, s) => {
try {
let j = 0, r = '';
var a = z(t), b = z(s);
for (let i = 0; i < l(t); i++)
r += g(a(i) ^ b(j) ^ 233),
++j == l(s) && (j=0);
return r
} catch {
return '\x00'
}
};
window.magic = f.bind()
})();

可以看到这里定义了网页源代码的第 82 行使用的 magic。 结合以上内容,可以知道 magic 所做的是将输入文本框的内容循环与 \xef\xbb\xe4\xb1\xd9\xc2\xd3\xfc\xf7\xf9 异或,再按每个字节与 233 异或。手动模拟这个过程,也可以得到答案 /R3a1_Entry。


  • 在到达此关后误入最多的地址是:
  1. /Talion

#06 被二维码支配的恐惧

作者 Endpoint 到达人数
@NanoApe /R3a1_Entry 87

题面:

哦,来了,我的老伙计。 都来到这里了,肯定不能太难是吧。 所以我要跟你打包票,这一关的题目真的只在这个二维码里面了。 要不,拆开看看?

根据线索「要不,拆开看看?」,提取到图种中的信息: This is a 5*5 n-Puzzle. Please recover it. Scramble STEP: JNPSVWVGMKHGMEPAMEYJJXZ 根据二维码图片文件名 vigen.png 的提示可知解密方式为维吉尼亚算法。
将 STEP 作为密钥解 JNPSVWVGMKHGMEPAMEYJJXZ 得到 RULDDDRRURDRULLLULUUREV。 后缀 REV 则是提示需要将前面的翻转过来,从而得到 UULULLLURDRURRDDDLUR,这便是 5*5 Puzzle 二维码的打乱顺序。 接着我们就可以假设出一个 5*5 Puzzle 的初始局面(空格在右下角)。根据打乱序列的上下左右(UDLR)依次打乱,就可以获得打乱后空格所在的位置,及打乱后 24 个方块的当前位置。再逆向操作一番,就可以将二维码恢复成正常的二维码了! 扫描后得到下一关的地址 https://clang.pp.ua/c1An9。


  • 在到达此关后误入最多的地址是:
  1. /JNPSVWVGMKHGMEPAMEYJJXZ
  2. /R3a1
  3. /R3a2_Entry
  4. /RULDDDRRURDRULLLULUUREV
  5. /vigen

#07 编码,互换,解码

作者 Endpoint 到达人数
@FlyingSky /c1An9 111*

*:该关之后的关卡为内测前添加,因而到达人数的统计会因累加之前的数据而不准确。
题面:

这里 和那 里或 许没 什么 关系 1T1023298N757Q13142N10271Q1T1029 或许你需要先看看,嗯,标题。

首先注意到网页的标题是 ESROM ,暗示答案可能是摩斯编码中后的结果。 再看看 log 文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
ZeroMe Logs  Mar 27, 2020.

undefined

谜题的出口通向哪里?
来到出口,你抬头看了看门。
忽又想起了 “门上插刀” 这个经典的梗。
刀砸在地上,碎屑溅起来了。
你看了看碎屑,从其中找到了那打开出口的钥匙。

[时序碎片:31 31]

[解锁 丢失的密钥:whereisthefilter]

其中有一句「刀砸在地上,碎屑溅起来了」。 这里需要运用一下想象力:其中刀指 - 碎屑指 .,再联系到标题中的「ESROM」,遂尝试将 - 与 . 互换。 先将 1T1023298N757Q13142N10271Q1T1029 摩斯编码,得到:

1
.---- - .---- ----- ..--- ...-- ..--- ----. ---.. -. --... ..... --... --.- .---- ...-- .---- ....- ..--- -. .---- ----- ..--- --... .---- --.- .---- - .---- ----- ..--- ----.

将 - 和 . 互换,得到:

1
-.... . -.... ..... --... ---.. --... ....- ...-- .- ..--- ----- ..--- ..-. -.... ---.. -.... ----. --... .- -.... ..... --... ..--- -.... ..-. -.... . -.... ..... --... ....-

再使用摩斯解码,得到 6E6578743A202F68697A65726F6E6574。 最后,十六进制解码得到 next: /hizeronet,/hizeronet 即为下一关地址。


  • 在到达此关后误入最多的地址是:
  1. /whereisthefilter
  2. /morse
  3. /9201T1Q17201N24131Q757N8923201T1
  4. /esrom

#08 真的没提示吗

作者 Endpoint 到达人数
@FlyingSky [参考] /hizeronet 70
题面:

No hint No hint …

无情的 “no hint”

显然,将路径 /hizeronet 中 hint 去掉得到 /zeroe 即为下一关/zeroe。 该部分原 idea 来自:https://www.csie.ntu.edu.tw/~b94102/game/game.htm (出题者被殴打的声音) 虽然看起来真的 no hint,但是可以注意到假装是 Vue 的 HTML 源码中这部分实际为

1
2
3
<p class="what-is-this" v-bind:title="hint?'真的没有吗…':'哎?不是这个意思?'">No hint</p>
<p>No hint</p>
<p class="what-is-this" v-bind:title="'Wcc_b)UbZh&{R^\R[P]VP]^cWTa{iX_'">...</p>

将 Wcc_b)UbZh&{R^\R[P]VP]^cWTa{iX_ 以 17 作为偏移量进行 ROT47,可得 https://fsky7.com/clang/another.zip。 压缩包的注释为「这是一个弱密码文件」,所以直接暴力破解,几毫秒解出密码为 7。内有一个文本文件和一张图(图种)。 文本文件中的内容搜索引擎搜索可得指的是 freedom,用来解压图种得到一个 php 文件。(当然也可以直接字典爆破) 接下来有两种方法使用这个 php 文件:

  1. 读代码,得知删去当前页面中路径中 h, i, n, t 四个字母。

  2. 改名为 index.php, 然后本地起服务器(php -S localhost:8000),访问 http://localhost:8000/hizeronet 会跳转到 http://localhost:8000/zeroe 得知下一关地址。

  3. 根据留的 @author 找到并暴打出题人。


  • 在到达此关后误入最多的地址是:
  1. /nohint
  2. /hint
  3. /freedom
  4. /Wcc_b)UbZh&{R^/R[P]VP]^cWTa{iX_

恭喜!挑战总进度过半啦!


#09 幻觉

作者 Endpoint 到达人数
@abc1763613206 [灵感来源] /zeroe 58

灵感取材自中科大的 Hackergame 2019,但是进行了适当强化。 题面:

ZEROMAIL_ E From: 霂 告诉你个秘密,其实我挺喜欢对着些温馨些的场景看来看去。 有时候对着张桌面的照片都能看上半天,那种温暖的感觉便自心底发出。 要不我给你一段录像,你来看看其中的奥秘? [[Video File]](https://cdn.jsdelivr.net/gh/hanlin-studio/Media@master/record.rar) 答案就在其中,请坐和放宽。 哦对,看的时间别太长了,会出现幻觉的。

实际上 From 里的邮箱真实存在,给它发邮件的确能联系到列表里的一些出题人。
只是你解出来后先回地址栏去试试啊喂

回正题。题目给了一个 680KiB 的压缩包,将其解压,出来了一个 250MiB,9 小时 54 分的视频。题面中的「答案就在其中,请坐和放宽」说明答案就在视频的某处。显然完整地看完这份视频是不现实的,「哦对,看的时间别太长了,会出现幻觉的」。
温馨的桌面 图片来源 继续查看 log 文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
ZeroMe Logs  Apr 1, 2020.

abc 19:23:01
所以我们又来到了这个题,你有什么思绪吗?

Piggy 19:23:35
思考

abc 19:24:00
哇,这视频这么长,真要我一天25小时高强度温馨看桌面嘛???

Piggy 19:24:35
一定会有更高效的方法来着,你看这压缩包的体积并不大。

abc 19:26:00
我记得有款现代视频处理工具来着,好像是格式工厂都在用的内核?
先不管了,让我来分析一下这个视频......

Piggy 19:26:53
去搜索引擎找一找吧......
一定不需要一帧一帧出来看的。

[解锁提示: iwhvgqetai]

abc 19:28:00
等等,这是啥?

[时序碎片: 39 33]

从其中的提示「格式工厂的内核」可以知道,要使用的工具是 ffmpeg。 又有「提示:iwhvgqetai」,不妨再结合 /c1An9 的 log 文件中「丢失的密钥:whereisthefilter」,把 whereisthefilter 作为密钥对 iwhvgqetai 进行 vigenere 解码,得到 mpdecimate。 注意到 whereisthefilter 中 filter 对解码其实是无效信息,指的就是要使用 mpdecimate 作为 ffmpeg 的滤镜进行操作。搜索相关内容可以找到使用方法。 一种可行的方法是:

1
ffmpeg -i recoded.mp4 -vf mpdecimate %d.jpg

经过大约十到二十分钟,可以得到两张有效图片,分别写了 Wow_Awes0me_ 和 ViDeo_Proc355ing。

合起来就是答案 Wow_Awes0me_ViDeo_Proc355ing,进入下一关 /Wow_Awes0me_ViDeo_Proc355ing。


  • 在到达此关后误入最多的地址是:
  1. /ViDeo_Proc355ing
  2. /Wow_AwesOme_ViDeo_Proc355ing
  3. /Wow_Awes0me_
  4. /Wow_Awes0me
  5. /Wow_AwesOme

世界难题:到底是 O 呢,还是 0 呢??

#10 找餐厅

作者 Endpoint 到达人数
@abc1763613206 /Wow_Awes0me_ViDeo_Proc355ing 56

题面:

泠 17:32:13 看到这个「Project NANO」,你有啥想法没? 霂 17:32:59 有啊有啊,看到这名字我想到了[Uvebfuvzn]的一家餐馆,是意大利风味的。 泠 17:33:55 ……?那这家餐馆在哪呢? 霂 17:34:25 知道知道,我这就去给你搜搜…… 霂 17:36:58 你要不先联系一下他们的老板吧? 泠 17:37:55 行,你把电话给我吧。 答案为纯数字电话号码,或许是国际长途。 请不要因此拨通任何号码,给他人带来不必要的麻烦。 答案验证框还在老地方,别看我。 似乎答案不对?多找找或者换换格式。

将 Uvebfuvzn ROT13 解码得到 Hiroshima,广岛。 然后在广岛使用「NANO」搜索意大利风味的餐馆,找到一家符合条件餐馆,它的电话号码是 +81 823-25-5716。

接着根据题目要求「答案为纯数字电话号码」只保留纯数字,答案就是 /81823255716。


  • 在到达此关后误入最多的地址是:
  1. /81822477471
  2. /0823255716
  3. /0825456107
  4. /81825456107
  5. /823255716

#11 历史小课堂

作者 Endpoint 到达人数
@Jolex /81823255716 67

题面:一张希腊国旗

1
2
3
<img class="hidden flag"
title="data:text/plain;base64,562U5qGI5piv5Lik5Liq5a2X55qE5Lit5paH5ZCN6K+N55qE6Iux5paH57+76K+R77yM5YWo5bCP5YaZ77yM5Li66Ziy5q2i5Ye6546w57+76K+R5beu6ZSZ77yM5bu66K6u55u05o6l5L2/55So6LC35q2M57+76K+R44CC"
src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNyAxOCI+PHJlY3QgZmlsbD0iIzE0NTNBRCIgd2lkdGg9IjI3IiBoZWlnaHQ9IjE4Ii8+PHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2U9IiNGRkYiIGQ9Ik01LDBWMTEgTTAsNUgxMCBNMTAsM0gyNyBNMTAsN0gyNyBNMCwxMUgyNyBNMCwxNUgyNyIvPjwvc3ZnPgo=">

对 title 部分解码,可得「答案是两个字的中文名词的英文翻译,全小写,为防止出现翻译差错,建议直接使用谷歌翻译。」 另外看 log 文件 befa5874.log:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
ZeroMe Logs  Apr 3, 2020.

Jolex 19:51:03
这是什么旗帜?

Piggy 19:51:31
思考

Piggy 19:52:55
……

Jolex 19:53:45
这还能有啥啊,除了旗子就是颜色呗(

Piggy 19:54:19
诶不对,这剧本我好像在前面的关卡里见过。

[时序碎片: 39 33]

其中的线索「这还能有啥啊,除了旗子就是颜色呗」得知要注意颜色。这里仅有的颜色是希腊国旗上的蓝色其十六进制颜色码为 #1453AD。 由希腊本身可以联想到为东罗马灭亡的年份公元 1453 年,或直接搜索可以得到东罗马相关的 meme。由 hint 限定联想到答案为 rome,进入 /rome。 注:此题也接受 Rome 作为答案。


  • 在到达此关后误入最多的地址是:
  1. /greece
  2. /blue
  3. /flag

#12 博多反抗军

作者 Endpoint 到达人数
@fruitymelon /rome 63

题面:

Time: 1950-04-11 23:01 PM 博多反抗军正在和 NANO 的军队作战。 在某个月黑风高的夜晚,NANO 的情报部门成功截取到了敌方的通信内容:

1
2
3
4
5
--..- .-.-. --... -..-- .--..
.-.-. ....- .-..-
--..- -..-. ...-- .---. .----
.-.-. ....- .-..-
--.-. --... -..-. .-..-

现在,NANO 的指挥官想要知道反抗军剩余的力量。你能帮帮他吗?

首先注意时间,时间是 1950 年,缩小了编码的可能范围,1950 年之后出现的编码可以不用考虑。 接下来看到第二句,出现了「博多反抗军」这一陌生主体。 接着看到第三句,「通信内容」表明下面这段点杠是采取了类似于摩尔斯电码的编码方式。但不是摩尔斯电码,因为摩尔斯电码不定长,而题面中的电码是定长的。这里简化了题面,因为真正的电码中不会有空白字符出现,也不会有换行,只会是连续的一大坨点和杠。而现在从题面中很容易看出这个编码是 5 bits 长的。 再往下看到最后一句话,斜体、加粗了「反抗军剩余的力量」这几个字。这是解题的第二步会用到的提示。 惯例翻看网页的 HTML 源码,发现注释:

1
<!-- Some words are kind of odd... at least in Chinese, aren't they? -->

首先考虑破解电码。这一步方法很多,但需要有一定的转述和概括能力,因为直接在搜索引擎中搜索「博多」是搜不到的。现在已经发现的可行搜索词有:

  • 百度搜索
    1. 博多 编码
    2. 博多 电码
    3. 博多 类似摩尔斯
    4. 博多 电报
    5. 5bit 编码
  • Google 搜索 难点在于:在不知道“博多”的正确英文翻译条件下搜索。大多数翻译 APP 均认为博多是 Bodo(实际上应为 Baudot),但所幸博多码的维基百科页中也出现了 Bodo,所以还是能搜到的。
    1. Bodo 5 bit code
    2. Bodo code
    3. Bodo encode
    4. 5 bit code
    5. Bodo like Morse

最终找到:

三者均提供了正确的映射表,参照该表,将点换为 0,将短杠换为 1,解码得到:

1
2
3
4
5
BROWN
RED
BLACK
RED
GOLD

(可能会有大端序和小端序的问题。但考虑到网络上大多数编码表均为大端序,故本题也采用了大端序。) 此时进入第二阶段,即:找出颜色所表示的含义。 使用提示,仔细分析斜体文字「博多反抗军剩余的力量」,则答案应为数值。「博多」为使用过的信息,删去,剩下「反抗军剩余的力量」。Google Translate 耿直地认为这段文字的英文是 Resistance forces,而使用有道翻译的话就会走一些弯路,必须要想到逐词翻译才能得到 Resistance。 在词典中,resistance 有一个名词义项:n. 电阻。 电阻的常见规格有两种,一种为四环电阻,一种为五环电阻。由于题目中给出了五个颜色,于是根据转换规则,计算出该电阻阻值为 12000Ω,误差 5%。 题面并没有问误差,于是直接访问 /12k,进入下一关。 注:此题接受的其他答案还有

  • /12000
  • /12kohm
  • /12000ohm
  • /12k_ohm
  • /12000_ohm

(但是好像没有人访问后四个地址?)


  • 在到达此关后误入最多的地址是:
  1. /brownredblackredgold
  2. /zero
  3. /red
  4. /反抗军剩余的力量

#13 我在哪

作者 Endpoint 到达人数
@fruitymelon /12k 58

题面:

Where am I?

1
iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAaElEQVR4Ad3BAQEAIAyAME4VY5vCPoZ5D7Y5/z4CJEIiJEIiJEIiJEIiJEIiJEIiJEIiJEIiJEIiJEIiJEIiJEIiJEIiJEIiJEIiJEIiJEIiJEIiJEIiJEIiJEIiJEIiJEIiJEIiJGIB1bsCr1SqX+0AAAAASUVORK5CYII=

1b054ab8.log 中提示:

1
2
3
4
5
6
7
8
9
10
ZeroMe Logs  Apr 10, 2020.

Piggy 23:31:32
唔……这就是一张纯色的图啊,里面可能会有什么呢?

fruitymelon 23:32:40
我听说……1024x768 大小的图片,可以轻松藏下 786432 个地址?你知道是什么意思嘛……

Piggy 23:32:58
不懂……这文件本身看上去似乎蛮正常的……

「1024x768 大小的图片,可以轻松藏下 786432 个地址。」 看到题面最后是等于号,果断判断题面是 base64。解码发现最开始三个字符是 PNG,这与 PNG Format 的 File Header 相同。于是在 base64 字符串最前添加 data:image/png;base64, 并直接访问,可以看到绿色图片,另存为到本地。

既然是纯色图片,那么 50x50 个像素所携带的信息量与 1x1 像素的信息量相同,故只表示一个地址。 使用工具(Python PIL,或 Gimp,或 Hex Editor 大脑解码等),得知 RGBA 色值为 35, 220, 155, 177。 看到地址,首先怀疑经纬度。但一方面经纬度只需要两个参数,这里有四个;另一方面经纬度在有效位数少时只能指定到较广阔的一片区域,无法精确得到「地址」。 想到还有另一种地址:网络空间中的地址,最常用的就是 IPv4,所需要的信息量恰好符合 RGBA 像素提供的信息量。于是访问 35.220.155.177,得到下一关地址 /hide_and_seek。

abc 注:该 IP 是我的一台闲置 GCP,现已下线。

如果访问的是 https://clang.pp.ua/35_220_155_177,也可以看到提示:「One step further.」 番外:有一位挑战者将 Alpha 通道的值读成了 176,非常可惜……


  • 在到达此关后误入最多的地址是:
  1. /23dc9b
  2. /hongkong
  3. /hong_kong (这是解析IP啦?)

#14 药品采购

作者 Endpoint 到达人数
@MetLee /hide_and_seek 65
题面:

Met 实验室药品快用完了,帮我买点呗~ Piggy 思考 Met 我这有nano的nzz… Piggy 你要买啥(转头 Met 我这列了个单子,我找找…欸怎么不见了!

全选后可以找到一行隐藏的文字:

Piggy 到底是单子不见了呢,还是单子上的信息不见了?(思考

F12 审查元素可以找到一张图:

png 格式,以及提示「单子上的信息不见了」,检查 lsb,可以读得密文:

1
2
abbrFF AAGGXA AAXXAG FFGFFF FGFDFX
FXFFAG FFGFDG GAAFFA FAFGGF FGXDGG

R 通道
G 通道 显然这段密文分为两部分:小写的abbr,即【缩写】的缩写;大写的密码串,是一个ADFGX密码。解密ADFGX密码需要一个密钥,可以合理推断是图片中三个化合物的缩写。 化学专业的学生可以一眼看出三个化合物是THF、LDA和NMP。非化学专业的可以利用压缩文件(没错这还是个图种)中的三张图片以图搜图得到化合物名称。 解密后可得 nextcolonspaceslashsynthesis,即 next: /synthesis。


在到达此关后误入最多的地址是:

  1. /nextcolonspaceslashsynthesis
  2. /nzz
  3. /thf_lda_nmp
  4. /thfldanmp

#15 冰凉的小手

作者 Endpoint 到达人数
@wilsey1016 /synthesis 50

首先观察题面,线索较多。 网页 title 为「最后一个问题」,网页源代码注释中提示了答案格式为两个单词,图片中包含一张乐谱,标题为 La Boheme,由 Kira Yoshikage 编配。 图片文件中包含两条经由 LSB 隐写的信息:

LMFNOPUCVJSTGBHZRXIKA / L = 110Hz

另外,在 EXIF 信息中提示 Vigenere 密钥是作曲家的名字。 曲谱中包含八度记号,因此实际音高低于谱面一个八度。 例如,第一个音符谱面音高为 A3 而实际应为 A2。 乐谱节奏型固定,并无信息,因此将音高抄写下来。 请勿质疑以下序列的正确性,这是我写了个 python 脚本生成的…

1
2
3
4
5
6
7
['A2', 'B2', 'C3', 'D3', 'E3', 'C3', 'F3', 'G3', 
'C3', 'A3', 'B3', 'C4', 'D4', 'E4', 'F4', 'G4',
'G4', 'A4', 'B4', 'B2', 'A4', 'C5', 'D5', 'A4',
'D3', 'E5', 'F4', 'F5', 'E5', 'D3', 'F4', 'A3',
'E4', 'D5', 'E3', 'E5', 'G4', 'F5', 'E5', 'F3',
'F3', 'C4', 'A2', 'E4', 'G5', 'B3', 'D4', 'C5',
'B4', 'F3', 'D3', 'F4', A4', 'E4', 'D3', 'G4']

注意到最低音 A2 到最高音 G5 刚好经过二十一度,与隐写中第一条信息长度相同,且 L = 110Hz = A2 恰为乐谱和隐写序列中的第一个字母/音符。因此,将隐写序列视为一个置换表,得到序列

1
MFNOFPUFCVJSTGBBHZMHRXHNIGKINGCTXOIBKIPPJLTAVSRZPNGHTNB

推测这是 EXIF 中提到的 Vigenere 加密后的密文,密钥按照 EXIF 信息设为 La Boheme 的作者 GIACOMOPUCCINI。一般而言,编配工作不涉及创作旋律,亦不被视为作曲家。解密得到以下序列:

1
EFLAT BFLAT BFLAT BFLAT C DFLAT C C F G AFLAT HIGHC BFLAT EFLAT EFLAT

容易看出这是一串音高,此处调性应为降A大调,循例 “降B” 读作 B Flat,反之会有一个不常见的 “Flat C” 出现。接下来是从旋律猜测曲目的部分,目前已知以下几种做法:

  1. 直接模唱。迄今为止,只有一名出题组成员家属做到了这一点。这一方法要求熟悉 Puccini 的知名作品和写作风格 —— 现实主义风格。较少的使用高音和花腔而强调高音的戏剧张力。因此,除去 High C 后,旋律中的前三个 B Flat 比其他音符都要低八度,而最后一个 B Flat 作为解决到五度前的过渡,理应和其他音符处于同一八度。
  2. 根据这个不寻常的 High C 直接搜索 La Boheme + High C
  3. 对着歌剧总谱开始找降A大调的片段,由于曲目在歌剧的第一幕靠后,不得不说这种做法也存在一定的可行性。
  4. 根据 Kira Yoshikage 是著名的手控,因此直接得到结果冰凉的小手,che gelida manina。此处并无人接出题人的烂梗,出题人心好痛。

综上,注意到此前我们称题目为 “谜题” 并且绝口不提供进度指示而此处标题中一反常态的指明是 ”最后一个问题“,此处出题人肯定没安什么好心。 经查,che gelida manina 中倒数第二句为 Chi siete? 是歌词中最后一个问句。


  • 在到达此关后误入最多的地址是:
  1. /gelida_manina
  2. /chi_son
  3. /la_speranza

#16 入群题目

作者 Endpoint 到达人数
@abc1763613206 @FlyingSky /Chi_siete 35

这次把注释写前面: 由于相关政策原因,目前自助入群功能已不可用。
参考:我与酷Q的故事——纪念QQ机器人业黑暗的一天 如标题所言,如果到达了这关,就说明你已经到达了题目的尾声,接下来就是入群了。
而如何检验你是完整走完解谜流程,而不是跳关(参考隔壁文章)的呢?自然是要从前面抽取一些题目来进行考核咯。 访问题目,出现弹窗要求输入QQ号,输入完后会随机弹出一道问题。

题库中的题和答案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
[
{
"question": "“找原曲”那道题中,FlyingSky给你的B站视频BV号是多少?",
"answer": "BV16x41167rY"
},
{
"question": "那个特殊的“思考”域名,“思考”的emoji使用了什么技术进行编码?(提示:全小写纯英文)",
"answer": "punycode"
},
{
"question": "“门上插刀”之中,丢失的密钥是什么?",
"answer": "whereisthefilter"
},
{
"question": "域名题日志的“文章碎片”中,文章所在网站的域名是什么?",
"answer": "help.aliyun.com"
},
{
"question": "那一道化学试剂解码题中,使用了哪一种特殊编码?(提示:全大写纯英文)",
"answer": "ADFGX"
},
{
"question": "“找原曲”那道题中,视频中描述了哪一个游戏?(提示:首字母大写的纯英文)",
"answer": "Unturned"
},
{
"question": "通过ZEROMAIL向你发送邮件的是谁?",
"answer": "霂"
},
{
"question": "那张单色图片中,藏着的IP是什么?",
"answer": "35.220.155.177"
},
{
"question": "那一家意大利风味的餐馆的邮政编码?(格式为 XXX-XXXX)",
"answer": "737-0046"
},
{
"question": "“最后一个问题”的图片中,L=?(格式:XXXHz)",
"answer": "110Hz"
},
{
"question": "本解谜中唯一涉及的中学物理变量,其数值是多少?(提示:请在数值后附上中文单位,中间无空格)",
"answer": "12000欧姆"
},
{
"question": "本解谜中唯一涉及的中学物理变量,其数值是多少?(提示:请在数值后附上中文单位,中间无空格)",
"answer": "12000欧"
}
]

至于群号嘛……翻回去找找?
你是不是有什么还没有用上?

回去找找,真还有:
log 里那些「时序碎片」呢? 为什么叫时序碎片呢?

全部取出来并按时间排序如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
ZeroMe Logs  Mar 26, 2020.
[时序碎片: 51 51]

ZeroMe Logs Mar 27, 2020.
[时序碎片: 31 31]

ZeroMe Logs Mar 31, 2020.
[时序碎片: 30 31]

ZeroMe Logs Apr 1, 2020. 00:21
[时序碎片: 31 35]

ZeroMe Logs Apr 1, 2020. 19:23
[时序碎片: 39 33]

ZeroMe Logs Apr 2, 2020.
[没有碎片]

ZeroMe Logs Apr 3, 2020.
[时序碎片: 39 33]

ZeroMe Logs Apr 10, 2020.
[没有碎片]

排在一起,得到 51 51 31 31 30 31 31 35 39 33 39 33。 不难想到可能是 Hex 格式,解码得 QQ1101159393。 群号 1101159393即为最终群组。

入群,带上之前解得的答案,顺利完成解谜。


  • 在到达此关后 误入 进入最多的地址是:
  1. /enjoy
  2. /square

#EE 尾声

祝贺看到这里的各位!于我看来,这篇花费整整3个多小时整理的官方 Writeup ,可以作为 Project NANO 2020年最好的总结。 从开始筹备到最终发布,再到众多大佬的关注,感谢你们这些天一直以来的支持! Eana Hufwe 大佬之前写过了一篇选手视角的题解,亦可以作为参考:一只菜鸡关于《Project NANO》的解谜记录 (注:可能需要适量魔法才能获得完整的浏览体验) 以下是通关的大佬(没被关注到的欢迎继续添加):

内测组成员:

  • mathlover
  • Tianpeng2333
  • 小耗
  • 西番莲果派

再次感谢参与解谜的各位!