CTF设计指南

admin 2025年7月8日11:36:02评论8 views字数 14623阅读48分44秒阅读模式

活力无限,科技无界点击关注👉 #猕猴桃实验室

一起在网络技术里遨游

CTF 设计指南

字数 11780,阅读大约需 40分钟

本文汇集的观点源自 ESPR 的 niklasb 和 tsuro、TokyoWesterns 的 icchy、Tasteless 的 fox、MeePwn 的 l4wio、HITCON 的 orange、TeamBaguette 的 StalkR、albinowax 的反馈与想法,以及 Google CTF 组织者的贡献。部分设计灵感源于 Selinker 和 Snyder 所著的《Puzzlecraft》一书。

挑战设计 (Challenge Design)

CTF 竞赛的核心是在竞争环境中创造性地解决信息安全问题。参赛者需要在广泛的、与安全相关的领域中比拼创造力、问题解决能力和速度。

与在线靶场不同,在 CTF 中,玩家无法跳过无聊的任务,也不能仅仅因为觉得没意思就决定不去解决它。为了赢得 CTF,参赛队伍被迫解决每一个挑战,因为如果其他队伍已经解决或很可能解决这些挑战,他们就会获得更高的分数。这意味着,一个糟糕的挑战就可能毁掉一场原本有趣的比赛,因此要求 CTF 组织者在任务设计和实现的质量上格外用心。

设计模型 (Design Models)

向玩家呈现问题的方式有几种不同的设计思路。这些方式(称为模型)会给玩家带来略有不同的体验,每种模型在真实性和范围限定方面各有优势。

效果/方法模型 (Effect/Method Model)

一些 CTF 任务遵循效果/方法模型。玩家会被呈现一个“效果”(Effect),这代表他们必须达成的一个明确目标(通常附带具体的组件列表),然后玩家需要去发现一种“方法”(Method) 来制造这种效果。

这些术语借鉴自魔术界,例如效果可能是预测一副牌中的某张牌,但实现方法可能有多种(如所有牌都一样、记牌/默记牌序等)。采用此模型构建 CTF 任务的特点在于:任务通常是开源的,范围被严格限定,并且常常(但不总是)允许存在多种可能的解法。

探索模型 (Exploration Model)

一些 CTF 任务遵循一种模型,即随着玩家逐步解决任务,挑战的不同部分会逐渐显露。这类任务通常是黑盒测试或侦察任务,目标是引导玩家逐步发现挑战的各个部分直至最终解决。

探索任务的范围应限定得足够窄,以便玩家能以合理的节奏取得进展,并应向玩家留下“路标”,让他们知道自己正走在正确的道路上。单步骤的探索任务通常旨在让玩家根据任务提供的信息,对现有工具进行微调来解决。

混合模型 (Hybrid Model)

混合两种模型也是可行的,即玩家需要先发现解决任务所必需的组件,然后在集齐所有组件后再解决任务。

此模型更贴近现实生活中的黑盒渗透测试,但同样需要将范围限定得足够窄,以确保在分配的时间内可解。

任务生命周期 (Task Lifetime)

设计挑战时,作者需要考虑玩家可能体验该挑战的方式。以下是任务解决生命周期的简化抽象描述,包含了玩家在特定时间点寻找的具体信息。请注意,现实中玩家会在这些阶段来回切换,有些任务可能没有某些阶段(或非常短暂),但按此思路思考任务解法,是为了确保任务中包含了需要传达给玩家的所有必要信息。下文详述的几个阶段是:

  1. 1. 发现 (Discovery)
  2. 2. 初步评估 (Triage)
  3. 3. 本地复现环境搭建 (Local Reproduction Setup)
  4. 4. 研究 (Research)
    • • 反混淆 (Deobfuscation)
    • • 分析性问题解决 (Analytical Problem Solving)
  5. 5. 利用 (Exploitation)

发现 (Discovery)

在发现阶段,玩家会对任务进行初步评估,以弄清它是什么(发现“未知的未知”),并开始构建某种与挑战交互的方式,以便后续通过试错进行实验。

初步评估 (Triage)

此阶段的目标是快速理解系统的整体设计,并确定任务的类型。玩家应能快速、在脑海中、直观地进行威胁建模并理解应用。

通常,在此步骤玩家会决定是现在处理此任务,还是稍后处理(或根本不处理)。玩家在此阶段应能回答的问题类型包括:

  • • 我能访问什么?
  • • 我不能访问什么?
  • • 最直接的第一步是什么?
  • • 是否有指向第一步的线索?
  • • 最终目标是什么?
  • • 玩家知道 flag 在哪里吗?
  • • 需要哪些技能/经验?

作为任务作者,除了帮助玩家尽可能多地回答关于挑战设置的上述问题外,还需警惕一些警示信号,例如:

  • • 任何错误的开端或误导性信息: 误导玩家并不能测试他们的创造力或问题解决能力。故意包含这些信息有挫败玩家并降低任务投资回报率 (ROI) 的风险。
  • • 问题空间过大,不适合竞赛: 如果挑战范围过大,玩家找到正确起点的可能性将更依赖于运气而非技能或创造力。
  • • 所需信息分散在多个地方: 如果重要信息没有相互关联,一些玩家可能意识不到他们正试图用不充分的信息来解决任务。

本地复现环境搭建 (Local Reproduction Setup)

玩家通常希望有一种能在本地测试挑战或以更方便的形式交互式处理任务的方法。因此,玩家常常会开发一些自动化工具来辅助任务的调试和研究。

此阶段通常决定了玩家在后续挑战中的体验。玩家在此阶段应能回答的问题类型包括:

  • • 我可以使用哪些工具与此任务交互?
  • • 此设置与实际挑战有何不同?

此阶段最危险的问题是存在非默认的自定义设置,玩家可能无法根据现有信息推断或理解。因此,需要避免的警示信号有:

  • • 非常规配置: 如果这对挑战是必需的,并且直接给玩家配置作为线索会泄露解法,那么问题应尽可能严格限定范围,使玩家明确发现此配置本身就是待解决的挑战。另一个重要方面是,自定义配置可能误导玩家走向错误方向,让他们误以为挑战内容与设计意图不同。
  • • 高启动成本: 某些情况下,任务作者可能拥有玩家不太可能拥有的资源。在这种情况下,创建测试挑战方法所需的时间成本可能非常高。

研究 (Research)

在研究阶段,玩家在积极“解决”任务。它包括两个子阶段:反混淆(Deobfuscation)(主要涉及逆向工程某些组件的行为)和分析性问题解决(Analytical Problem Solving)(主要涉及审视所有组件并运用灵感找出利用它们达成目标的方法)。

反混淆 (Deobfuscation)

此阶段的目标是连接发现阶段和分析性问题解决阶段。玩家将利用他们掌握的信息,找出他们可能还需要但尚未拥有的信息。通常,此阶段需要一些技能和实践才能高效完成,但新手通常只需更长时间也能度过此阶段。玩家在此阶段会提出的问题包括:

  • • 为什么它会这样运行?有什么特别之处?
  • • 这个实现有什么不安全或不同寻常的地方?
  • • 这是如何工作的?是什么让它这样工作?
  • • 我应该关注哪里?应该深入探究哪里?

在某些情况下,发布应用程序的源代码可以帮助向玩家证明,应用程序中没有其他值得关注的内容。而在另一些情况下,发布源代码实际上可能迫使玩家检查应用程序中的每一块功能(即使与任务无关的部分),从而混淆玩家。通常,开源多少代码的平衡点在于作者如何把握,以尽可能将玩家的注意力集中在任务上,同时避免制造误导。

此阶段最明显的问题是范围。过大的二进制文件或具有庞大代码库的应用程序,如果玩家对下一步没有明确指导且在该领域经验不足,可能会让他们不知所措。因此,需要牢记的主要警示信号是:

  • • 范围 (Scope): 如果能在不使任务过于简单的前提下,帮助玩家将搜索空间限制在最小必要范围内,那将是理想的做法。否则,简单的线索或任务的其他组件限制搜索空间也能有所帮助。
  • • 时间 (Time): 识别那些在规定时间内极难分析的组件非常重要,或许需要寻找方法使其分析速度更快。

分析性问题解决 (Analytical Problem Solving)

此阶段的目标是发现代码或设计中的漏洞。玩家应在理解应用程序及其主题领域的前提下,能够发现问题。

这是任务解决过程的高潮,也可能是最重要的部分。如果玩家未能到达此阶段(即寻找漏洞),则意味着他们未能理解任务的要点。一旦玩家到达此阶段,他们会自问如下问题:

  • • 这个系统的弱点是什么?
  • • 从这里出发,这是正确的路径吗?
  • • 我是否还需要其他目前没有的东西?

任务作者可以通过限定范围、并在可能时留下“路标”来强化玩家对其进展的理解,从而帮助玩家回答这些问题。作者应警惕的一些警示信号包括:

  • • 存在太多漏洞,但只有部分相关: 这会浪费玩家时间在非生产性工作上,限制了竞争性工作的总量。
  • • 具有非常规/非默认设置的挑战: 如果玩家为了发现漏洞,不得不对任务环境配置进行盲目假设(例如,如果环境被修改导致某些攻击无效,玩家可能因为不知道环境被修改而放弃一个漏洞),这可能成为问题。

未告知玩家的挑战环境修改会严重干扰研究过程,甚至使任务无法解决。另一方面,提供过于详细的挑战环境信息可能会过多地提示解法。作者需要平衡这两个问题,使任务不包含误导信息,为解法路径提供足够的清晰度,同时不泄露过多信息而使挑战过于简单。

利用 (Exploitation)

此阶段的目标是最终利用漏洞。玩家在发现问题并理解后,应能够利用该漏洞。任务的这一部分也可能极具创造性和复杂性,但也常常只是一个编码任务。玩家在此阶段更有可能向作者寻求帮助,因为他们基本上已完成任务,只需要获取 flag。玩家在此阶段提出的问题类型包括:

  • • 我的本地设置与远程服务器之间有何区别?
  • • flag具体在哪里?
  • • 我有足够的时间/资源获取 flag 吗?

如果玩家在此阶段卡住,可能会极其沮丧,尤其是在比赛临近结束时。因此,作者必须特别注意以下警示信号:

  • • 基础设施问题或本地化网络问题: 需要为玩家提供监控和 24/7 支持。
  • • 过度不必要的、手动重复的非创造性工作: 如果任务的最后阶段涉及手动工作,可能会毁掉一个原本有趣、引人入胜的挑战。
  • • 令人意外的 flag 格式/位置: 按照惯例,flag 通常位于 /flag~/flag 文件中,或数据库中的 select flag from flag 查询结果中。任何其他位置(如隐藏文件、自定义二进制文件等)都应向玩家妥善说明。

希望此阶段的结果是获取 flag,并且在此阶段对基础设施的任何更改/修复都必须妥善通知所有队伍。

设计考量 (Design Considerations)

体验 (Experience)

挫败感是玩家处理任务时常有的情绪,但人们参赛不是为了感受挫败,而是为了在经历一段挫败后获得成功的感觉。如果一个游戏没有挫败感,往往会很无聊;如果挫败感过多,则游戏会太难或过于依赖猜测。

在某些情况下,可以通过问题结构、图形、故事或挑战主题为玩家构建更复杂的体验。例如,在游戏过程中向玩家揭示惊喜,或在挑战中嵌入谜团。对于线下 CTF,有时还可以利用物理空间,为玩家提供更独特的实体体验。

任务的界面需要让玩家产生兴趣立即开始玩,保持足够长时间的注意力以理解挑战组件,然后开始解决它。优秀的界面使挑战更直观且不碍事,它们改善了体验,并使玩家在挑战中卡壳时的天然挫败感不那么痛苦。

灵感 (Inspiration)

玩家会花费一定时间,在一个相对受限的搜索空间中通过试错探索可能的解法。如果空间过大,或者玩家最终卡在与任务无关的问题上,都会导致挫败的体验。

为了优化挑战,玩家需要在下一步尝试什么方面获得灵感。“顿悟时刻”(A-ha moments) 出现在玩家获得关于下一步尝试的新颖想法时。一个挑战的乐趣程度取决于任务需要多少灵感以及任务需要多少工作量。

任务所需 ⬇️+➡️
工作量少
工作量中等
工作量大
工作量过大
灵感少
非常简单
轻松
令人失望
无趣
灵感中等
容易
令人满意
有趣
令人疲惫
灵感多
令人惊喜
富有见地
具有挑战性
非常困难
灵感过多
依赖猜测
令人沮丧
非常令人沮丧
不合理

积极灵感 (Positive Inspiration)

积极灵感需要玩家可能认为自己拥有或未拥有的知识,以及他们实际拥有或未拥有的知识。这常常带来令人满足的“顿悟时刻”,使 CTF 挑战充满乐趣。

在某些情况下,玩家需要学习新东西;而在另一些情况下,玩家必须重新评估他们已知的事物,以发现如何利用它们做新的事情。

玩家所需知识⬇️+➡️
他们实际知道
他们实际不知道
认为自己知道
显而易见,简单
令人惊喜,困难
认为自己不知道
富有见地,困难
具有教育意义,有趣

消极灵感 (Negative Inspiration)

消极灵感是指那些无法以积极方式缓解挫败感的灵感。玩家在 CTF 期间将被迫经历此过程,并理所当然地抱怨它,因此避免这些问题很重要。

需要消极灵感的挑战示例包括:

  • • 需要玩家不感兴趣领域的知识和灵感的挑战(例如“自学梵语”)。
  • • 以理解作者的心思/思维过程为核心的挑战(例如“猜猜我把便士藏哪儿了”)。
  • • 即使不是必要手段,猜测也可用作解决挑战捷径的挑战(即“具有猜测表象”)。

复杂度 (Complexity)

一个挑战的复杂度可能体现在两方面:要么是少量简单组件以出人意料的方式相互作用;要么是大量复杂组件及其复杂的交互必须被用来解决问题。

当挑战的要点是与更大集合中的一小部分简单组件交互时,隐藏其他组件以避免分散玩家注意力通常是有用的。也许可以将挑战设计为两个阶段:第一阶段发现目标范围内的组件,第二阶段利用它们解决问题。

当玩家需要面对大量组件进行选择时,更重要的是在过程中设置检查点,让玩家知道他们处于正确的轨道上。或者,例如,如果挑战的要点是发现一种通过自动化将这些众多组件拼凑起来的方法,那么一个线索可以是添加如此大量的组件,使其显而易见地表明这些组件并非需要逐一查看。

总体而言,如果玩家卡住并决定休息或放弃挑战,原因不应是他们认为任务在规定时间内无法解决,而应是因为他们认识到自己缺乏解决问题的关键见解。然而,一个常见的问题是游戏中的干扰项(red herring)让玩家误以为必须解决一个与设计意图不同的问题。如果故意设置,这可能会严重(且负面地)破坏玩家的体验,尤其是当它无法解决时。

其他设计考量 (Other Design Considerations)

为 CTF 选择任务时,可能需考虑以下方面:

  • • 真实漏洞 (Real Vulnerabilities)
  • • 挑战多样性 (Challenge Diversity)
  • • 专业知识与资源 (Specialized Knowledge and Resources)
  • • 挑战复用与多 flag 任务 (Challenge Reuse and Multi-flag Tasks)
  • • 计分系统 (Scoring Systems)

更多细节如下。

真实漏洞 (Real Vulnerabilities)

通常,任务的预期解法要么是受影响软件中的 0day,要么发现 0day 的可能性比预期解法更大(例如处理已知有漏洞的软件时)。这会与玩家产生利益冲突,因为用 0day 解决挑战可能会向组织者披露该 0day,并迫使玩家在某种程度上妥协(积分或披露实践)。

真实漏洞的另一个常见问题是,有些挑战纯粹是实现针对已知漏洞的利用程序。此类任务依赖于该漏洞没有公开利用程序,并鼓励玩家开发它。这引发了围绕漏洞利用程序共享的类似问题,尤其是因为发布 CTF 任务解题报告 (write-up) 的做法通常会导致利用程序泄露。

挑战多样性 (Challenge Diversity)

队伍需要花费时间评估任务,以确定他们是否有队员能处理这些任务。如果 CTF 的设置使得只有队伍中的少数队员能够参与,而其他人只能闲置,这会降低队伍参与的积极性。

除了专项 CTF(如仅限逆向工程类),大多数 CTF 都高度多样化,玩家期望找到多种类别和难度的挑战。因此,需谨记某些考量:

  • • 类别多样性 (Diversity of categories): 不同的玩家擅长且感兴趣于不同类别的挑战(如 Pwn、Crypto、Web、逆向工程)。因此,如果未提前宣传,可能会出现玩家预留时间参赛,却发现没有他们感兴趣的挑战可解的失望情况。
  • • 难度多样性 (Diversity of difficulty): 如果 CTF 中所有或大部分挑战都很简单,可能会偏向特定时区的队伍和队员众多的队伍。另一方面,如果所有挑战都很难,则对新手不够友好,只对顶尖经验队伍有利。因此,平衡任务难度或提前宣传 CTF 的目标受众,将有助于玩家规划并决定是否参与。
  • • 挑战标注 (Labelling of challenges): 对任务进行分类或标注(如难度、类别、预期解决时间或其他信息)可以帮助玩家优先处理某些挑战。这有助于队伍在队员(新手或专业玩家)之间更好地评估挑战。

专业知识与资源 (Specialized Knowledge and Resources)

CTF 任务的范围被设定为在分配时间内可解。如果它们给予所有队伍相似的起点(或让玩家有机会提前准备),则对新手更公平,因为玩家能够根据自身现有经验选择是否参与,或在比赛开始前学习将要测试的领域。

因此,如果某些任务假定玩家具备某些先验知识,那么缺乏这些知识就意味着玩家需要在短时间内学习它。如果在比赛期间获取这些知识不太可能,那么这个挑战可能节奏太慢了。

这意味着,如果涉及现有软件的任务能提前通知玩家,使他们能够为此做准备,而不是只让恰好熟悉该技术的队伍受益,那么所有队伍都有机会研究该特定技术,或寻找具有此类经验的队员。

同样存在一些可能需要拥有专业设备或资源的任务,它们存在类似的担忧,尽管在这种情况下,它们可能歧视财力较弱的玩家。需要大量资源(如计算能力)来解决,或利用专业设备更容易解决的任务,会使某些队伍受益。因此,如果预期解法假设队伍在分配时间内拥有大量计算资源可用,一些玩家可能会觉得不公平。

挑战复用与多 flag 任务 (Challenge Reuse and Multi-flag Tasks)

由于任务作者通常也是 CTF 玩家,将一项比赛的挑战稍作修改后用于另一项比赛很常见。原因可能是存在非预期解法,或者只是相同想法换了个样子。这会带来关于队伍公平性的问题。当任务以某种形式(全部或部分)复用时,会产生一些问题,例如:

  • • 参加过两次比赛的玩家将比未参加过的玩家略有优势,因为某些评估和研究工作无需重复。
  • • 关于非预期解法,由于任务通常范围严格限定,很可能存在关于该解法的解题报告(可能使用不同语言或未明确提及该任务)。
  • • 许可可能是个问题,因为任务可能未被授权复用(无论是否修改)。

与需要其他知识的任务类似,一个合理的折衷方案是提前(在比赛开始前)向玩家指明作为灵感来源的任务,或尽可能避免复用。

另一个问题是任务原始解法可能会分散玩家注意力(因为它本质上变成了一个多 flag 的任务)。包含多个 flag 的任务即使标注得当,也可能使玩家困惑,因为任务的“探索”阶段和线索可能会混淆方向——当两个 flag 的线索交织在一起时,玩家无法分辨哪个线索对应哪个 flag。

另一方面,如果挑战设计为顺序解决(先解决 A,再解决 B),则会显著高估一组任务相对于其他任务的价值(因为解决第一个任务不仅获得其本身的分数,还获得了它所解锁的所有任务的潜在分数)。

计分系统 (Scoring Systems)

计分系统有多种变体,各有优缺点。静态计分 (Static Scoring)、一血奖励 (First-blood Bonus)、动态计分 (Dynamic Scoring)(按解决时计分 vs. 每次解决后重新计算分数)、竞速赛 (Speedruns)(奖励最先或最佳解决任务的队伍),或需要先解决其他任务的任务。根据 CTF 的不同,这些会显著影响比赛的动态和公平性。

任务的分数定义了其价值,因此通常将更多分数分配给更困难的任务是合理的(假设 CTF 的目标是找出能解决最难问题的队伍)。分配任务分数的方式有多种,如下所述:

静态计分 (Static Scoring)

静态计分是指任务分数由组织者提前设定(如 100, 200, 300, 400, 500)。这是传统的 Jeopardy 式计分系统,需要广泛的测试和特定的挑战设计,以严格控制任务的难度。可以说,这在资源或经验有限的情况下难以实现。

一血奖励 (First-blood Bonus)

成为第一个解决任务的队伍,可以激励队伍尝试新任务或优先处理尚未解决的任务。这创造了更多样化的积分榜,并增加了任务至少被一支队伍解决的可能性。另一方面,根据任务发布时间(及其难度),这可能为在线比赛制造不公平的情况。然而,对于线下 CTF,由于参赛队伍较少(意味着某些任务未被解决的可能性更大),且队伍起始时间更一致,时区带来的不利影响较小,尽管在选择更快或更易的挑战上仍存在一定的运气成分。

动态计分 (Dynamic Scoring)

动态计分是指队伍因任务获得的分数由解决该任务的队伍数量决定。这可以通过递减计分 (Declining scale)(第一个解决的队伍得 500 分,第二个得分更少,第三个更少,依此类推)实现,或者每次提交后为每个队伍重新计算分数 (Score recalculation)

动态计分的主要优势在于,它利用解决任务的队伍数量来发现任务的实际难度。这使得组织者能够减轻非预期解法或任务比预期更难的风险。

定义分数随时间变化的公式通常由组织者提前设定,可以是线性的(例如,每次提交扣 50 分),或基于更复杂的公式(例如,对数公式)。但其缺点是要求组织者预先了解或推测参赛队伍数量及其技能水平。

对数公式 (Logarithmic formula)

定义对数公式有几种方法,这里提供一个在 100-500 分范围内使用对数衰减形式的示例: ,其中:

  • • P 是给定 S 次解决后获得的分数。
  • • K 和 V 是根据不同难度任务的预期解决次数计算的变量。

我们假设:1 次解决 = 500 分,最简单任务为 100 分,中等难度任务为 300 分。变量 K 和 V 用于拟合符合该形式的曲线,计算步骤如下:

  1. 1. 定义最简单任务(100 分)的预期近似解决次数。设为 e
  2. 2. 定义中等难度任务(300 分)的预期近似解决次数。设为 m
  3. 3. 计算 V 和 K

示例:假设预期解决最简单任务的队伍数为 125 (e=125),解决中等难度任务的队伍数为 20 (m=20),则:

因此公式  可直接嵌入竞赛评分系统中,而实际情况需要根据自己需求而动态调整。

分数重算 (Score recalculation)

动态计分最常见的变体是每次任何队伍解决任何挑战时,都重新计算每个队伍的所有分数。这可能导致一次 flag 提交影响另一支队伍的排名并降低其分数。

这种计分形式的主要缺点是,它需要在每次提交后重新计算大多数队伍的分数,在大量队伍不断解决简单任务的情况下,可能导致某些基础设施的扩展问题。

递减计分与竞速赛 (Declining scale (and speedruns))

动态计分的一个变体是递减计分模型,分数在提交时计算并授予。此模型显著有利于最先解决非常容易挑战的队伍,这极大地惠及任务发布时所在时区醒着的队伍,以及幸运地最先找到简单任务的队伍。这种情况下的主要激励是成为第一个解决任务的队伍,使 CTF 更像一场竞速赛 (speed run)。

多阶段任务 (Multi-stage Tasks)

需要先解决另一个任务的任务,可能会无意中影响比赛机制。原因可能是动态计分会高估后期 flag 的价值,或者因为这些任务本身价值更高(详见下文计分系统部分)。这也可能导致一个简单任务隐藏在已损坏的任务之后,从而加倍放大了任务问题的风险和影响。

操作考量 (Operational Considerations)

在理想情况下,玩家完全不需要组织者的介入。但实际上,玩家很可能需要与组织者互动,无论是预先安排的形式(例如,挑战需要人工干预),还是寻求支持的形式(例如,玩家需要帮助或发现问题)。组织者在比赛期间应始终有人可用并被授权做出决策。他们还应具备问题升级途径(例如通过呼叫另一名组织者)。本节列出了一些最常见的操作考量以供规划,但总需要一定的判断力,组织者必须有办法在出现分歧或不确定性时做出决定。

挑战发布计划 (Challenge Release Schedule)

何时发布挑战需要平衡多方利益。

  • • 在比赛期间缓慢发布任务,限制了拥有大量队员队伍的优势。
  • • 在较长时间内发布任务,使组织者能够确保有足够周期尽早修复损坏的挑战,而不必同时修复许多问题。
  • • 然而,缓慢发布任务可能会影响某些队伍解决任务的时间,具体取决于他们的时区。在 24 小时内同步任务发布(例如,第一天发布一半,第二天发布另一半)可以减轻此风险。
  • • 缓慢发布任务可能无法给队伍足够时间在规定时间内审阅和处理任务,因此更困难的任务通常应比更简单的任务更早发布。
  • • 缓慢发布任务会使队伍优先处理任务变得更难,这会围绕非预期解法和损坏任务引入一种奇怪的“元游戏”。

理想情况是向玩家保持透明,提前告知预计发布多少挑战以及何时发布。并制定此类计划时考虑时区挑战。

攻击与作弊 (Attacks and Cheating)

或许不足为奇,安全竞赛必须应对针对基础设施的主动攻击、参赛者的作弊行为,以及单纯寻求破坏比赛的捣乱者。

攻击类型多种多样,从拒绝服务(针对积分榜、任务、IRC 频道,或线下 CTF 的网络),到主动利用漏洞窃取 flag,或绕过组织者的控制,或简单的作弊(flag 交易、为仅限线下 CTF 提供远程帮助等)。

处理这些问题的首要方法是确保队伍了解规则。主动提醒玩家,并向玩家展示规则正在被积极执行,表明组织者对此很重视。如果规则隐藏在网站上,组织者似乎一开始就不知道或不关心它们,那么就会招致违规行为。

话虽如此,总有人会在某个时候尝试做些事情。准备好扩展基础设施、修复漏洞、进行快速紧急修复,与启动比赛本身同样重要。主动的自动化监控(及妥善的日志记录),以及关注玩家的投诉,对于在问题严重干扰比赛前识别并解决问题是必要的。

规则执行可能会在社区中引起一些争议,但执行规则是组织者的主要责任。

线索与提示 (Clues and Hints)

任务比预期更难的情况很常见。因此,组织者通常会准备提示 (hints),在比赛期间发布给玩家,以确保任务在比赛结束前至少被解决一次。另一方面,对于某些任务,其范围足够大,作者会在任务中留下线索 (clues),以便让玩家知道他们正朝着正确方向前进。

线索 (clue) 和提示 (hint) 的区别在于:

  • • 线索 (Clue) 旨在告知玩家他们走在正确的道路上,但不会向他人提供任何额外信息。
  • • 提示 (Hint) 旨在推动玩家在挑战中取得进一步进展,使他们跳过任务中可能过于困难的某个组件。

一个提示可能是发布源代码(从而移除逆向工程组件),一个线索可能是将一个文件命名为 flag.txt,让玩家知道他们拥有正确的漏洞类型。

所有提示和线索应同时传达给所有玩家。 私下仅向单个或一小部分玩家透露关于任务的信息(无论是作为线索还是提示)都是不公平的。示例:

  • • 如果一名玩家联系组织者询问是否允许暴力破解服务器,组织者回应“那对你没帮助”或讽刺地暗示这是错误方向,这将被视为其他玩家没有的线索。
  • • 如果一名玩家联系组织者索要任务代码,组织者回应代码已是开源的,这甚至可能被视为提示,因为访问代码可以排除大量可能的解法。
  • • 如果一名玩家抱怨挑战损坏,并解释了他们迄今为止的尝试,但组织者打断他们说挑战运行正常,这可能成为玩家方向错误的线索(因为组织者没让他们说完)。

一般而言,当组织者与玩家进行 1 对 1 互动时,预先定义好要询问玩家的问题列表,并避免进行活跃的来回交流,以减少信息泄露是有益的。任何线索和提示都应专门且同时向所有人发布,切勿私下仅透露给部分玩家。

实施问题 (Implementation Problems)

开发安全的软件很难。但开发仅有一个漏洞的不安全软件更难。因此,挑战常常存在功能或安全方面的实施问题,它们可能以不同方式干扰比赛。组织者应对这些问题的方式是比赛的关键方面。

损坏的挑战 (Broken Challenges)

玩家很难区分损坏的挑战和困难的挑战,尤其是在损坏非常微妙的情况下。因此,组织者必须在发布前、发布后不久以及队伍提出要求时随时测试所有挑战。

如果出现任务被证明是损坏的情况(未做测试、测试不充分或任务遗漏关键信息),组织者必须决定如何处理。如果任务完全损坏且完全无法解决,修复它并通知队伍挑战已更新是好的做法,但通常队伍直到可能为时已晚并浪费太多时间空转时才会意识到任务损坏。

另一个问题是,如果任务仍可通过猜测或利用其他漏洞解决。这可能导致在修复任务或保持原样之间产生艰难的冲突。一个可以通过猜测解决的损坏任务,很可能导致对整个 CTF 的负面评价。最终,需要做出决定来平衡 CTF 的趣味性/教育性与其竞技性。

非预期解法 (Unintended Solutions)

避免非预期解法非常重要,因为它们会破坏原本有趣的挑战。它也让猜中非预期解法的玩家有更大机会解决它(他们可能认为挑战过于依赖猜测)。

虽然无法完全防止非预期解法,但充分的准备能显著降低其可能性。因此,审阅并简化挑战设计尽可能多地进行测试最小化不必要的组件数量隔离沙盒化风险组件以及使用更安全的库和编程语言都有助于减少任务中出现漏洞的可能性。

当发现非预期解法时,组织者可能直到比赛结束后(或永远)才听说。这意味着必须预期每个任务都可能被非预期解法解决。非预期解法不同于损坏的任务,因为在非预期解法的情况下,任务仍然可以通过预期方式解决,但对存在非预期解法的损坏任务的应对措施是相同的。非预期解法可能比预期解法更容易或更难。如果一支队伍向组织者通报了非预期解法,这会给通报的队伍带来优势,因为(假设他们的唯一动机是积分)他们只会在自信能用预期方式解决任务时才会通知组织者;而如果组织者做出任何更改,那么通报的组织者的队伍可能会获得优势。实际上,由于队伍可以在比赛期间的任何时间点(比赛中期或许多队伍解决后)通知组织者,这会给比赛引入一个可能破坏公平性或给其他玩家造成不公平印象的“元游戏”成分。

可能的应对措施 (Possible Actions)

组织者有多种处理方式,各有优缺点:

  • • 修复任务,并扣除所有已解决该任务队伍的分数:
    • • 优点:将任务恢复到预期状态。不惠及以非预期方式解决任务的队伍。
    • • 缺点:以非预期解法解决任务的队伍可能认为这不公平,尤其是如果更改发生在这些玩家已转向其他任务之后。可能不公平地惠及报告非预期解法的队伍。以预期方式解决任务的玩家可能认为这不公平,因为他们没有这种优势(因为修复可能向修复后开始玩的玩家暗示漏洞位置)。
  • • 更新任务但保留当前解决记录:
    • • 优点:如果非预期解法带有运气或一次性成分,更新任务可以为所有队伍(包括新玩家)提供规范该行为的能力(例如,如果挑战在比赛开始时以非预期方式更容易解决,但对后来的队伍更难,组织者可以让新玩家也获得平等机会)。
    • • 缺点:如果任务修复了非预期解法,这对错过使用它的机会的队伍不公平。如果任务稳定了非预期解法(使其成为可重复的解法),这对以预期方式解决任务的队伍不公平。
  • • 发布修复了该漏洞的第二个任务:
    • • 优点:技术上等同于拥有两个任务。
    • • 缺点:实际上使该任务的分数翻倍。第二个任务可能泄露非预期解法所在位置的信息,这是原始玩家所没有的。
  • • 不做任何处理:
    • • 优点:对所有人同样公平。
    • • 缺点:任务未能展示/教授预期的问题。如果任务只能以非预期方式解决,该任务可能过于依赖猜测。

决定采取何种措施通常需考虑非预期解法是否在提交任何 flag 之前被发现,以及是由组织者自己还是由玩家发现的。

应对措施 任务状态
修复使任务变易
修复使任务变难
任务未解 通常做法是修复任务。

 但这略微不公平,因为在修复前尝试解决的队伍,可能比其他队伍花费了更多时间。
通常做法是不修复任务。

 因为玩家可能已在任务中取得进展,修复它可能给新队伍带来劣势。
任务已解 通常做法(但有争议)是不修复任务。

 修复它非常不公平,因为解决它的队伍失去了基于率先尝试的时间投入。
通常做法是:

 要么发布修复了漏洞的第二个任务(可能不公平并虚增任务价值),要么清除分数并修复任务(可能不公平且意外改变分数)。

⚠️对于已解决的任务,将其修复变难可能不公平。其含义在于,一支发现了两种解法(预期和非预期)的队伍,可以通过在比赛后期竞争队伍没有时间以预期方式解决时通知组织者,来操控积分榜使其对自己有利。

轮流机制 (Turn Taking)

某些挑战可能要求队伍轮流解决。原因可能是它们需要有限的资源,或者需要工作人员 (STAFF) 手动干预。提前定义轮流的后勤工作(如频率或冷却时间)非常重要。通常,需要轮流的挑战必须提供足够的轮流机会让每支队伍都能解决任务。如果一个预期由 1000 支队伍解决的任务需要手动干预,且预计最多需要 100 次尝试,那将使其无法在合理时间内解决。因此,设计任务时必须考虑参与者数量和解决挑战可能需要的尝试次数。在某些情况下,甚至可能需要配给或节流,以免耗尽资源。

带 XSS 机器人的 Web 任务 (Web tasks with an XSS bot)

需要 XSS 机器人的挑战的一个常见问题是,它们必须设计为 XSS 机器人可以独立于任务进行扩展,但这在流程早期并不总能被认识到。

这是因为某些任务可能需要在请求之间保持状态(例如一个硬盘驱动器),如用于跟踪文件或会话,这在单一服务器上更容易实现。但 XSS 机器人必须能够扩展到任意数量的机器。

设计良好的 XSS 机器人是创建一个可用于跟踪提交的任务队列。如果队列增长过大,只需添加更多服务器即可。将队列按任务(如果可能,按队伍)分开是个好主意,这样单个垃圾任务或队伍就不会减慢所有人的队列速度。

节流保护(工作量证明 (proof of work)、验证码 (captcha)、队伍轮流等)是防止基础设施不堪重负的好方法,但它们也可能给玩家带来非常沮丧的体验。平衡这一点的一种方法是,仅在队列等待时间(队列中最旧项目的时长)超过某个限制(例如 1 分钟)时才启用节流保护,否则禁用它。这可能导致不同时区的玩家体验不同,并可能破坏一些未预料到此类保护的自动化工具,因此玩家应始终知晓节流保护的存在。

带硬件组件的线下任务 (Offline tasks with a hardware component)

线下 CTF 通常包含一些带硬件组件的挑战。这些挑战可能非常独特,但需要显著更多的准备工作和应急预案。此类挑战的示例包括:

  • • 向玩家提供他们必须攻击的硬件,但其中包含一个假 flag,要获得真 flag,他们需要在另一台设备上重复攻击。
  • • 挑战本身只有一两个硬件设备,这意味着无法为每位玩家提供一份副本,因此玩家轮流尝试该挑战实例。
  • • 挑战需要组织者某种形式的监督(例如防止作弊)。

这些任务存在以下风险:

  • • 硬件可能(意外)损坏,必须有足够的备用时间和资源。
  • • 如果硬件在比赛中途损坏,那么任务可能无法为所有玩家提供公平的访问机会。
  • • 如果一个挑战损坏,在 CTF 中途移除该任务对已解决的队伍不公平,而保留它则对未获得公平机会的队伍不公平。
  • • 队伍可能获得不均衡的信息(例如,如果简报或设置对每个玩家不完全相同,或存在任何错误)。如果玩家被计时,甚至可能在解决过程中任务损坏,这可能要求暂停计时器(因为他们无法继续),但这可能给队伍更长时间思考解法。

带现场演示组件的现实任务 (Real-life tasks with a stage presentation component)

设置带有演示组件的任务(例如 pwn2own 风格),存在一些挑战,例如:

  • • 分散玩家解决其他任务的注意力: 如果不断有演示,会使玩家很难专注于其他任务。如果队伍座位靠近舞台、对着灯光或靠近扬声器等,这种情况会进一步加剧,可能更损害他们的机会。
  • • 允许无限次重试的轮流机制会导致其他队伍延误: 例如,如果一个队伍的漏洞利用程序只有 10% 的可靠性,他们可以多次重试直至成功。这降低了演示的相关性,如果不加以限制,可能会减少其他玩家的可用时间。
  • • 不允许无限次重试的轮流机制迫使队伍优先处理这些任务(即使分值不高): 例如,如果引入 1 小时“冷却期”,这可能使玩家在比赛的最后 1 小时无法使用该任务(因为那是他们的最后一次尝试)。这迫使队伍优先解决此任务,以便最后一小时用于其他任务。

如果引入了带有演示组件的任务,玩家会期望组织者解决这些问题。

本文属于译文,编者力求各方面尽量保持与原作者表达一致,但鉴于编者水平和时间有限,在编写过程中难免存在疏漏、不足之处,敬请各位读者批评指正。

 

原文始发于微信公众号(哆啦安全):CTF设计指南

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年7月8日11:36:02
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   CTF设计指南https://cn-sec.com/archives/4231941.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息