发布于 ,更新于 

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 记录吧。 在排除了 thinkthinking 后,我们可以把重心转移到 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 输入内容,但是我们知道输入完 TalioninputBox.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”

显然,将路径 /hizeronethint 去掉得到 /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。 注意到 whereisthefilterfilter 对解码其实是无效信息,指的就是要使用 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
  • 小耗
  • 西番莲果派

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