解密dJulkalender 2022:CTF挑战全解析

本文详细解析了dJulkalender 2022的每日CTF挑战,涵盖立方根解码、MUD冒险、SQL注入、图像处理、JavaScript逆向等多种技术,适合对计算机安全与编程感兴趣的读者。

dJulkalender 2022: Write-up

简介

我的母校KTH的计算机科学分会组织了一个名为“dJulkalendern”的降临日历活动。这是一个类似CTF的谜题挑战,几乎每天都有新题目,直到圣诞节,同时还是一场竞赛。这些谜题并不像常规CTF那样专注于安全,而是更广泛的IT相关谜题。今年,每个工作日都有一个谜题,我将逐一讲解。为防止文章过长,我会尽量简洁。如果您有任何疑问或以不同方式解决了某个问题,请在下方评论。

第-1天:准备好了吗?

第一个窗口只是一个热身,鼓励您阅读背景故事页面以了解背景,并在挑战开始前制造一些期待。它还通过给出密码“further”介绍了密码系统的工作原理。

第1天:Mrs. Claus,更像是Missing Claus

在这个窗口中,主要内容是以下句子:

所有3vil的根源是:1404928 1481544 1367631 1191016 1030301 970299 1560896 1157625 1367631 1331000

这里的关键部分是“root”、数字3和大数字。如果我们对每个数字取立方根,并将其视为ASCII编码文本,我们可以提取密码。这可以通过以下代码完成:

1
2
3
4
5
6
7
8
#!/usr/bin/env
import math

numbers = "1404928 1481544 1367631 1191016 1030301 970299 1560896 1157625 1367631 1331000"
numbers = [int(x) for x in numbers.split()]

roots = [round(x**(1/3)) for x in numbers]
print(bytes(roots).decode())

运行此代码得到密码:projection

第2天:编写安全代码

按照dJulkalendern的传统,周五窗口是MUD窗口。这意味着我们使用提供的说明通过netcat连接到MUD。连接到服务器后,您会看到一个经典的文本冒险游戏。在游戏中,我们在房子里走动并与各种物品互动。

在床下,我们找到一张纸条,上面写着“0 _ _”。在水槽里,有一张纸,上面写着“3 ”。在切菜板上,有一个包裹,给我们文本“ 2 _”。最后,有一张打孔卡,提供了最后一位数字的线索:

程序似乎验证了某种SAFE_CODE的最后一位数字等于HOT_FRUITS的数量。

温室里有九个辣椒果实。这些信息给出了保险箱的代码:0329。 打开保险箱得到密码:beaned

第5天:双因素认证

在这个窗口中,我们得到一个包含40501个0和1的文本文件。这个数字恰好可以分解为101和401。如果我们将这些0和1排列成一个401x101像素的矩形,并为它们使用两种不同的颜色,我们会得到一张图像。这可以通过以下代码实现:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#!/usr/bin/env python3

from PIL import Image
p = 101

with open('zeroes-and-ones.txt', 'r') as fin:
    data = fin.read()

q = len(data)//p
assert p*q == len(data)

im = Image.new('1', (q, p))
im.putdata([1 if x == '1' else 0 for x in data])
im.show()

运行此代码得到以下图像:

因此密码是:picturesque

第6天:障碍物

在这个窗口中,我们得到一个鸭子跳过障碍物的视频。每个障碍物由三个块组成,每个块的高度可以是0、1或2。如果我们将每个障碍物视为一个三位三进制数,它们可以给出0-26的数字。实际上,26不会出现,因为那个障碍物无法跳过,但这仍然足以给出英语字母表中的每个字母。我们可以使用以下代码进行转换:

1
2
3
4
5
#!/usr/bin/env python3
import string

obstacles = ['011','120','010','210','111','012','112','202','001','200','221']
print(''.join(string.ascii_lowercase[int(x, 3)-1] for x in obstacles))

运行此代码得到密码:documentary

第7天:数据库

在这个窗口中,我们得到一个图书及其ISBN号的SQL数据库转储。ISBN号有一个校验位,可用于纠错。我们可以遍历每个条目并检查相应的ISBN号是否有效。这可以通过以下代码完成,该代码首先将数据库加载到内存中,查询条目,并打印具有有效ISBN号的条目。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#!/usr/bin/env python3

import sqlite3
import itertools

with open('wishlist.sql', 'r') as fin:
    queries = fin.read()

with sqlite3.connect(":memory:") as conn:
    with conn:
        cur = conn.cursor()
        cur.executescript(queries)
    with conn:
        cur = conn.cursor()
        cur.execute('SELECT name, isbn FROM Book')
        for name, isbn in cur:
            isbn_digits = str(isbn)
            check = sum(w*int(d) for w,d in zip(itertools.cycle([1,3]), isbn_digits)) % 10
            if check == 0:
                print(name, isbn, check)

运行上述代码显示只有一个条目具有有效数字,这给出了密码:subsequent

第8天:仅限开发者

这个窗口将我们带到一个Discord服务器,有一个机器人问三个问题:

我的机构位于哪条街? 这个锁的产品ID是什么? “Tomtefar”的名字是什么?

第一个问题的答案可以在背景故事页面上找到,是“Cooking Lane”。第二个问题的答案可以通过在Discord中启用“开发者模式”,右键单击机器人并复制其ID“1043964628050378813”找到。最后一个答案可以在联系页面上找到,是“Mathias”。通过提交这三个答案,我们被允许进入服务器,在那里我们找到以下引用。

储物柜门打开,露出一个满是灰尘文件的黑暗房间。房间正中央有一个盒子,前面用大字写着“sicily”。

因此密码是:sicily

第9天:在巢穴中

这个挑战是另一个MUD冒险。这次我们在一个5x5的网格中走动,代表一个FAT文件系统。在单元格中运行showcontent命令会给出该单元格的内容。运行getfat 命令会给出提供单元格之后单元格的索引。我们从集群2开始,它给出以下信息:

您在集群2 这是一个文件夹集群,包含: 名称 扩展名 类型 集群 大小 . 文件夹 2 0x0 CRIMES 文件夹 7 0x0

SYNONYMS 文件夹 18 0x0

如果我们走到集群7,我们得到这个信息。文件“CRIME D”很突出,因为它是一个图像。我们可以看到它从集群22开始。

您在集群7 这是一个文件夹集群,包含: 名称 扩展名 类型 集群 大小 . 文件夹 7 0x0 .. 文件夹 2 0x0 CRIME A TXT 文件 11 0x2b CRIME B TXT 文件 8 0x2b CRIME C TXT 文件 14 0x2b CRIME D JPG 文件 22 0xa59 CRIME E TXT 文件 19 0x2b

通过使用getfat命令,我们可以获得需要重新组装图像的集群链。然后我们可以走到这些集群并使用showcontent命令收集数据。然后我们可以使用以下Python代码重新组装文件:

1
2
3
4
5
6
#!/usr/bin/env python3

clusters = {
    23: 'FF D8 FF E0 00 10 4A 46 49 46 00 01 01 01 00 60 00 60 00 00 FF E1 00 68 45 78 69 66 00 00 4D 4D 00 2A 00 00 00 08 00 04 01 1A 00 05 00 00 00 01 00 00 00 3E 01 1B 00 05 00 00 00 01 00 00 00 46 01 28 00 03 00 00 00 01 00 02 00 00 01 31 00 02 00 00 00 11 00 00 00 4E 00 00 00 00 00 01 76 F6 00 00 03 E8 00 01 76 F6 00 00 03 E8 70 61 69 6E 74 2E 6E 65 74 20 34 2E 2E 31 34 00 00 FF DB 00 43 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF DB 00 43 01 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF C0 00 11 08 01 00 01 00 03 01 22 00 02 11 01 03 11 01 FF C4 00 1F 00 00 01 05 01 01 01 01 01 01 00 00 00 00 00 00 00 00 01 02 03 04 05 06 07 08 09 0A 0B FF C4 00 B5 10 00 02 01 03 03 02 04 03 05 05 04 04 00 00 01 7D 01 02 03 00 04 11 05 12 21 31 41 06 13 51 61 07 22 71 14 32 81 91 A1 08 23 42 B1 C1 15 52 D1 F0 24 33 62 72 82 09 0A 16 17 18 19 1A 25 26 27 28 29 2A 34 35 36 37 38 39 3A 43 44 45 46 47 48 49 4A 53 54 55 56 57 58 59 5A 63 64 65 66 67 68 69 6A 73 74 75 76 77 78 79 7A 83 84 85 86 87 88 89 8A 92 93 94 95 96 97 98 99 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 B4 B5 B6 B7 B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA D2 D3 D4 D5 D6 D7 D8 D9 DA E1 E2 E3 E4 E5 E6 E7 E8 E9 EA F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FF C4 00 1F 01 00 03 01 01 01 01 01 01',
    9: '01 01 01 00 00 00 00 00 00 01 02 03 04 05 06 07 08 09 0A 0B FF C4 00 B5 11 00 02 01 02 04 04 03 04 07 05 04 04 00 01 02 77 00 01 02 03 11 04 05 21 31 06 12 41 51 07 61 71 13 22 32 81 08 14 42 91 A1 B1 C1 09 23 33 52 F0 15 62 72 D1 0A 16 24 34 E1 25 F1 17 18 19 1A 26 27 28 29 2A 35 36 37 38 39 3A 43 44 45 46 47 48 49 4A 53 54 55 56 57 58 59 5A 63 64 65 66 67 68 69 6A 73 74 75 76 77 78 79 7A 82 83 84 85 86 87 88 89 8A 92 93 94 95 96 97 98 99 9A A2 A3 A4 A5 A6 A7 A8 A9 AA B2 B3 B4 B5 B6 B7 B8 B9 BA C2 C3 C4 C5 C6 C7 C8 C9 CA D2 D3 D4 D5 D6 D7 D8 D9 DA E2 E3 E4 E5 E6 E7 E8 E9 EA F2 F3 F4 F5 F6 F7 F8 F9 FA FF DA 00 0C 03 01 00 02 11 03 11 00 3F 00 65 14 51 40 0B 4A 29 B4 B9 A0 09 29 A6 93 34 84 D2 18 94 52 8E B4 EF D7 8A 62 1B 4B 83 F9 52 E3 9C 7E 22 82 68 01 B4 51 45 00 1D E8 A5 14 94 00 52 52 D2 50 01 45 18 A5 A0 04 A2 96 8E 7B 0A 00 51 48 69 E1 69 0A F1 40 0C A2 8A 30 68 00 A2 8A 5C 1A 00 29 28 A2 80 0A 28 A5 C5 00 25 48 31 4C 34 66 80 0C 51 8A 71 C5 36 81 B1 28 A7 51 40 86 D1 45 39 71 DE 80 12 94 74 EB 4E C7 3C 7E 54 70 28 00 FE 78 A4 C1 C7 4A 75 27 4A 00 4C 7F 9F 5A 69 EB 4E CD 34 FA D0 02 D2 52 51 40 05 14 52 E2 80 B0 94 B8 A5 A4 A0 AE 5E E1 52 01 C5 47 52 0E 82 80 63 A9 29 69 28 24 88 8C 1A 5F FF 00 5F FF 00 5A 86 EB 47 E3 9A 00 5C 0E BF 43 47 D7 D3 14 60 F6 E2 90 FD 73 40 0D A2 8C 1A 28 01 C0 53 F0 29 80 D2 E6 90 C4 34 DA 53 CD 14 C4 28 A3 1F CE 93 A5 1C D0 36 83 F5 A2 90 D1 9A 04 2D 1D 0D 14 A3 1D E8 01 FF 00 4A 4C E3 3E BD E8 DC 29 01 EB EF 40 0E A4 26 8F 6E 98 A4 3D 70 47 1E B4 00 D3 45 06 8A 00 4A 5C 0A',
    17: '05 14 14 90 B4 52 51 48 61 45 14 50 01 40 38 A2 92 98 99 20 6A 09 ED FA D3 3B D2 8E FF 00 D6 82 45 FE 82 8C 51 9C 0C 9E F4 B4 00 98 CD 03 BD 2D 1C 1C D0 02 74 3F CA 90 9C 0A 5F AE 73 ED 48 47 F9 34 00 DA 28 A5 A0 04 A2 8A 28 01 E0 73 CF 41 4E EB CF 6A 69 39 A5 07 02 90 03 0E 2A 3A 90 9C D3 08 A0 62 51 45 2E 29 85 84 A7 0A 4A 33 40 31 E7 A5 19 F5 FF 00 F5 53 32 68 E4 D0 20 34 94 52 81 9A 00 05 2D 3B 69 A3 6D 05 26 AC 32 8A 93 68 A5 C0 F4 A0 2E 88 E8 C1 A9 31 4B 40 73 11 6D 34 DA 9A A2 23 93 41 2D DC 4A 5A 4A 77 6F 7A 00 5E 
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计