资讯动态

CTF校赛全方向解题复盘:从隐写分析到栈溢出的实战经验

发布时间:2026/10/17 13:46:32 来源:尧图企业网站定制
1. 比赛概况与赛制复盘1.1 这场比赛是什么盘面提到网络与信息安全校赛CTF圈子里的同学应该都不陌生。这次某高校的第一届网络与信息安全校赛属于典型的校内选拔赛主要目标就是筛出有潜力参加省级和国家级CTF竞赛的种子选手。整场赛事持续了大约8小时采用Jeopardy解题式赛制题目按照Web、Pwn、Reverse、Crypto、Misc五个方向分布难度从入门到进阶梯度拉得比较开。我拿到比赛题目清单的时候第一印象是出题人确实花了心思。总共14道题其中Web 4道、Misc 4道、Crypto 3道、Reverse 2道、Pwn 1道。这个比例在校内赛中非常典型Web和Misc占大头因为它们对新手友好能保证大部分参赛者有参与感Pwn和Reverse偏难主要用来区分高阶选手。从实际得分分布看Misc和Crypto的得分率最高Pwn则几乎只有个位数的人做出来这一点和大多数高校CTF校赛的难度曲线基本一致。为什么要聊赛制因为校赛和校外公开赛的做题策略完全不同。校赛题目数量少、题型集中意味着你不需要像打大型CTF那样疯狂抢时间刷分更重要的是把每道题读透。比如这次Misc里有一道流量分析题许多同学一上来就想着套用各种自动化脚本反而忽略了题目文件名中暗示的“USB流量”关键词结果绕了一大圈。说白了校赛考的不只是技术面还考你读题和定位问题的能力。1.2 出题倾向与考察重点从这几道题能看出出题人非常看重基础功没有故意出偏题怪题。Web方向围绕SQL注入、文件上传、反序列化、SSRF四个经典考点展开几乎就是照着OWASP Top 10的常见漏洞打的Crypto方向则清一色是古典密码和简单现代密码的变体比如维吉尼亚密码、RSA低指数攻击Reverse和Pwn题目明显借鉴了主流CTF平台的经典题型但降低了保护机制的门槛比如Pwn题直接关闭了PIE和栈保护目的是让第一次接触Pwn的同学也能在调试器里看到清晰的溢出点。我给准备打校赛的同学一个建议不要一上来就死磕0day或者研究冷门漏洞先把每道题的标准解法吃透。比如RSA的低加密指数攻击网上模板一大堆但如果你不知道原理是e很小导致明文m的e次方小于模数n、直接开e次方就能取回明文遇到变形题目照样抓瞎。校赛的考察核心不是你知道多少漏洞而是你能不能在一个干净的环境里把经典漏洞从识别到利用的完整链路走通。2. 分方向解题经验从Misc到Crypto2.1 Misc方向信息隐写与流量追踪Misc杂项在校赛里通常承担“开胃菜”的角色但千万别小看它。这次Misc四道题覆盖了PNG图片隐写、压缩包伪加密、USB流量分析、音频频谱隐写四个典型场景。我按顺序做下来最直观的感受是Misc做题的核心其实是“文件敏感度”的培养。第一道图片隐写题给了一张看起来正常的风景图。我当时的操作流程是先用binwalk扫一遍看有没有附加文件再检查文件尾部是否有多余数据最后用StegSolve逐通道查看图像。结果就是在Red plane 0通道里看到了一串若隐若现的字符——这是典型的LSB隐写把信息藏在像素最低有效位里。这种题在线上平台烂大街但考场里因为紧张不少人直接打开图片看了一眼就跳过了这就是“文件敏感度”不够的典型表现。第二道压缩包伪加密题更考验耐心。压缩包显示有密码但用暴力破解工具跑了好几分钟没跑出来。后来我手动修改了压缩包头部加密标志位重新解压就直接拿到内容了。伪加密的原理很简单ZIP文件在压缩目录区有一个两位的加密标志位改成0x0000就能绕过密码校验。这道题其实是个提醒——很多“密码”根本不需要破解先判断是真加密还是伪加密能省下大量时间。第三道USB流量分析题最有代表性。PCAP文件里全是USB HID数据包懂行的人立刻会想到键盘流量。这里的关键是把8字节的USB报文中的按键值提取出来对照USB HID键码表还原成键击序列。我用了现成的脚本把数据包里的Shift键状态和按键值一起做了映射还原出一段完整的键盘输入里面就藏着flag。这道题如果没接触过USB协议会一头雾水但只要知道HID报文的结构其实就是个体力活。音频频谱隐写题则考的是信息隐藏的多样性。打开音频文件、播放一遍听到的是一段白噪音。放进Audacity看频谱图发现高频区域有一段明显的摩尔斯电码图案。照着频谱图把点和横划出来翻译成ASCII码就是flag。这类题目在大型CTF里经常以“音频图像”双隐写的形式出现校赛只用了单层算是给选手留了条活路。2.2 Crypto方向识别加密模式是关键Crypto方向是我个人觉得这届校赛最有教学价值的部分。三道题分别对应维吉尼亚密码、RSA低加密指数攻击、AES的ECB模式字节翻转难度呈阶梯状。维吉尼亚密码那道题给出了密文和密钥长度提示7我直接用了Kasiski检验法确认密钥长度再用重合指数法逐位移确定密钥字母最后解密出明文。新手做古典密码最容易犯的错是死记硬背解密脚本却不明白为什么要算重合指数。实际上重合指数是用来衡量一段文本中字母分布均匀程度的指标英文文本的重合指数约为0.065而随机文本约为0.038通过这个差异就能反推出密钥长度。RSA低加密指数攻击那道题更经典。题目给的公钥文件里e3模数n有1024位但密文c明显短于n。看到这个条件直接想到m^3 n这个判定条件用gmpy2库对c做三次根号开方flag就出来了。这道题的原理解释起来很通俗如果明文m的三次方还没有模数n大RSA加密后得到的密文c就等于m^3本身根本不需要模运算那就直接开方还原。要是m稍微大一点还可以用循环遍历k*nc再开方的思路这是同一类攻击的变体。AES的ECB模式字节翻转题考的是对分组密码工作模式的理解。ECB模式下每个16字节分组独立加密所以只要我们篡改某个分组的密文只会影响对应分组的解密结果不会波及其他分组。题目给了一个加密后的cookie服务端会解密并检查其中的身份字段我通过翻转密文特定字节把普通用户变成管理员拿到了flag。这道题我印象很深因为很多同学明明知道ECB模式有这个问题但实际操作时搞不清字节偏移翻了半天都没翻对最后发现是自己数错分组位置了。2.3 Web方向信息收集决定成败Web四道题覆盖了SQL注入、文件上传、PHP反序列化、SSRF。整体难度不高但陷阱不少。SQL注入题是个登录表单我习惯性地先试了单引号结果页面直接报错说明存在字符型注入。用order by探测出3列再union select把当前库名表名字段名依次拖出来flag就藏在users表里。整个过程行云流水但前提是你对SQL语句的拼接逻辑足够熟悉。我个人建议新手的练习路径是先手工注入再上sqlmap两条腿走路才不会沦为工具人。因为一旦遇到参数被WAF过滤的情况你只有懂底层原理才能手工绕过。文件上传题比较刁钻前端校验了文件扩展名后端却没做二次校验。我抓包改了后缀名成功上传了含一句话木马的图片马然后通过蚁剑连接拿flag。这道题考察的是“前端校验只是摆设”这个经典认知但同时也暴露了不少选手的一个盲区——他们习惯用现成的Webshell工具却不愿意看一眼上传包里Content-Type和文件名的对应关系导致连绕过前端脚本这一步都没想到。PHP反序列化题则给了完整的源码审计点通过阅读代码发现一个__destruct魔术方法会拼接文件路径并读取文件。构造序列化字符串时重点是控制对象属性和触发链的入口。这类题在校赛里算中上难度需要你对PHP魔法函数的调用时机非常敏感。连我这种做了几年Web的人第一次也会把__toString和__destruct搞混实际做题时多想一步当前这个操作触发了哪个魔术方法它能不能被我们前端输入控制。SSRF题给了一个图片抓取功能输入URL就能请求远程图片并展示。我试着把URL改成内网地址目标是读取内网中某台主机的敏感文件。这道题的关键是绕过URL解析限制比如用十进制IP代替域名、用302跳转等方式让服务端去请求内网。它不需要多高深的技术但考察你能不能跳出“输入框只能填网址”的思维定势——这其实是一种非常基础的安全思维。3. 核心赛题深度复现逆向与Pwn的完整思路3.1 逆向题从静态分析到动态调试逆向方向的两道题是我这次写WP最想详细展开的部分因为它们的解题思路完全可以迁移到未来的比赛里。第一道是个简单的ELF程序运行后要求输入一串字符如果正确就输出flag。拿到文件后我先用file命令确认架构和位数再用strings命令直接搜索可见字符串——结果什么都没搜到。这说明字符串被加密或者运行时动态生成了必须走静态分析。我打开IDA分析主函数逻辑发现程序把用户输入逐字节与一个固定数组做了异或然后和内存中的密文比较。因为是逐字节异或而固定数组的值可以通过动态调试拿到我直接把数组和密文dump出来写了一段十几行的Python脚本做异或还原flag就到手了。这里有个实用技巧如果题目没有去掉符号表先用F5看伪代码找逻辑如果手动分析太费时间用Ghidra做Decompile辅助理解比纯汇编快得多。第二道逆向题加了UPX壳。看到upx字样我本来打算用upx -d直接脱壳结果发现文件被改过标准脱壳报错。这个情况在CTF里很常见出题人故意魔改了壳的特征让你不能一键脱壳。我的做法是手动调试在OllyDbg里单步跟踪找到popad后跳转到原始入口点OEP然后dump内存。步骤说起来简单实际操作时最大的坑是找OEP的时机——跟快了还没解压完跟慢了程序已经开始自修改。好在题目本身没开反调试花十几分钟也就过了。逆向题目给新手的核心启发是不要怕汇编也不要过度依赖自动化工具。脱壳和定位关键函数的本质都是“搞清楚程序的控制流”而这些能力只能靠一次次调试积累。3.2 Pwn题理解崩溃点与利用思路本届唯一一道Pwn题是个典型的栈溢出。题目直接给了源码核心是一段不安全的strcpy拷贝漏洞一眼就能看到。然而真正上手做的时候没有Pwn基础的选手还是会卡住因为栈溢出利用的每一步都有细节。我当时的操作流程是先checksec看保护机制确认只开了NX非可执行栈没有开Canary。题目又给了system函数的地址这意味着我只需要把返回地址覆盖成system的地址并把参数设置成“/bin/sh”字符串的地址。确定偏移量用的是cyclic命令生成特征字符串用gdb跑崩之后通过崩溃地址算返回地址的偏移——实际算出来是112字节。之后构造payload112字节填充 system地址 4字节占位 “/bin/sh”地址。题目环境是32位程序参数通过栈传递所以extra的4字节是返回地址占位。这条利用链路在校赛里是非常标准的“入门级别”但很多第一次接触Pwn的同学会在两个地方卡住一是不知道checksec是什么更不知道每种保护机制怎么绕过二是不理解为什么栈上布局要按“填充返回地址参数”的顺序来。我建议想学Pwn的新手先别急着写exp花一个晚上把函数调用约定、栈帧结构、ret指令的行为彻底搞清楚后面的路会顺畅得多。4. 实战工具与环境的准备清单4.1 一个顺手的环境比技术更重要这次比赛让我再次确认了一件事赛前准备好工具链比赛中临时找工具重要一百倍。很多同学比赛开始后还在装Python库、下载IDA等环境配好时间已经过去半小时了。校赛总共8小时排除吃饭和休息有效做题时间也就6个多小时半小时的浪费会直接影响你能碰几道题。我自己的标准赛前装备是一台装了Ubuntu虚拟机或双系统的笔记本Python 3.10以上版本预装pwntools、gmpy2、pycryptodome、requests等常用库。逆向工具装了IDA Pro、Ghidra、x64dbg、OllyDbg杂项工具准备了StegSolve、binwalk、Audacity、WiresharkWeb方向备好Burp Suite和浏览器代理配置。别嫌工具多真正比赛时你会发现平时练手的那套工具组合就是考场上最顺手的那套。临时换工具意味着你要重新适应快捷键和交互方式纯属给自己找不痛快。有一点值得单独说提前写好常用脚本片段。比如RSA攻击的模板、LSB隐写提取脚本、ZIP伪加密修复脚本、USB键盘流量还原脚本这些代码量不大但每次都要现写现查非常耗时。我这次就在Misc的USB流量的题目上直接套用了自己之前整理的脚本省了至少10分钟。建议把这些脚本放到一个固定的目录命名清晰赛前跑一遍确认无报错。4.2 高频工具用法速查下面这些工具在我这次的解题过程中用到频率最高我把关键用法和适用场景列成一个速查表方便新手们对照着准备。工具适用方向核心用法要点binwalkMisc扫描文件中的隐藏文件和嵌入数据配合 -e 自动提取StegSolveMisc逐通道查看图片检查LSB隐写和像素异常WiresharkMisc分析PCAP流量过滤HTTP/DNS/USB协议追踪流AudacityMisc查看音频频谱图识别摩尔斯电码或慢速隐藏信息IDA Pro / GhidraReverse静态分析F5反编译看逻辑定位关键函数x64dbg / OllyDbgReverse动态调试寻找OEP脱壳和验证逻辑pwntoolsPwn编写exp处理字节流、地址编码、交互和接收数据gdb / pedaPwn崩溃调试计算偏移量观察寄存器与栈布局Burp SuiteWeb抓包改包验证注入、上传绕过和SSRF请求sqlmapWebSQL注入自动化检测带上 --batch 参数免交互gmpy2Crypto大整数运算RSA攻击中开方、求逆元的核心库CyberChefCrypto万能转换工具快速尝试各种编码和古典密码每一类工具不需要全会掌握最常用的两三个就够打校级比赛了。比如Pwn方向会gdb加pwntools就足够应对入门题目Web方向Burp Suite熟练之后sqlmap只是辅助。贪多嚼不烂这是我想反复强调的一点。5. 赛后复盘新手最容易踩的坑5.1 时间分配与心态管理的学问校赛结束后我特意统计了各题得分情况发现一个很有意思的规律Misc和Crypto的得分率很高但Web和逆向的解题人数较少Pwn几乎无人问津。出现这个现象不是因为这些方向特别难而是大部分新手把前两个小时耗在了Web的SQL注入题和Reverse的脱壳题上碰壁之后心态就崩了后面原本能做出来的Crypto题也没时间细看。我的时间分配建议是这样的比赛开始后的前30分钟先快速把所有题目过一遍在草稿纸上记录每道题的类型、给的文件、初步的想法按难度从易到难排序。然后按“Misc → Crypto → Web → Reverse → Pwn”的顺序做题。我这次的实操是先用1.5小时搞定3道Misc和2道Crypto拿到保底分数再花1小时集中攻克Web题最后还剩时间慢慢磨逆向。这样的节奏能保证你不至于零分收场也能在最有把握的题上拿满。心态上也要给新手提个醒卡题是比赛的常态不是你的失败。一道题卡了30分钟还毫无进展果断放下做下一道等回头再看的时候往往因为换个角度就有了新思路。我这次逆向第二道脱壳题中途卡了好久放下它去做了一道Crypto回来再跟的时候发现之前把magic code的位置记错了这个错位其实就是“钻牛角尖”造成的。5.2 读题不认真导致的低级失误这次的比赛里有个非常典型的反面教材。Crypto的维吉尼亚密码题明明给出了密钥长度是7有的同学却反复用各种在线网站爆破密钥爆不出来就怀疑题目有坑。我后来一聊才发现他们把“密钥长度”理解成了“密钥本身”一直试图把7当关键词去解密。这就是典型的读题不仔细花了大把时间去解决一个不存在的问题。还有一道Web文件上传题flag其实在注释里就给了提示提示写的是“上传目录下有一个特殊的备份文件”。结果不少同学上传成功拿到shell之后眼睛只盯着flag文件的位置完全没注意到同目录下的index.php.bak文件而备份文件里就写着flag的后半段。明明可以一分钟解决却折腾了大半个小时。我把这类教训整理成一个简单的自查清单拿到题目先确认输入输出是什么明确flag的载体是什么列出题目提示里的所有关键词先手动搜索一遍这些关键词在文件中出现的位置任何自动化工具跑之前先想清楚它解决的问题是不是题目真正要求的问题。这个清单听起来简单但比赛高压环境下非常容易忽略。6. 从校赛到更大赛场的进阶路径6.1 这次比赛暴露的真实差距复盘完整场比赛我最大的感触是校赛最大的价值不是分数本身而是帮每个参赛者画了一张自己的能力画像。比如我这次在Crypto方向的RSA题上花了将近40分钟因为在计算私钥d时用错了模反函数参数而Misc的USB流量题却只花了15分钟就搞定。这清楚说明我的二进制分析基本功还比较扎实但密码学原理层面的熟练度有待提高。赛后我又把两道没做出来的题Pwn和Reverse各一道重新拿出来做了一遍。有意思的是脱离考场环境后我很快就看懂了Pwn题里的栈布局原来考场上卡住的点只是因为它要求把flag输出到屏幕而不是直接拿shell而我之前练的题都是直接弹shell没处理过这种变体。这种考后复盘带来的提升往往比赛场内的苦思冥想更有效所以我建议每个参赛者赛后一定要做两件事把没解出来的题完整复现一遍并写一份自己的WP哪怕只有自己能看懂这个总结过程本身就是一种训练。6.2 下一阶段该练什么如果你这次校赛拿了不错的分数打算冲击省赛或者更高级别的公开赛我的建议是把重点放在Pwn和Reverse上。这两类题目在任何大型CTF中都是区分选手实力的关键因为它们的知识点密集需要大量的底层知识积累。具体路径可以这样走Pwn方向先掌握栈溢出(ret2text、ret2libc、ret2shellcode)再学堆利用Reverse方向先能独立完成各种花指令、反调试和壳的对抗再接触混淆代码。同时多刷公开平台的题目保持每周3到5题的稳定训练量。Crypto和Web方向也不能丢但训练的重点要往现代密码学和真实漏洞场景偏移。比如Crypto不要只停留在古典密码要把AES的CBC字节翻转、RSA的共模攻击、格攻击基础都过一遍Web方向除了SQL注入和文件上传还要掌握JWT伪造、条件竞争、模板注入这些实战中高频出现的问题。如果这次比赛你只做出了一两道题也没关系。我第一次参加校赛的时候14道题里只做出来2道Misc。把基础工具练熟、把每道做出来的题背后的原理吃透再打两三场比赛你的题感会在某一天突然开窍。到那个时候再回头看这些题目你会发现自己已经很难记得当初为什么会被它们困住那么久了。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑