是的,我又来 W4terCTF 出题了!今年除了 Pwn 题以外,我还和 APJifengc 准备了一道 Minecraft 相关的 Misc 题「心理念写」。
题目内容
Misc — 心理念写(Hard / 6 Solves / 823 pts)
我这是在做 MisC!才、才不是在玩什么 Minecraft 呢……
题目分发了一个压缩包 thoughtography.zip,包含一个简单的 Minecraft Paper 服务器 Docker 镜像,其中需要注意的是 plugins/Thoughtography-2026.jar。这个插件没有提供源码,但是只有一个类,用市面上的反编译插件可以轻松读懂内容。
1 | package team.w4terdr0p.thoughtography; |
分析代码可以知道:
- 插件在启动时从配置中读取
flag。 - 在玩家触发
PlayerTeleportEvent事件,传送原因为UNKNOWN,且传送距离大于 10 格时可以得到 Flag。 - 提供了一次任意命令执行机会,只禁用了
gamemode和op两个命令。 - 世界初始化禁用了昼夜和天气循环,禁用了命令方块,生成了初始平台,基本没有其他限制。
另外,还有一些 server.properties 中值得注意的设定。
1 | difficulty=easy |

代码审计
题目的目标十分明确。UNKNOWN 实际上是默认的传送原因,找到 Paper 中没有正确处理的传送链,只要找到一条符合传送要求的链,再编写实现该传送的命令即可得到 Flag。
在出题过程中,我们找到了三条可能触发对应传送要求的链,我们给它们分别取一个名字。
- 耕地链. 玩家在耕地上跳跃时,有机会将耕地转化为泥土。由于泥土的方块高度比耕地高一些,服务器会把玩家向上传送一小段距离,这个传送的原因为
UNKNOWN。 - 骑乘链. 玩家在骑乘在一个实体上。当那个实体传送时,玩家会被带着传送,对玩家的这次传送原因为
UNKNOWN。 - 末地链. 玩家通过末地传送门从末地回到主世界时,如果没有触发终末之诗,这次传送的原因为
UNKNOWN。
其中,耕地链
挑战
由于 Minecraft 服务器消耗的资源较多,本题最终采用了预约挑战的形式,选手可以通过预约客户端在网站上预约。

在放出的 78 个可预约时间段中,共有 23 个被预约,其中 6 支队伍成功攻破本题!真的非常感谢大家。
骑乘链
在解出的队伍中,有 3 个队伍使用了骑乘链。
我们出题时使用的命令如下。核心思路是生成一个船和末影珍珠,并把末影珍珠的 Owner 设置为船。然后在末影珍珠掉下来之前,乘船逃跑,实现 10 格以上的传送。
1 | /use execute summon acacia_boat positioned ~ ~99 ~ summon ender_pearl run data modify entity @s Owner set from entity @e[type=acacia_boat,limit=1] UUID |

一血队伍采用的是类似的命令,但是多生成了一个潜影贝用来接末影珍珠,这样就不用乘船逃跑了。
1 | /use execute summon oak_boat run execute positioned ~ ~15 ~ summon shulker run execute positioned ~ ~200 ~ summon ender_pearl run data modify entity @s Owner set from entity @e[type=oak_boat,sort=nearest,limit=1] UUID |
二血队伍没有使用 execute,只使用了一条 summon,配合 Passengers 也实现了类似的利用思路。
1 | /use summon minecraft:area_effect_cloud ~ ~2.5 ~ {Duration:0,Age:0,WaitTime:0,Passengers:[{id:"minecraft:oak_boat",NoGravity:1b,UUID:[I;9,9,9,9]},{id:"minecraft:ender_pearl",Motion:[0.0d,3d,0.0d],Owner:[I;9,9,9,9]}]} |
六血队伍使用的命令也类似,在此不再赘述。
末地链
相较于骑乘链,末地链的利用则更为有趣一些。根据前面的分析,只要从末地返回主世界两次,就可以实现要求。而要从末地无限制返回主世界,最容易想到的方法就是打龙了!
我们预期的一个简单解法如下。通过三个带有末地传送门的矿车,在主世界打掉第一个,把剩下两个放进末地。由于玩家传送到末地出生点平台时,平台上的方块会被清空,包括我们放的末地传送门。所以我们需要先在末地放第二个传送门,穿过回到主世界,然后回到末地放下第三个传送门,再次穿过完成利用。
1 | /use execute summon armor_stand summon armor_stand summon armor_stand at @e[type=armor_stand] run summon minecart ~1 ~1 ~1 {Passengers:[{id:"falling_block",BlockState:{Name:"end_portal"},Time:-20000}]} |
三血队伍采用了类似的思路,不过少了一个末地传送门。要实现利用则需要 roll 一个较好的末地出生点,开船把第二个传送门送离出生点,这样就不会被清空。
1 | /use summon minecraft:oak_boat 0 9 1 {Passengers:[{id:"oak_boat",Passengers:[{id:"falling_block",BlockState:{Name:"end_portal"}}]},{id:"falling_block",BlockState:{Name:"end_portal"}}]} |

四血队伍选择打龙(需要 roll 一个出生点非封闭的种子),通过箱子矿车给自己准备了十分强大的弓箭,以及末影珍珠用于移动,成功拿下末影龙,并走两次末地主岛传送门得到 Flag。这个队伍原本还打算用末影水晶把龙蛋炸下来,不过貌似是因为冒险模式没能成功放下末影水晶。
1 | /use summon chest_minecart ~ ~1 ~ {Items:[{Slot:0,id:bow,components:{"enchantments":{power:255}}},{Slot:1,id:ender_pearl,count:16},{Slot:2,id:arrow,count:64},{Slot:3,id:end_crystal,count:64}],Passengers:[{id:falling_block,BlockState:{Name:end_portal}}]} |

五血队伍也选择了打龙,不过他们的命令……
1 | /use setblock ~ ~ ~ minecraft:end_portal |
没错,这一队选择了开挂打龙。

大哥不喜欢末影珍珠,直接飞怎么了?大哥不喜欢开挂刷神器,直接上手打怎么了?裁判进服时被大哥 KA 狂殴,忘关就是开了?实际上开挂也在我们的预期里,不过实际看到还是十分难绷。
另外,我们还考虑了一些可能的方案,不过比较好笑。比如,生成三个末影人,然后……慢慢等他们放下手中的末地传送门。需要 roll 一个末地平台全封闭的种子,防止末影龙在等待过程中来打扰。(不过这个方案并没有成功实践过,等得太累了。)
1 | /use execute summon enderman summon enderman summon enderman as @e[type=enderman] run data merge entity @s {carriedBlockState:{Name:"end_portal"}} |
后记
由于题目太有节目效果(特别是末地链),我原本还打算剪一个视频发布,但是因为太蠢了没有装 Replay Mod,很多通过时刻也没有开 OBS 录制!为数不多录制下来的片段实际看的时候发现画质十分差,检查 OBS 设置发现我还用着国赛画质呢??那还说啥了,不录了!

和我出的其他大多数题目类似,「心理念写」也是一个超能力,作用是预知未来,并以摄像机等媒介成像。本题使用一条命令后,还需要做许多别的工作,对应了 Flag 中的 snap the unknown future in one shot,也就是用一条命令为之后要做的操作铺垫,令人忍俊不禁。(大概如此吧,我扯不动了。)
我自认为本题既有传统的审计,又有新颖的体验,应该能让大家玩的开心吧!不过就在这五个月间,听说有另一场新手赛出了许多 Minecraft OSINT,最后呈现到本场比赛的效果是许多人看到 Minecraft 就吓哭了。看到有些队伍赛后后悔没看过题目内容,还是有些遗憾的。
不论如何,明年如果有机会我还会出有趣的 Misc 题的,下次再见!