Real entry
网页关键内容:
<!--哦,我的老伙计,你怎么误打误撞到这里来了。-->
<!--认真告诉你,这里没东西,去研究下那个二维码吧。-->
<div class="inside-qr">
<p>哦,来了,我的老伙计。</p>
<p>都来到这里了,肯定不能太难是吧。</p>
<div class="hint">
<p>所以我要跟你打包票,这一关的题目真的<strong>只在这个二维码</strong>里面了。</p>
<p>要不,拆开看看?</p>
</div>
<img "https://cdn.jsdelivr.net/gh/hanlin-studio/Media@master/vigen.png" />
<div class="hidden">
<a href="https://cdn.jsdelivr.net/gh/hanlin-studio/Media@master/vigen.png">打开这个图片</a>
</div>
</div>
一个二维码图片。下载下来之后跑一遍 binwalk ,发现里面藏着一个 ZIP 压缩包,压缩包里面有个 README 文件,内容如下:
This is a 5*5 n-Puzzle. Please recover it.
Scramble STEP: JNPSVWVGMKHGMEPAMEYJJXZ
根据提示,可以看出图片是被当作拼图来打乱过的。
不过我到最后也没想出来这个打乱步骤的提示是什么意思。知道这个图片是被分成 5×5 的小格子,按照 QR 码的格式,能够先手动拼出其中的 17 格。
这里面不能完全确定但是还有些线索的只有右下角的格子:要求第一个像素必须是黑色的。这样在剩余的 8 个格子里面只有 4 个格子是可能在右下角的,其他七个格子肉眼没法看出线索。
有了这些条件,我们可以推测出剩余的可能性有
4\times7!=2\,0160\text{ 种}
于是把上面的图片拆成了 25 个小图片,写了一个简陋的脚本来暴力破解这两万多种可能性。
(至少比 25!=15511210043330985984000000={15\text{\footnotesize秭}5112\text{\footnotesize垓}1004\text{\footnotesize京}3330\text{\footnotesize兆}9859\text{\footnotesize亿}8400\text{\footnotesize万}} 种可能性要好得多。)
from PIL import Image
from itertools import permutations
from pyzbar.pyzbar import decode
p_0_0 = Image.open("0-0.png")
p_0_1 = Image.open("0-1.png")
p_0_3 = Image.open("0-3.png")
p_0_4 = Image.open("0-4.png")
p_1_0 = Image.open("1-0.png")
p_1_1 = Image.open("1-1.png")
p_1_2 = Image.open("1-2.png")
p_1_3 = Image.open("1-3.png")
p_1_4 = Image.open("1-4.png")
p_2_1 = Image.open("2-1.png")
p_3_0 = Image.open("3-0.png")
p_3_1 = Image.open("3-1.png")
p_3_3 = Image.open("3-3.png")
p_3_4 = Image.open("3-4.png")
p_4_0 = Image.open("4-0.png")
p_4_1 = Image.open("4-1.png")
p_4_3 = Image.open("4-3.png")
p_n_0 = Image.open("n-0.png")
p_n_1 = Image.open("n-1.png")
p_n_2 = Image.open("n-2.png")
p_n_3 = Image.open("n-3.png")
p_y_0 = Image.open("y-0.png")
p_y_1 = Image.open("y-1.png")
p_y_2 = Image.open("y-2.png")
p_y_3 = Image.open("y-3.png")
n = [p_n_0, p_n_1, p_n_2, p_n_3]
y = [p_y_0, p_y_1, p_y_2, p_y_3]
fixed = [
(0, 0, p_0_0),
(0, 1, p_0_1),
(0, 3, p_0_3),
(0, 4, p_0_4),
(1, 0, p_1_0),
(1, 1, p_1_1),
(1, 2, p_1_2),
(1, 3, p_1_3),
(1, 4, p_1_4),
(2, 1, p_2_1),
(3, 0, p_3_0),
(3, 1, p_3_1),
(3, 3, p_3_3),
(3, 4, p_3_4),
(4, 0, p_4_0),
(4, 1, p_4_1),
(4, 3, p_4_3),
]
left = [(0, 2), (2, 0), (2, 2), (2, 3), (2, 4), (3, 2), (4, 2)]
d = 20
def join_pic(yy, ns):
dest: Image = Image.new("RGB", (d*7, d*7), (255,255,255))
for x, y, img in fixed:
dest.paste(img, (d * (y + 1), d * (x + 1)))
for coord, img in zip(left, ns):
x, y = coord
dest.paste(img, (d * (y + 1), d * (x + 1)))
dest.paste(yy, (d*5, d*5))
return dest
def gen_perm():
for i in y:
ii = [j for j in y if j is not i]
ii.extend(n)
for j in permutations(ii):
yield (i, j)
for y, ns in gen_perm():
p = join_pic(y, ns)
v = decode(p)
if v:
print(v)
尝试出来的结果……
python3 test.py
[Decoded(data=b'https://clang.pp.ua/c1An9', type='QRCODE', rect=Rect(left=20, top=20, width=100, height=100), polygon=[Point(x=20, y=119), Point(x=120, y=120), Point(x=119, y=20), Point(x=21, y=21)])]
设计解法:文件名的 vigen.png
提示的是 Vigenère Cipher。用 STEP
当作密钥,JNPSVWVGMKHGMEPAMEYJJXZ
当做密文,可得明文:
RULDDDRRURDRULLLULUUREV
其中:
- R: right = 右
- U: up = 上
- D: down = 下
- L: left = 左
- REV 提示「Reverse」,就是反转的意思。具体怎么反转的我也没太仔细研究。(毕竟是暴破出来的。)
按照步骤还原拼图应该就可以了。
(感谢群友 @MiaQAQ 的指点)
Clang
网页主要内容:
<title>./.../.-./---/--</title>
<!-- ... -->
<div id="not-here">
<p class="what-is-this">这里 和那 里或 许没 什么 关系</p>
<p><code>1T1023298N757Q13142N10271Q1T1029</code></p>
<p>或许你需要先看看,嗯,标题。</p>
<p class="what-is-this">9432bc3b.log</p>
</div>
「日志」内容:
ZeroMe Logs | Mar 27, 2020. undefined 谜题的出口通向哪里? 来到出口,你抬头看了看门。 忽又想起了 “门上插刀” 这个经典的梗。 刀砸在地上,碎屑溅起来了。 你看了看碎屑,从其中找到了那打开出口的钥匙。 [时序碎片:31 31] [解锁 丢失的密钥:whereisthefilter]
能够找到的线索:
- 标题
./.../.-./---/--
是摩尔斯电码的 ESROM(Morse 反过来写) - 「这里 和那 里或 许没 什么 关系」→两字一组?
-
1T1023298N757Q13142N10271Q1T1029
:不明。 -
whereisthefilter
:不是答案,用途不明
「门上插刀」似乎是出题者杜撰出来的一个「梗」。
看截图来说基本上就是描述日文字形的特点了吧。(是的,同样是汉字,但是不同地方的汉字长得不总是一样的。)
我说泥萌出题能不能加混淆提示了啦。
于是乎,俺到这里……
……就卡住了。
翌日,得到了出题者给出的提示:
网上搜索「解谜之履第三期解析」,得到了一篇微博。
当中第九关有着这样的谜题:
战役 Ending with codes
06068N86858488818187858389
Are you seeking the clue which is quite important?
题目原文
FIRST… YOU MAY TRY ‘ESROM’.
观察发现那句英文的空格是不对的,把单词前空了两格的首字母提出了得到【ASCII】,提示使用ASCII码表。把“ESROM”反过来得到【Morse】,提示使用摩斯电码,以及把密文“反过来”。
引用自题解
根据提示操作,把上面超长的字符串转成摩斯电码,再将点线互换,再次转成字符串再对照ASClI码16进制那栏,得到密码【qq:1093662084】
【另外一种解法会认为将摩斯电码逆过来看。但是这种情况下,频繁出现的8会变成2。但是ASC码中,2字打头的除了16进制那栏,都无法对应符号,16进制那栏对应的都是标点符号,所以这种考虑被排除了。至于为什么是先摩斯再ASCII,是因为英语中提到了FIRST。】
所以基本上这道题是同样的意思。(谁能想到 ESROM 代表的反转是把「嘀」和「嗒」换过来了啦摔)所以……
1T1023298N757Q13142N10271Q1T1029
- 转换成摩尔斯电码
- 嘀嗒对调
- 转换回字母
- 按照两字一字节用 ASCII 解码,得到
next: /hizeronet
Hi Zeronet
从本题目以降,感谢群友 Lawson(@N5cA934A)的协作。
网页关键内容:
<div id="not-here">
<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]V|P]^cWTa{iX_'">...</p>
</div>
能看出来的是:
- URL 里面的提示:Zeronet,一个去中心化的网站托管技术。
-
v-bind:title
:这应该是 Vue.js 了。(不过这跟解谜有啥关系?) -
'Wcc_b)||UbZh&{R^|R[P]V|P]^cWTa{iX_'
:一串密码。直觉判断应该是能解出一个 Zeronet 地址的。(Zeronet 地址长得是像一串 Base64 一样的 35 位字符,而这串字符刚好也是 35 位。)
然后就是出题组成员的各种玄妙的提示……
Piggy 这样强调「hint」这个词我也只能想到那个二分逻辑式(hint?'真的没有吗…':'哎?不是这个意思?'
)里面把 hint 取伪。但是仍然是毫无头绪。(果然俺还是不适合这种解谜的么 orz)
于是乎,俺到这里……
……刚解出来一关……
……就又卡住了。
翌日,在一番苦思冥想之后,发现了这个是要用脑筋急转弯的思路来解的。就是那种「把冰变成水怎么最快」的思路。所以……
\text{hizeronet}-\text{hint}=\text{zeroe}
然后那串代码什么的基本上就是绕远路解法了(虽然我也不知道怎么才能把那远路绕出来)。
Zeroe
页面主要内容
<div id="here-is">
<p><small>ZEROMAIL_</small></p>
<div class="subject">E</div>
<p><small>From: <a href="mailto:[email protected]">霂</a></small></p>
<hr>
<p>告诉你个秘密,其实我挺喜欢对着些温馨些的场景看来看去。</p>
<p>有时候对着张桌面的照片都能看上半天,那种温暖的感觉便自心底发出。</p>
<p>要不我给你一段录像,你来看看其中的奥秘?</p>
<p><a href="https://cdn1.ihcr.top/clang-game/record.rar" target="_blank">[Video File]</a></p>
<p class="hint">答案就在其中,请坐和放宽。</p>
<p class="hint">哦对,看的时间别太长了,会出现幻觉的。</p>
<p class="what-is-this">ffa04ddc.log</p>
</div>
「日志」内容:
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]
那个「现代视频处理工具」、「格式工厂都在用的内核」指的是 FFMpeg1Wikipedia。经过一番搜索,发现 CTF 常用的一个手法就是在长视频里面隐藏 flag。本来视频是有 80 多万帧的,我开始是着每秒只提取一帧,然后逐帧比对,没有比对出什么。但是每一帧都提取我的硬盘会吃不消的。光是这三万多帧的逐帧比对就花了电脑两个多小时,这个数字乘以 25 真的搞不来。
经过群友一只废喵@NebulaNeko 的抓帧,得到以下两帧内容:
事后谈
- FFMpeg 有一个
mpdecimate
的 filter 专门用来解去除重复画面的。当时不知怎的没搜到。 - 群友 Suzunari Shizuku@GPLv3 提示说「给了一串神秘字符,用之前关卡出现的 key 解密可以得到 hint」。拿着之前日志里面的「iwhvgqetai」和 Clang 的日志里面给的「whereisthefilter」,塞进他们喜欢的Vigenère Cipher,就真的给出了
mpdecimate
这个提示。
Wow awesome video processing
页面主要内容:
ZeroMe Logs | Apr 2, 2020. [部分讯息经过加密] 泠 17:32:13 看到这个「Project NANO」,你有啥想法没? 霂 17:32:59 有啊有啊,看到这名字我想到了[Uvebfuvzn]的一家餐馆,是意大利风味的。 泠 17:33:55 ......?那这家餐馆在哪呢? 霂 17:34:25 知道知道,我这就去给你搜搜...... 霂 17:36:58 你要不先联系一下他们的老板吧? 泠 17:37:55 行,你把电话给我吧。 答案为纯数字电话号码,或许是国际长途。 请不要因此拨通任何号码,给他人带来不必要的麻烦。 答案验证框还在老地方,别看我。 似乎答案不对?多找找或者换换格式。 > |
没有任何提示,经过各种试错,发现加密方式是 ROT13。
ROT13(Uvebfuvzn) = Hiroshima
Hiroshima = 广岛县,搜索广岛县叫做 NANO 的意大利餐馆,会找到一个这个:
带着国家代码把电话号码输进去,就是答案。
发表回复