周末两天几乎都坐在电脑前把2025春秋杯网络安全联赛冬季赛个人赛的题从头到尾过了一遍。趁着思路还热把这份“私人WP”整理出来——不是标准答案也不代表官方意图只记录一下我在每个方向上的踩坑和思考路径。如果你正准备打下一站CTF或者想看看一场正规个人赛里到底会考哪些东西这份复盘应该能帮你少走不少弯路。先交代一下赛事结构本人赛一般分五个方向——Web、Pwn、Reverse、Crypto、Misc偶尔会加一个“综合渗透”类题目本质上还是把多个模块拼在一起。冬季赛个人赛的时间线拉得比较紧总共十几个小时中间还要吃饭、休息所以精力分配成了头等大事。1. 赛前准备与个人赛特有的精力分配陷阱别看CTF比赛拼的是技术其实最考验的是“在有限时间内别让自己心态崩掉”。我这次开赛前准备了常规工具链但依然在身边好几个朋友身上看到了同一种状况前两个小时死磕Pwn一道题没出来后面Web和密码学的时间全被压缩最终分数很难看。1.1 个人赛的题目构成与场外准备先简单理一下个人赛常见的题目数量与分值节奏。一般来说Misc和Crypto的题目相对直接单题分值大约在100到300之间Web题可能会有两到四道分值从200到500不等Pwn和Reverse同样如此。冬季赛因为“赛季终章”的属性通常会把压轴题放在Pwn和Reverse上分值最高但难度也成倍增长。我赛前准备的原则很简单上面两个小时的黄金时间优先做Misc和Crypto中间两个小时扫Web剩余时间留给Pwn和Reverse的攻坚。这不是说Web不重要而是因为前两类题目更容易形成稳定得分能先把基础分拿到手心里不慌。另外一个容易忽略的点是“比赛平台本身”。个人赛的题目下发、flag提交、动态分值都在平台上完成建议赛前至少半小时熟悉页面布局。我见过有人在比赛开始后找不到“提交flag”按钮在哪甚至在题目容器启动后不知道去哪里看IP端口白白浪费了差不多二十分钟。类似这种问题非常可惜因为这段时间足够解开一道简单Misc。1.2 我踩过的坑本地环境缺失与工具版本错位我的本机系统是干净的Linux环境但开赛第一道Reverse题就需要运行一个高版本的库。当时我下意识地用系统包管理器装依赖折腾了十来分钟后来才发现直接去题目的容器环境里操作反而更快。这里给个建议赛前一定要准备好Docker环境至少能随手拉起常用镜像。比赛时很多Reverse和Pwn题自带运行环境如果本地缺库果断用远程容器做题别在本地环境里死磕。还有一个典型的版本问题我用的是旧版GDB插件对题目的调试信息解析不够友好花了不少时间去手工看汇编。后来切到新版调试器配合自动脚本效率高了很多。赛前把工具链更新到最新稳定版永远是性价比最高的动作。1.3 时间分配的实际节奏我给自己定的节点是这样的前30分钟快速浏览所有题目把Misc和Crypto的简单题标记出来。第30到第120分钟集中解Misc和Crypto争取拿三到四道题的分数。第2到第4小时处理Web方向优先看信息收集题和逻辑漏洞题。第4小时以后主攻Reverse和Pwn如果卡了超过40分钟就果断换题。这套节奏的核心理念是“持续得分”。CTF个人赛不看你单题多强而是看总排名。一道500分的Pwn题啃三小时没出来不如用同样时间拿下两道200分的Web和一道150分的Crypto。这听起来像废话但真到比赛时候很多人就是忍不住要和某个难点杠到底。2. Web方向信息收集、逻辑漏洞与“框架隐藏分”Web题在个人赛里往往不是难度最高的但却是最考细心的。冬季赛的Web题整体风格偏“贴近实战”有些题目包装了一个完整的业务场景像“某管理系统”“某论坛”普通扫描一顿乱打是拿不到分的关键在于读懂代码和业务逻辑。2.1 信息收集不是扫目录那么简单很多刚接触CTF的朋友拿到Web题的第一反应就是跑目录扫描然后盯着后台路径发呆。但这次比赛的Web题里真正有用的信息藏在响应头、注释、JS文件甚至报错页面里。我记得一道模拟后台登录题页面本身没有入口最后是在前端JS文件里发现了一段被隐藏的接口路径访问后才出现真正的登录框。所以做Web题时我建议按这个顺序来先看页面源码、响应头、Cookie、JS文件收集所有可访问的接口。再用目录扫描补充重点是api、admin、upload这类敏感路径。遇到参数就多试几个值别只盯着字符串型参数数字型参数也许藏着越权。信息收集阶段的核心是“不要只用一个工具跑完就完”要结合自己的逻辑判断。比赛里很多考点其实就是某个接口的“存在”本身发现了突破口后面就是顺水推舟的事。2.2 一道模拟题从登录口到后台的逻辑利用有一道Web题给了源码下载是一个很常规的后台管理系统。我第一眼看到的是登录代码里做了一个校验但没有限制登录失败的次数。当时我没有选择无脑爆破而是先去读用户表初始化的SQL文件果然后台里有一条测试账号的记录密码字段是明文MD5。用在线工具解出密码直接登录整个过程不超过十分钟。这道题并不是传统意义上的漏洞利用而是考察“你是否会去读源码里自带的初始数据”。比赛方特意在注释里写了一段提示大意是“开发者图方便留了测试账号”。如果你只盯着暴力破解可能坑坑洼洼折腾一小时还可能触发封禁机制。另一道题则更接近真实的越权逻辑登录一个普通用户后发现修改个人资料的请求里带着用户ID字段。把ID改成另一个数字后直接就能看到别人的手机号。这类题目的考点非常明确——服务端没有对用户身份做二次校验完全信任前端提交的ID参数。解题时只需要把请求改成另一个ID再观察响应差异就行。我们在写WP的时候常常会把这类题描述为“低危逻辑漏洞”但在CTF里它就是实打实的分数。平时做业务系统代码审计时这种漏洞也最容易被忽略因为这些地方没有“危险函数”靠的是对业务场景的理解。2.3 WAF与绕过的边界在哪里有一道题的环境里带了简单WAF会拦截一部分包含关键字的内容。很多人的第一反应是找各种编码方式绕过但我建议你先停下来想想WAF是否真的需要绕过我在这道题上花了将近四十分钟尝试了各种大小写混合、注释符、Unicode编码结果发现全部被拦截。后来回到题目描述发现这道题要的是“伪造认证头”跟WAF半毛钱关系没有。WAF的存在只是虚张声势真正的考点在另一个接口。这个经历让我意识到千万别题目越做越上头先回归题目本身确认攻击面。如果确认就是要绕过WAF也要先观察拦截规则不要直接上全套混淆。规则往往只拦截某几个关键词你用别的方式表达同样语义就过去了。CTF里允许做这种模拟环境下的绕过练习但在实际生产环境里绕过防护不是我们该做的事发现漏洞后应该走正规上报流程。比赛题目只是把攻防技术放在隔离开的靶场里这一点要分清楚。3. Pwn与Reverse动态调试器比静态看代码更高效Pwn和Reverse是很多人又爱又恨的环节。冬季赛这两个方向一共出了好几道题我个人的直观感受是难度曲线比前几个赛季更平滑前几题甚至能让你体验到“秒杀”的快感但压轴题确实需要极强的底层功底。3.1 栈溢出题目如何快速定位溢出点Pwn方向的第一道题是一个很基础的栈溢出程序从标准输入读固定长度到栈缓冲区然后直接调用一个危险函数。常规做法是用调试器定位偏移构造返回地址跳转到后门函数。我写了一个简单的Python脚本来自动生成不同长度的输入通过崩溃日志快速确定偏移避免手工数栈帧。关键操作流程大概是这样checksec查看程序保护状态确认是否有栈保护和NX。用调试器在危险函数调用点下断点观察栈布局。输入有序字符模式让崩溃位置暴露出偏移量。计算目标函数地址与偏移构造payload。第一题没什么复杂的花活分数线下来就十几分钟的事。但第二题的难度就上来了程序开启了栈保护而且没有后门函数需要先泄漏地址再控制流程。这里最难的是“泄漏地址”的步骤我尝试了几种输入最后用格式化字符串把栈上残留的返回地址打印了出来。这类技巧在Pwn题里非常常见建议新手先熟练掌握格式化字符串的读取能力它比直接学堆利用更实用。3.2 逆向题的花指令与反调试手法Reverse方向有一个题目很搞笑程序开头跑了一大段无意义的寄存器翻转看起来像是在做AES初始化其实只是花指令。我一开始傻乎乎地用静态分析工具慢慢看结果越看越迷茫。后来直接把程序丢进调试器动态跑在关键API函数比如比较函数上下断点很快就拿到了正确输入。这里要分享一个经验Reverse题不要只依赖静态分析。很多程序为了增加难度会插入无效数据、控制流平坦化、反调试检测你盯着汇编读半天不如让程序自己跑起来。动态调试时留意几个关键点检查程序是否调用了ptrace()一类的系统函数如果是需要用脚本绕过。在字符串比较函数或自定义校验函数下断点观察栈上的输入和期望值。如果程序有反调试可以先尝试用调试器插件自动绕过不行再手工修补二进制。我这次遇到的一个反调试其实只是检测“进程名”里是否包含调试器前缀简单改个名就躲过去了。这类防护在CTF里更多是“劝退”作用而非真的不可逾越别被吓到。3.3 我常用的工具链路和一点心得Pwn和Reverse方向我的工具链路如下工具用途我的习惯checksec查看二进制防护拿到题先跑一遍GNU调试器及插件动态调试反向断点、漏洞分析反汇编工具静态分析看程序结构找主逻辑Python脚本库交互构造payload本地测试、远程打包我不建议在比赛里临时找新工具因为每个工具的快捷键和输出格式都需要适应。平时就固定使用一套比赛时闭着眼睛都知道下一步该点哪里。比赛外训练时可以故意给程序加上花指令再练习快速定位主逻辑这种方式比单纯刷题更有效。4. Crypto与Misc这些“送分题”也最考验基本功Crypto和Misc在个人赛里经常被视为“送分题”但“送分”不等于“白给”。冬季赛的Crypto题整体偏基础但有一道题如果不知道某个函数的默认参数你就只能干瞪眼。Misc更是把隐写、编码、流量分析都串在了一起考验的是综合信息提取能力。4.1 古典密码与现代密码的“一眼识别”Crypto部分的古典密码题出题人给了密文和一堆提示。比如看到只有大写字母和数字下意识就应该尝试栅栏密码、维吉尼亚密码或者十六进制转ASCII。我通常会把密文先丢进识别脚本快速判断编码类型而不是手动一个个试。现代密码题更适合用已知的本地模块直接解RSA的小公钥指数攻击、相同模数攻击、选择密文攻击等都是常见考点。冬季赛里有一道RSA题给出的公钥指数非常大一看就是需要做Wiener攻击用现成脚本改一改就出来了。这里的关键是能否从公钥参数里看出攻击类型这个能力只能靠平时积累。我还想特别提一个细节很多CTF题目喜欢在描述里放一段看似无关的话其实那就是提示。比如有个题的描述是“安全工程师喜欢把秘密藏在时间戳里”对应的就是从时间戳里提取种子再生成序列号。阅读题目描述本身就等于拿了一半分。4.2 图片隐写和数据包分析的解题节奏Misc题里最经典的自然是图片隐写。我的固定套路是先用strings看有没有可见字符串。再用文件分析工具看文件尾有没有附加数据。然后用LSB隐写工具提取最低有效位。最后如果图片特殊命名或尺寸不对考虑修改宽高再重新保存查看。有一道题目给了张风景图用常规查看方式发现不了任何东西但用脚本提取LSB后得到一段Base64解码后直接是flag。这类题做多了基本是机械化流程。流量分析题则更看重“耐心”。打开数据包后不要急着翻先看统计列表找流量最大的IP和端口。许多隐蔽传输会放在DNS请求里一点点把数据拼起来。我记得这次有个流量题隐藏信息就分散在一堆正常的HTTP请求里每次响应时间字段的值对应一个字符抽出来拼接后就是flag。这种题没有太高深的算法就是看你能不能想到“把看似随机的字段当作编码”。4.3 写脚本时的编码意识解Misc和Crypto时写的脚本多半是一次性脚本但仍然要有工程意识。我的习惯是先写一个处理字节的函数统一处理bytes和str的转换。每步处理都打印中间结果方便回溯。不要把题目里的密文直接作为十六进制硬编码而是从文件读取。上次比赛我就吃过亏题目给的密文是一个文本文件我用系统自带编辑器打开后不小心把换行符复制了进去结果解密一直失败后来才发现是字符串末尾多了不可见字符。从那以后所有从外部文件读数据我都用二进制方式打开再手动strip()。5. 赛后复盘哪些能力是真正值得长期投入的比赛结束不等于学习结束。打完一场个人赛最大的收获往往是暴露出的能力短板。我这次最大的感触是技术面再广也抵不过“稳定输出”这四个字。5.1 比赛分数之外的能力图谱如果不用分数来看我会把个人赛能力拆成三个维度工具熟练度能不能快速启动工具、配置环境、编写辅助脚本。知识广度是否知道各类漏洞和算法的存在以及它们大致长什么样。做题心态卡题时能不能果断止损能不能有条理地推进。第三个维度最容易被人忽视但恰恰是最影响总分的。我见过太多人前两个维度很强却因为某个环节卡住导致整场比赛节奏崩掉。建议平时训练时模拟比赛环境给自己设置“40分钟必换题”的规则刻意练习止损能力。5.2 如何在平时训练里复现这类赛题很多朋友会问我赛后想复现题目去哪里找环境我的建议是先看官方是否公开源码和部署镜像如果公开直接本地搭建。如果没有公开也可以根据题目描述的关键词到其他开源训练平台搜索类似题目。复现的时候不要只照着WP敲一遍。更好的做法是不看WP重新独立做一遍并记录用了多少时间。把自己的解题脚本整理成模板下次遇到同类型题目直接调用。把题目涉及的考点写进自己的知识清单比如“修改请求中的ID参数测试越权”“检查文件尾部的附加数据”等。复现的意义不在于拿到flag而在于把“偶然解题”变成“必然能力”。我自己会把同一道题隔一周再做一次看自己是不是真的记住了关键思路还是当时只是跟着WP走流程。5.3 给新手的建议不要只盯着高难度题我知道很多人打比赛时特别喜欢“硬刚”压轴题觉得解出来很有成就感。这没问题但如果你还在积累阶段我更建议把时间花在基础题上。原因很简单基础题覆盖了最常见的考点练习性价比极高。比如一道栈溢出题乍一看简单但它涉及的调试、偏移计算、栈布局理解是后面理解堆利用的必需品。另外别怕写WP。写WP的过程就是复盘的过程能把脑海里模糊的思路变成清晰的语言。每场比赛结束后我都会逼自己把做出来的题和卡住的题都写一篇记录。这个习惯让我在后续比赛中遇到类似问题时能快速回忆起上次的解法而不是重新踩坑。最后再分享一个小技巧比赛过程中随手记一个“题目进度表”记录每道题的打开时间、卡点、尝试过的方向。赛后复盘时这张表比任何官方题解都珍贵因为它还原了你当时真实的思考轨迹。希望这份个人记录能对准备打下一场CTF的你有点帮助。赛场见。