“
又是一个被 CTF 分数按在地上摩擦的赛季。我见过太多这样的选手:平时靶场刷得飞起,一到个人赛就被打回原形,看着排行榜上那些稳定拿分的 ID 直挠头。CTF 拿不到高分,大多数时候不是你不够聪明,也不是你题做得少,而是你的整个过程——从训练到比赛——存在系统性偏差。
这篇文章不打算教你某道具体题的 writeup,而是想把“为什么拿不到分”这件事拆开揉碎讲清楚。我会结合自己这些年打 CTF、带新人、以及看各类个人挑战赛(比如 2025 年冬季个人挑战赛这类赛制)的踩坑经验,给出一套直接能用的改善路径。无论你是刚入门 CTF 的萌新,还是卡在中间分数段想冲前排的老手,这篇文章都值得你花十分钟认真读一遍。
先说清楚一个基本事实:CTF 拿高分,比的不是谁的奇技淫巧多,而是谁在有限时间内用最少的失误拿完该拿的分。理解了这一点,后面所有的问题都好解了。
1. 先别急着刷题,你的精力分配就出了问题
很多人的训练方式是从第一天就有问题。打开一个靶场,注册账号,然后一头扎进 Web 题目里,刷到哪做到哪,做不出来就看 writeup,看懂了就觉得“我会了”。这种刷题方式最致命的地方在于,它让你产生了大量虚假的熟悉感,却没有形成真正的得分能力。
1.1 刷题量不等于得分能力
我见过一个选手,题库刷了小一千道,但每次比赛成绩都很平庸。问题出在他的“刷”毫无结构——Web 题做累了去做杂项,杂项卡住了又跑去瞄一眼密码学,一天下来每个方向都摸了,但每个方向都停留在“会用工具”的层面。
CTF 的得分单位从来不是“刷了多少题”,而是“在赛场上现场解决一个未知题目的能力”。比赛中的题目和你平时刷的靶场题之间,永远隔着一层“陌生化处理”——主办方会换花样、加干扰项、甚至故意在题目里埋陷阱。你平时刷题时的“看 writeup 秒懂”状态,恰恰是得分能力最薄弱的训练方式。
正确的刷题方式应该是按专题横向推进。比如你这一周只碰 LFI(本地文件包含)和命令执行,那就把所有能找到的相关题目全部做一遍,做到看到类似的函数、参数组合就条件反射地知道下一步该测什么。这种横向专题训练,建立的是“识别模式—触发动作”的肌肉记忆,到赛场上看到题目才能快速反应。
1.2 高投入低回报的方向要果断砍掉
这里要泼一盆冷水:不是所有 CTF 方向都适合你投入同等时间。CTF 有四大主流方向——Web、逆向、PWN、密码学,外加杂项。每个方向的天赋门槛、时间投入和得分稳定性完全不同。
新手最容易犯的错误,就是雨露均沾,看到什么火就学什么,最后每个方向都只懂皮毛。带新人的时候我常说一句话:你不需要所有方向都强,你只需要有 1-2 个强项方向,外加 2-3 个能拿基础分的保底方向就够了。
拿个人赛来举例,假设一场 24 小时的比赛总共有 20 道题,Web 和杂项通常占比最大,逆向和 PWN 题量相对较少但单题分值高。如果你在 Web 方向能做到稳定拿分,再补上杂项的常见套路题,你的基础盘就已经很稳了。逆向和 PWN 这种需要大量底层功底的题目,如果当前水平做不到前 30% 的完成率,不如果断把时间挪给提分空间更大的方向。
我见过太多人花了整整一个赛季死磕汇编和堆利用,比赛的时候照样一道 PWN 都做不出来,反而把 Web 和杂项的常规分全丢了。这不是劝退,这是止损。
1.3 把“做过”变成“掌握”的复盘方法
刷题不复盘,等于白刷。但复盘这件事,90% 的人做得不合格——他们的复盘就是"把 writeup 再看一遍",然后合上电脑觉得自己又变强了。
真正的复盘是两个动作。第一个动作是重新独立做一遍:看完 writeup 之后,把题目的环境重新搭起来,关掉 writeup,从零开始做,做到哪一步卡住了再回去看,然后问自己为什么会卡在这里,是思路问题还是知识点盲区。第二个动作是抽象归纳:这道题用了什么套路,前置条件是什么,触发点是什么,把这道题的解题思路压成一条模式化的笔记,下次遇到同类题目直接套用。
给你一个实测有效的工具组合:用思维导图或者表格来维护自己的“解题模式库”,按方向、漏洞类型、工具、识别特征、攻击链五列去整理。比赛前翻一遍,比赛时遇到题直接查库。这个做法看起来笨,但坚持下来你会发现,你的解题速度会明显快过那些靠临时翻 writeup 的人。
2. 比赛里的时间管理:你不是不会做,是来不及做
比赛拿不到高分,还有一个常见原因:时间管理一塌糊涂。尤其是个人赛,没有队友帮你分摊任务,所有题目都要自己啃,时间分配稍有失误,后半程就会全线崩盘。
2.1 拿到题目的前 30 分钟决定你的整场节奏
很多选手一开赛就兴奋,看到哪道题眼熟就直接冲上去做,结果做着做着发现卡死了,一卡就是一两个小时。等回过神来,其他简单题已经被别人交了,你连汤都喝不上。
我的经验是,比赛开始后的前 30 分钟内,不应该急着解题,而是应该把所有题目快速过一遍。按两个维度给每道题打分:一个是你对题目涉及领域的熟悉程度,一个是题目给你的直觉难度(看描述、看附件类型、看交互返回的内容)。然后根据这两项打分,把题目分成三类:第一类是熟悉且看起来有机会的,标记为优先进攻目标;第二类是陌生但题干简单、可能靠搜索或常识能拿下的,标记为第二梯队;第三类是拿眼一看就知道没戏的,直接标记为放弃。
这套筛选动作最大的价值,是帮你避开两个常见陷阱:一是把时间花在了自己其实不擅长的题目上,二是错过了那些其实很简单、只是看起来唬人的送分题。
2.2 卡题 30 分钟的断电法则
不管赛前准备得多充分,赛场上总会遇到卡壳的情况。这时候考验的不是你的技术水平,而是你的情绪管理能力。
我给自己定过一个规矩,也推荐给你:一道题如果连续攻了 30 分钟还没有任何有效进展(连信息收集层面的进展都算),立刻断电,换下一道题。这里说的“有效进展”,不是指“我好像想到了新思路”,而是指你手里已经获得了新的信息,比如一个新的端口返回、一段新的响应头、一个报错信息里的路径泄露——这些才算进展。
为什么要设 30 分钟这个阈值?因为从大赛经验来看,一道题的最佳突破窗口通常在前 30 分钟。30 分钟后,你的头脑已经开始疲劳,思路容易在原有模式里打转,继续硬啃往往会越陷越深。换题之后,大脑切换到新的题目上,原本卡住的思路反而可能在潜意识里自己解开——这就是“酝酿效应”在起作用,你在做下一道题的时候,大脑后台仍然在偷偷处理前面那道题。
2.3 有限时间内的“分值是王道”原则
个人赛不同于团体赛,没有分工就意味着每道题的机会成本都很高。“这题看起来很有意思”和“这题能帮我拿到分”,这两者之间你必须坚决选择后者。
举一个实际例子:一场比赛里给你两道题,A 题是杂项里的一道流量分析,逻辑清晰、手法常规,估计 40 分钟能做完,分值 200 分;B 题是一道偏门逆向,涉及到 VM 混淆,你可能要花两三个小时才能啃下来,分值 400 分。看似 B 题的单位时间回报更高,但别忘了,B 题存在很高的沉没风险——你花了两小时做不出来,等于零分落袋。A 题同样是两小时,你可以做三遍还有剩余。
我推荐的决策模型是:估算完成概率 × 分值的期望 = 决策分,优先做决策分高的题。基础分题目的完成概率你目标定在 90% 以上,进阶题定在 40%-60%,高压题低于 20% 就果断放弃。这样按期望分配时间,比凭感觉做题科学得多。
3. 核心短板:你的知识体系里藏着“看不见的洞”
很多选手平时刷题表现不差,但一到比赛就露馅,原因在于他们的知识体系是“碎片化”的——这里是零散的知识点,那里是孤立的技巧,彼此之间没有串成网。比赛题稍微绕一个弯,直接掉洞里。
3.1 从题目类型反推你需要建立的能力矩阵
拿 Web 方向举例。CTF 里 Web 题常见的考点基本固定在几个大块:SQL 注入、XSS、文件包含、文件上传、命令执行、SSRF、反序列化、中间件与配置问题、源码泄露。每一类考点都有对应的前置知识要求。
比如文件上传,很多新手以为就是绕过后缀名过滤,结果一遇到检测文件内容、检测二次渲染、配合解析漏洞的题目就傻眼。实际上,文件上传考法是有层次的:第一层是后缀名单绕过与黑名单检测;第二层是 MIME 类型检测与内容头绕过;第三层是图片马(图片中嵌入 PHP 代码)、绕过 getimagesize 检测;第四层是配合 Apache/Nginx 解析特性、.user.ini、伪协议实现的组合利用。如果你只掌握了第一层,比赛里遇到第三层自然做不出来——你不是手生,是这块知识在体系里压根没有长出来。
建议你按“考点—前置知识—工具链—常见绕过姿势—题目特征识别”五个维度,把你当前方向的知识体系全部画出来,找到那些标记为“空白”的模块,然后定向补课。这个工作量看起来大,但本质上是在给你自己的地图填上暗区,填完一块,以后遇到这块的题目就是稳定得分区。
3.2 常见赛题的四个“必会套路组”
下面整理四个高频必备的套路组,每一个都是经过多场比赛验证的基础分来源,建议你对号入座查缺补漏。
第一组是源码泄露类。前期开发不规范导致 .git 目录被部署到服务器上是真实世界常见的配置错误,在 CTF 里更是常客。除了用 GitHack 这类工具,你可以先手动测 /git/config 是否能访问,再测 /.git/HEAD,目的都是快速判断是否存在源码泄露。如果确认 .git 泄露,可以从历史提交里翻 diff 文件,很多 flag 就藏在被删除或修改过的代码注释里——这个方法值得熟练到条件反射。
第二组是命令执行类。PHP 里 system、exec、shell_exec、passthru 这些函数一旦参数可控,往往直接就能拿到 RCE。但很多题目并不会把命令执行直接暴露给你,而是会包一层过滤,比如把分号、管道符、空格都过滤掉。这时候就要熟练用 ${IFS} 绕过空格过滤,用 $IFS$9 这种姿势处理变量名拼接,用 /???/??? 这种通配符方式执行命令。比赛现场你可以直接写一个 PHP 一句话后门,把要执行的命令作为参数传进去,测试各种过滤规则到底堵了哪些字符,效率会高很多。
第三组是流量分析类。杂项方向流量分析几乎是必考题,常见套路包括:USB 键盘流量分析(特指 USB 协议中键盘按键事件的 pcap 抓包文件,里面按固定格式记录按键编码,需要解析出按键序列还原为正常字符)、HTTP 隧道木马通信流量、DNS 外带流量(通过 DNS 查询记录中的子域名部分隐藏数据)。这里面 USB 流量分析算是一个经典考法,脚本处理时要特别注意按键编码的映射表(不同的键盘 HID 码对应不同的字符),很多新手在转换表上翻车,导致解出来的字符串完全不对。你可以在赛前备好一段多场景适配的解析脚本,一键输出普通按键和带 Shift 组合的按键序列,能节省大量现场调试时间。
第四组是中间件配置类。nginx 安全加固在 CTF 赛题里经常出现,考的核心是对常见配置缺陷的理解。比如 try_files 配置不当导致源码泄露,alias 拼接导致目录穿越,limit_req 配置失误导致绕过频率限制,等等。解决这类题目,关键在于测试模板里预先收集好的 nginx 常见漏洞 payload,以及掌握 Nginx 解析阶段与测试顺序(先看是否有路径穿越的可能性,再看是否可以利用 $uri 与 $document_uri 的解析差异绕过)。
3.3 禁区提醒:这三类问题,赛场上最容易翻车
这里特别提醒三个我反复踩过的坑,也是带新人时几乎必然翻车的三件事。
第一个坑是盲测。题目下来不读源码、不看附件、不分析响应差别,上来就把一堆 payload 往目标上扔,企图用穷举的方式打穿题目。这种做法不仅效率极低,而且极易触发平台的 IP 封禁或 WAF 拦截,直接把自己锁死在门外。CTF 比拼的是思路的精密度,而不是工具的暴力度——先花五分钟读题、看返回、分析差异,永远比先花五分钟打 payload 要快。
第二个坑是忽略输出点。很多命令执行题或注入题,真正决定成败的不是过滤绕得多漂亮,而是你有没有找到一个可靠的回显点。有些题目给的是无回显注入,就需要你用时间盲注或 DNS 外带来解决。赛前把各种盲注和延迟注技巧过一遍,到了赛场上才不会抓瞎。
第三个坑是排除太慢。进度条推进到一半,明明已经拿到了 shell 或已拿到数据库权限,却卡在“下一步该干什么”上。这个问题的根子在于你没有内化一套常规后续流程——拿 shell 之后先看当前用户权限,再尝试提权;看数据库先列库、再列表、再重点看 flag 相关表;看到 flag 先判断是不是真 flag,不是再检查源码里的隐藏逻辑。把标准操作流程刻进脑子里,能省掉比赛中大量无谓的原地打转。
4. 真实赛场复盘:那些拿分的人到底做对了什么
说了那么多理论,来看一场实际比赛的关键决策链。我拿 2025 年冬季个人挑战赛的典型场景来复盘,假设你是参赛者之一,看看高手和普通选手在相同局面下的分水岭。
4.1 一场个人挑战赛的时间轴拆解
比赛开始前 15 分钟,选手进入等待区。这时候,普通选手在聊天、刷手机;高手已经把本地环境调好——Burp Suite 监听就位、平台页面已登录、常用解码工具已打开,连浏览器代理都已经是工作状态。
前 1 小时,题目放出。普通选手从第一题开始按顺序做,遇到难的也死磕;高手花 10 分钟把所有题目快速浏览一遍,在大脑里给每道题贴标签:这个杂项流量题套路眼熟,分配 30 分钟;那个逆向题看到有 VM 关键词,果断丢到最后再看;Web 题里有一道看着像是 git 泄露,立刻用工具扫一下。做完这个动作,高手已经比普通选手多出了一个完整的全局视角。
赛程中段,普通选手在某道题上已经耗了 70 分钟,情绪开始焦躁,继续硬耗。高手在第 30 分钟时果断换题,先拿下一道 150 分的杂项签到题垫底,回头再看之前那道卡住的题时,思路被新题目里的某个关键词启发——这种“跨题迁移”的启发效果在真实赛场特别常见。
赛程末段,普通选手手里只有一两道题的分,剩下全是半成品。高手已经在基础分稳定的前提下,尝试挑战逆向和 PWN 的高阶题,拿两道里的其中一道,为最终排名冲了一波关键分。
4.2 高手与普通选手的三个核心差距
对比下来,差距集中在三个方面。
第一是目标清晰度。普通选手的目标是“做出这道题”,高手的落点是“拿到这一分”。这个细微的出发点差异决定了后续所有决策——前者会在一道题上较劲,后者永远在权衡时间和分值。
第二是动作效率。普通选手的大部分时间花在“试错”上——试 payload、试工具、试各种参数;高手的动作则来自赛前沉淀的“模式库”——看到这个特征直接进入对应套路,一步到位。同样是解决一道 Web 题,前者可能需要 1 小时,后者 20 分钟就完成了,差距就在这里。这种差距不来自智商,而是来自赛前刻意训练的自动化反应。
第三是情绪维稳能力。CTF 比赛是持续的脑力消耗,越到后面,情绪对认知的影响越大。普通选手一旦连续卡题,就会进入“动作变形”状态——明明简单的命令拼写出错好几次,或者连最基本的 Base64 解码都搞反了。高手有一套自己的“断电—换题—回归”节奏,始终保持同一个稳定的工作频率。
4.3 如何把比赛经验沉淀到下一场
每一场比赛,无论成绩好坏,都是绝佳的样品。但如果你打完只是看看排名就关电脑,这些样品就全部浪费了。
我推荐的赛后复盘姿势是“三道题复盘法”。第一道复盘:那些你做出来的题,记录一下花了多少时间、有没有更优解、哪一步能提速。第二道复盘:那些你没做出来但看完 writeup 后恍然大悟的题,重点记录卡住你的那个“关键认知跳跃”,比如原来那道题要先用 trace 命令查看动态库依赖才能定位核心逻辑。第三道复盘:那些连 writeup 都看不懂的题,汇总成一个“待学清单”,按优先级排入下一阶段的训练表。
把复盘结果写进你的模式库,你就已经完成了从“做完题”到“学到东西”的跨越。
5. 常见问题速查:赛前这十个检查项,帮你稳定涨分
最后分享一份实操价值极高的检查清单。每次比赛前,按这个清单快速过一遍,能帮你避开多数低级失误。
5.1 工具链准备检查
本地环境是否齐备可以直接影响开赛状态。最少必备:Burp Suite(Web 抓包与改包)、CyberChef(编码解码与数据处理)、Wireshark(流量分析)、IDA/Ghidra(逆向静态分析)、Python3 环境(脚本处理与自动化利用编写)、Git 命令行(用于应对部分基于源码的考察)。注意,工具不一定全用上,但你赛前必须确认它们都被配置好了,不会现场装环境浪费时间。
5.2 信息收集标准流程
无论是何种类型的题目,前三分钟永远通用三步:看题目描述与附件备注、试访问目标/运行附件获取基本信息、用 curl 或 nc 查看目标的响应头与握手信息。这三步做完,你要能回答三个问题:对方的系统或语言环境是什么、这道题属于哪个攻击面、有哪些可疑的异常点。答不上来,说明你还没进入做题状态,别急着开打。
5.3 提交 flag 时的低级错误
这一条具体到让人哭笑不得,但真的每年都有大量选手在细节上丢分。flag 提交时注意大小写,注意有没有多余空格,注意平台给的格式(有的平台要求带 flag 前缀,有的不用)。另外,部分平台对重复提交有冷却时间限制,连击提交会导致被判定异常。更典型的场景是:通宵做题到后半夜,眼睛花了,把 0 看成 O,把 1 看成 l,导致明明拿到了正确答案却被判 wrong。建议提交前做一次复制粘贴的二次核对,而不是手动重新输入。
5.4 赛场突发状况的应急方案
比赛期间可能出现的突发状况比你想得多。WiFi 断流、代理失效、平台崩溃、保存失败——每一样单拎出来不致命,叠加在一起足以毁掉你整场比赛的节奏。
给三条建议。第一,随时保持本地草稿的实时保存(比如用 Markdown 编辑器自动保存 + 历史版本功能),所有脚本和命令输入同步到一个云端笔记,避免环境崩溃导致工作丢失。第二,准备好一个备用网络通道,例如手机热点(不需要额外理解成某种代理工具,就是在断网时能迅速切换的网络手段),关键操作时如果主网络异常可以秒切。第三,比赛中途如果平台异常,冷静截屏记录时间与错误信息,赛后以此申诉,千万不要在情绪失控的状态下反复试探导致账号异常。
聊到这里,最后再分享一个我带新人时反复强调的观点:CTF 拿高分本质上是“系统性工程”,它由赛前训练方式、赛时决策模型、赛后复盘机制三块拼图共同组成。大多数人只盯着“做题”这一个环节拼命使劲,恰恰把最影响得分的精力分配和决策逻辑给忽略了。
我自己也曾经是那个一开赛就乱冲、卡困在一道题上坐到天黑的人。后来把这些方法一套一套落实下来,分数才慢慢从两位数爬到排行榜前列。这个过程没有什么不可告人的秘密,唯一称得上捷径的,是你愿意在别人赶路的时候,停下来先把地图画清楚。希望这份总结能帮你在下一次个人挑战赛里多抢回五百分,比什么都实在。