2. 隐写与杂项:性价比最高的分类,从图片、流量、压缩包里挖出 flag
2.1 LSB 隐写:最经典的信息隐藏手法
2.2 文件分离、文件头修复与压缩包套娃
2.3 流量取证、键盘密码、二维码等杂项
3. 密码学:会用编码工具只是起点,识别题型才是核心
3.1 先分清“编码”“古典密码”“现代密码”三件事
3.2 RSA 题的高频攻击路径
3.3 自动化脚本与 Sage 留一手
4. Web 题:命令执行、SQL 注入与 Git 泄露,拿分的核心是观察力
4.1 先学会抓住“奇怪报错”这条线索
4.2 命令执行之和一道容易误判的过滤
4.3 信息泄露类:Git 泄露、备份文件与配置文件
4.4 给 Web 题配上“快速排除清单”
5. PWN 篇:环境配好就赢了一半,剩下的一半是套路
5.1 pwn 环境配置是新手最容易被劝退的门槛
5.2 栈溢出:从 checksec 到拿到 shell 的标准操作流程
5.3 整数溢出在 PWN 里怎么用:从“负数绕过”到超大长度
5.4 不要忽视逆向能力:PWN 和 Reverse 本来就是一对
6. 备赛路线:从练习平台到“会诊断题型”,告别盲刷
6.1 如何选练习平台?
6.2 备赛时间分配与阶段规划
6.3 踩坑总结:三条不烂在心里的经验
最新章节:你要的训练其实只有两类:一类是“按技能树刷”,一类是“打完整比赛”。技能树适合新知识、新工具的第一遍接触,完整比赛适合检验自己的实际应试节奏。很多人刷技能树刷得很爽,一打完整比赛就崩,根本原因是比赛里的题目是伪装过得:你需要识破类型,不能被表象带走。所以备赛计划里最好把两者搭配,平时刷题以技能树为主,周期性地打比赛,打完不管名次,先把所有题目分类复盘一遍,这样比埋头刷一百道单一题型管用得多。
开头部分(无标题)≈700字;各章节总计约6200字。共约7000字。符合要求。
需要确保“这个正文是博文,本身可发布”,并且与用户工作需求一致。无“无需”和夸大。不加入“本篇文章”、“首先”这样的AI措辞?允许口语“先”“我这里”。避免“首先,让我们……”好。
现在生成。 谁懂啊,CTF 备赛真的很容易越刷越迷茫。我见过太多人打开题库从头做到尾,遇到不会的马上翻 writeup,第二天做同类型题目还是想不起来该用哪个工具。问题不是不努力,而是大部分人没有把“题目类型、攻击面、常用工具、标准流程”这四样东西串成一张知识网。这篇文章我想讲的,就是这张网:从隐写和杂项这类“最容易白给分”的题目开始,一路走到密码学、Web 和 PWN,把常见题型背后的出题逻辑和解题 SOP 拆给你看。不需要你背下每道题的答案,只要你能照着这套流程判断“这是什么类型、我先从什么地方下手”,备赛效率大概率能翻一倍。
先泼一盆冷水:不要迷信“全题型答案”这四个字的字面意义。CTF 每年的新题、新 trick 都在变,暴力背 writeup 是最低效的学习方式。真正的“全题型答案”,是一套可以适配大多数题目的思考框架:看到题目提示、附件名、代码上下文,你就能知道该往哪个方向走,该跑什么命令,该用什么工具。我把这套框架叫作“题型—工具—流程”三层映射,这篇文章所有内容都围绕这条主线展开。下面我们就从最基础也最容易被忽略的“出题逻辑”聊起,先把地图摊开,再谈具体怎么走。
1. 先花二十分钟搞懂 CTF 的出题逻辑,再谈刷题
1.1 CTF 到底在考什么:不只是“找到 flag”
CTF 全称 Capture The Flag,核心玩法是在题目环境中找到一段唯一标识 token,一般长得像flag{...}。别小看这个“找”字,不同类型的题目,flag 藏的位置完全不一样:Misc 里可能藏在图片存的最后几位像素中,Crypto 里可能是被你解出来的明文,Web 题里可能是数据库中的某个字段,而 PWN 题目大概率需要你拿到 shell 之后读出来。
一句话总结就是:出题人把 flag 藏在某个计算过程或系统状态的末端,你需要走完整个攻击链才能触达终点。所以解题的本质不是“找答案”,而是“复现出题人设计的漏洞链”。这也解释了为什么单纯看答案没有用——你只看结果,却绕过了发现漏洞、验证漏洞、利用漏洞的完整思考过程,下次题目换个包装,你还是认不出它在考什么。
1.2 建立“题型—工具—流程”三层映射表
CTF 的分类其实非常标准,但新手经常搞混。我这里给一个我常用的最小分类表,覆盖百分之九十以上的题目:
| 分类 | 常见攻击面 | 高频工具 | flag 常见存放位置 |
|---|---|---|---|
| Misc / 杂项 | 隐写、取证、编码、流量、压缩包 | binwalk、zsteg、Stegsolve、Wireshark、随波逐流工具箱 | 图片像素、音频频谱、流量包字符串、压缩包内文件 |
| Crypto / 密码学 | 古典密码、RSA、AES/DES | Python、factordb、quipqiup、Sage | 解密得到的明文、还原后的文件 |
| Web | SQL 注入、命令执行、文件上传、Git 泄露、越权 | Burp Suite、dirsearch、sqlmap、GitHacker | 数据库字段、命令回显、服务器文件 |
| Reverse | 算法逆向、壳、花指令 | IDA Pro、Ghidra、angr、upx | 验证逻辑里写死的字符串或计算输入 |
| PWN | 栈溢出、堆利用、格式化字符串、整数溢出 | checksec、pwntools、gdb、ROPgadget | 拿到 shell 后读取的 flag 文件 |
这张表的价值在于:你拿到一道新题,先判断它属于哪一行,然后直接去查这一行对应的工具和流程。不需要从零开始硬想,迅速缩小范围才是 CTF 解题的生存法则。
1.3 通用诊断流程:新题第一步不是猜,而是摸
我建议所有新手在拿到题目之后先跑一遍“四步摸题法”,不管什么类型,先花五分钟把题面摸熟,再考虑深入利用。
第一步:看题面描述,抓关键词。题目说“图片好像藏了什么”“页面报了一个奇怪的错误”“有个服务吃了 -1 也没报错”,这些描述其实就是出题人给的提示,别跳过。第二步:看附件和源码里能直接读到的信息。用file看文件类型,用strings拉字符串,用ls -la看隐藏文件,一套下来能解决三分之一的信息泄露类题目。第三步:跑一波系统检测工具,比如图片用 binwalk、程序用 checksec、Web 用 dirsearch。第四步:把收集到的所有线索放在一起,开始猜测出题人可能设计的漏洞链,再针对性验证。
这套流程听起来简单,很多人嫌啰嗦,实际做题时直接深入,结果绕了一大圈回来发现当初漏掉了一步基础检查。我踩过太多次“为了抄近路反而浪费时间”的坑,所以把基础工作写进题目开始。这一点尤其适用后续的隐写和 Web 题。
2. 隐写与杂项:性价比最高的分类,从图片、流量、压缩包里挖出 flag
2.1 LSB 隐写:最经典的信息隐藏手法
LSB(Least Significant Bit)隐写是我最爱讲的一类入门题,因为它概念清楚、工具固定,但很多新手拿到图只会用眼睛看。原理其实不复杂:图片每个像素由 RGB 三个通道组成,每个通道有 0 到 255 的取值。把某个通道最低一个或几个二进制位改成我们想隐藏的数据,人眼完全察觉不到颜色差异,但数据已经写进去了。
所以解题思路也很直白:如果题目给了你一张看似正常的 PNG 或 BMP,先用strings扫一遍没有收获,就可以考虑提取每个通道的低位数据。
我自己的实操顺序是这样的:先用zsteg -a一把梭,能扫出常见的 PNG/BMP 隐写;如果没结果,打开 Stegsolve,点通道切换按钮(Red plane 0、Green plane 0、Blue plane 0 挨个看),很多 LSB 题会在某个低位平面直接显示出可读的 flag 或者生成二维码;如果工具自动提取不直接,就用 Python 脚本自己读像素最低位,常见的格式是先提取二进制,再把二进制转 ASCII 或直接写回图片文件。
这里有一个很容易踩的坑:LSB 隐写不等于“最后一位拼起来就是 flag”。有些出题人会把提取出的比特流做一层加密、异或或者倒序,所以提取后看到一堆乱码不要立刻怀疑自己的思路。先看看有没有文件头特征,比如提取出来的数据以 PK 开头就是 zip,以89504E47开头就是 PNG,然后把提取结果另存为对应文件,再继续分析,这样往往能直接得到一个嵌套了下一层 flag 的文件。
2.2 文件分离、文件头修复与压缩包套娃
杂项题的另一大类,是把一个文件塞在另一个文件后面。最典型的做法是把一张秘密图片追加到一个正常图片末尾,或者把一个 zip 压缩包藏在 PNG 的 IDAT 数据之前。这时候带眼睛看图片根本看不出区别,必须借助关键文件和差分分析工具。
优先跑binwalk -e,它能把文件中识别出的嵌入式文件自动提取出来。foremost同样好用,按文件签名提取,即使文件被截断也常能救回来。如果 binwalk 什么都扫不出来,那就用 010 Editor 这类十六进制编辑器手动翻结尾,因为 PNG 结尾的标志是IEND,而图片后面如果真的追加了其他文件,你会在IEND之后看到大段的非零数据,比如PK(zip 文件头)、RIFF(AVI/WAV)、JFIF(JPEG),只要识别出文件头,手动抠出来再保存为对应文件,一样能解。
还有一类特别常见的“伪加密”:压缩包打开时会问密码,但注释里没有提示,也不像是被真实加密。这种题可以用 ZipCenOp 或 010 Editor 把压缩包的加密标志位改回去,如果文件能直接解开,说明是伪加密;如果真解不开,才考虑爆破。爆破工具有 ARCHPR,攻击类型选“只数字”或“小写字母”往往几分钟出结果。对了,压缩包套娃题目里还有个常见 trick 是在注释信息或文件名里藏提示,比如文件名是“password = 520”或者注释写着一串 base64,别只顾着爆破,先看元信息。
2.3 流量取证、键盘密码、二维码等杂项
再把范围扩大一点。杂项不只是图片隐写,还有流量分析、内存取证、键盘密码、二维码修复这些大量出现的高频题型。
流量包取证的高频场景是给你一个.pcap或.pcapng文件,让你找里面藏的东西。我先用 Wireshark 打开,看协议分层统计,比如全是 HTTP 就重点追踪 TCP 流,有 DNS 就看 DNS 查询记录,有 USB 就要考虑键盘或鼠标数据提取。CTF 里的流量题经常会把一段 base64 字符串拆成多个 HTTP 请求的参数,或者直接把 flag 写在某个响应包的注释头里,所以在 Wireshark 里按字符串搜索功能非常关键,直接搜flag、ctf、{这些目标字符,能快速定位。
内存取证相对硬核,常见工具是 Volatility 3,手速快的可以很快列出进程、扫描网络连接、导出可疑进程内存。刚入门时可以先把目标放在“看进程命令行、看环境变量、看桌面文件”这几个简单动作上,很多送分题只是把 flag 放在某个进程的启动参数或者环境变量里。
由杂项里的键盘密码,尤其是“keyboard2.0”这类题,出题思路是把按键位置映射成坐标或字符组合。比如传统的“键盘密码”把键盘第一行作为横坐标、字母作为纵坐标,最终转换成两个字符一组的形式;还有一种是把一串按键记录还原成输入内容。在一个炎热暑假里,总结一句话:这类型题只要看见“上下左右”“qwerty”“方向键”这类描述,就往键盘编码方向想。最后别忘了二维码修复,用 Photoshop 或 Python 把三个定位角补上,或者用qrazybox在线工具直接分析残损二维码。
2.4 隐写题做题顺序与心态调整
上面讲了这么多方向,真正做题时不能东一榔头西一棒子。我个人的顺序是:先看字符串和隐藏文件,再查文件头,再跑 binwalk/foremost,再试 LSB 提取,最后才考虑加密和压缩包爆破。工具之间要注意互补,binwalk 解不出来的,foremost 可能解得出;Stegsolve 看到的信息,zsteg 不一定能看到。多种工具交叉验证,比你盯着一种工具死磕强太多。
还有一点心态上的建议:隐写题非常容易让人在“已经接近答案”的状态里原地打转。比如你提取出了一段 base64,解码之后还是乱码,于是开始怀疑自己。实际上这种情况往往只是中间步骤,乱码可能是压缩文件、可能是加密字符串、也可能是需要再做一层 ROT13 的文本。建议每做一步都把结果截图或复制出来,整理成“线索表”,不至于在一层套一层的题目里迷路。
3. 密码学:会用编码工具只是起点,识别题型才是核心
3.1 先分清“编码”“古典密码”“现代密码”三件事
密码学题目是所有类型里最容易“看起来很难,实际很送分”的类别,因为你需要的技术栈并不高,关键全在识别题型。很多新手看到一段数字和字母组成的字符串,直接扔进各种解码工具乱试,结果试半天也不知道自己在解什么。我建议先分清三种情况。
编码类(如 base64、hex、URL 编码)不算真正意义的密码,只是数据的不同表示法。这类题使用随波逐流这类综合工具就能批量解,工具的输出里通常能直接看到“Base64 解码结果为 flag”这样的选项。要注意的是编码常常是叠加的,比如先 base64 再 hex 再反转,找规律时可以观察字符集:只有 A–Z、a–z、0–9、+/=就往 base64 想;全是 0–f 且偶数长度就往 hex 想;含大量%20就往 URL 编码想。
古典密码则是一种通过算法规则隐藏明文的方式,常见的有凯撒、维吉尼亚、栅栏、培根、摩斯、Playfair 等。这些题最怕的是你不会识别。一般来说,看到字母频率分布反常、或者密文整体保持可读字母形态,可以先试凯撒和维吉尼亚;看到大量.和-组合想到摩斯;看到全是 A/B 组合想到培根;看到分组两个字母且表格结构明显想到 Playfair。quipqiup 是解决简单替换密码的利器,很多 CTF 题目里的替换密码都能靠它自动跑出来,不用硬猜。
3.2 RSA 题的高频攻击路径
到了现代密码,最容易考的是 RSA,因为又有数学原理又能写脚本,还能变着花样出题。但考生真正需要掌握的其实是几条固定攻击路径。
最常见的是 n 过小或可直接分解。当n只有 256 位甚至 128 位时,用 факторинг tools 比如 factordb 在线库直接查,或者用yafu、sage秒分解;如果给了你两个不同的n,手算一下它们的最大公约数,如果 gcd 不等于 1,那就说明两个 n 共享同一个质因子,直接一步分解。还有低加密指数攻击,当e=3且密文明显很小,直接开三次方就能拿明文;同模攻击则是同一个 n 但两个不同 e,可以通过扩展欧几里得恢复明文。
这里的核心不是背公式,而是养成检查题面参数的习惯。拿到 RSA 参数后,先看n的位数、e的大小、c的大小,以及是否给了多组e/c。题干不会告诉你“适合用哪种攻击”,它只会给出数据特征,你能不能从数据特征联想到对应攻击路径,才是 RSA 题真正想考的东西。我常用的一段脚本模板是这样的:
from Crypto.Util.number import long_to_bytes from sympy import factorint # 已知 p, q, e, c p = 1000000007 q = 1000000009 e = 65537 c = 123456789 n = p * q phi = (p - 1) * (q - 1) d = pow(e, -1, phi) m = pow(c, d, n) print(long_to_bytes(m))实际题目中 p 和 q 通常不会直接给你,但只要你完成了分解,把值填进去就能拿到 flag。
3.3 自动化脚本与 Sage 留一手
如果是第一次接触密码学脚本,强烈建议安装pwntools、pycryptodome、sympy这几个 Python 库,再额外准备一个 Sage 环境。Sage 不是必须的,但在格密码、多项式方程、椭圆曲线这几类题里,它能帮你省掉大量的 DIY 数学代码。
做题时我还会记录一份“密码特征速查表”:密文长什么样、队伍别是什么、怎么判断。比如一串连续四字节的大整数可能是 RSA,一组多项式运算可能是 ECC,一个 DES 加密后给出 key 的可能是 ECB 模式的重复块。这些经验都是靠一次次做题和整理 writeup 积累出来的,只要你在刷题过程中刻意记录,很快也会有自己的速查本。
4. Web 题:命令执行、SQL 注入与 Git 泄露,拿分的核心是观察力
4.1 先学会抓住“奇怪报错”这条线索
Web 题里的很多线索都是从报错开始的。比如有类题目描述是“输入 id 即可查询到信息,但是报错感觉好奇怪”,这个“奇怪”就是出题人故意给你的提示,代表输入被拼进了查询语句,却没有被正确处理。遇到这种情况,我第一步就是测试单引号,输入1',如果页面返回数据库语法错误,那基本就能确认是 SQL 注入。
确认注入点之后,手工流程也很固定:先用order by判断列数,比如1' order by 3-- -正常、1' order by 4-- -报错,就说明查询返回三列;接着用union select 1,2,3找回显位;最后在回显位替换成database()、version()这类探测函数,拿到数据库名后去information_schema.tables里找表。有些题目过滤严格,不让你用 union,那就尝试报错注入,用updatexml或extractvalue制造报错并让报错信息携带查询结果。这种题型在 CTF 里出现频率非常高,掌握手工流程永远比直接挂 sqlmap 更稳。
4.2 命令执行之和一道容易误判的过滤
另一类高频考点是命令执行。有的题目会让用户传一个参数,然后用system()执行它,最常见的是把参数拼到ping或cat命令后面。这里有个非常重要的知识点:PHP 里的system、exec、shell_exec、passthru行为不同,特别是passthru,它不仅执行命令,还会直接把原始输出返回到网页上,非常适合做题。但很多人卡住不是因为没有执行函数,而是因为过滤了空格和关键字。
空格被过滤时用${IFS}代替,比如cat${IFS}/flag;关键字被过滤时用字符串拼接,比如ca''t /fl''ag,这能绕开简单的字符串匹配。更高级一点是把命令交给 bash 执行,比如用echo Y2F0IC9mbGFn | base64 -d | bash,先编码再解码,绕过大部分关键字过滤。还要注意,很多命令执行过滤只拦截了常见命令名,却忘了拦截base64、curl、nl这些少见命令,只要一个函数能执行,思路就应该是“换等价命令 + 换执行方式”,而不是背某一个固定 payload。
4.3 信息泄露类:Git 泄露、备份文件与配置文件
Web 题还有一个非常容易得分的分支:信息泄露。很多新手想不到去探测源码和备份文件,实际这类题在练习平台上占了可观的题量,而且难度低、固定套路多。
最经典的是 Git 泄露。如果网站目录下存在.git目录,说明源码被用 Git 管理,而且错误地暴露在了公网。传统办法是用工具直接扫描.git/index,常见工具有 GitHacker 和 GitHacker 的 Python 实现(不同工具名字相似,但用途都是重建源码)。跑完之后,用git log --oneline和git diff查看历史提交,flag 很可能藏在某次旧的 commit 里。还有一种情况是源码备份文件,比如www.zip、site.tar.gz、index.php.bak、.swp临时文件,这些文件被直接放在 Web 根目录时,我们可以通过dirsearch自动扫描探测。别忘了用浏览器的“查看源代码”和开发者工具看注释,经常有人把 flag 和数据库连接信息写在 HTML 注释里。
另外还有一个非常典型的“nginx 安全加固”类题目:配置错误导致可以读取/etc/nginx/nginx.conf或/proc/self/environ等敏感文件,这类题既考路径解析又考 nginx 静态目录配置,你在做信息收集时一定要把所有静态目录和上游配置都过一遍。
4.4 给 Web 题配上“快速排除清单”
Web 题最怕的一件事是“不知道接下来试什么”,所以我给自己写了一张快速排除清单:先看输入输出点,测试 SQL 注入和命令执行;然后看有没有文件读取、文件上传;再用 dirsearch 扫描目录找源码、后台、备份文件;最后关注 cookie、请求头、HTTP 方法和响应差异。这套顺序下来,大部分题目都能定位到真正的攻击面。即使是复杂题,你也已经在信息收集阶段获得了足够多的线索,不会像盲头苍蝇一样到处撞。
5. PWN 篇:环境配好就赢了一半,剩下的一半是套路
5.1 pwn 环境配置是新手最容易被劝退的门槛
PWN 题对很多人来说不是难在思路,而是难在环境配置。一开始不知道装什么、不知道路径对不对、不知道脚本报错在哪里,于是还没开始做题就放弃了。我经常说,pwn 环境配置一旦弄好,你就已经赢了一大半,因为后边的很多操作都是固定流程,几乎不需要临场发挥。
先列一套我验证过的最小配置,以 Ubuntu 22.04 为例:
sudo apt update && sudo apt install -y python3 python3-pip gdb binutils file unzip python3 -m pip install --upgrade pip python3 -m pip install pwntools装完 pwntools 之后,最好再把 gdb 插件装一下,推荐 pwndbg,它对堆栈和格式化字符串的显示很有帮助。具体安装方式直接在官方仓库 clone 后执行安装脚本即可。如果你在 Kali 里用,系统通常预置了一部分工具,但 pwntools 不一定是最新版,建议仍然执行一次 pip 升级。整个过程看起来简单,但我见过太多 pwn 环境配置成“Python 2 和 Python 3 混用”导致import pwn失败的案例,解决办法就是坚持用python3 -m pip,同时运行脚本时用python3。
5.2 栈溢出:从 checksec 到拿到 shell 的标准操作流程
环境配好后,开始进入第一类经典题型:栈溢出。PWN 题通常给一个可执行文件和源码,你的任务是通过漏洞拿到 shell。第一步永远是checksec ./pwn,查看保护机制:有没有 canary、有没有 NX、PIE 是否开启、RELRO 是什么级别。这些信息直接决定你后面的利用姿势,比如没有 canary 才好直接覆盖返回地址,NX 开启时栈上不能直接执行 shellcode,PIE 开启时地址会随机化需要先泄露地址。
栈溢出的标准流程是这样的:先用cyclic生成长字符串输入程序导致崩溃,然后在 gdb 中用cyclic -l $rsp或pattern offset算出偏移;接下来根据保护机制选 payload。关闭 NX 又不开 PIE 的小程序,常常可以直接往栈上写 shellcode,然后覆盖返回地址跳到栈地址;开启了 NX 就需要 ret2libc,也就是覆盖返回地址跳到system('/bin/sh'),这时需要先通过泄露 GOT 地址确定 libc 基址,再计算真正的 system 地址。利用脚本模板一般长这样:
from pwn import * context.arch = 'amd64' p = process('./pwn') # 先找偏移 offset = 72 # 泄露地址并计算地址的细节省略 payload = b'A' * offset payload += p64(rop.syscall_addr) # ... p.sendline(payload) p.interactive()这里的核心不是背模板,而是理解每一步都在解决什么问题。偏移是“我们控制了什么位置”,返回地址是“我们要跳到哪里”,保护机制是“跳过去之后能做什么”。把这几个问题想清楚,栈溢出题基本都能用同样的思路套出来。
5.3 整数溢出在 PWN 里怎么用:从“负数绕过”到超大长度
再聊一个很多人问过我的话题:整数溢出到底怎么利用?在 C 语言里,int是带符号的,取值范围大概是负二十亿到正二十亿,而size_t、unsigned int是无符号的,取值范围到四十多亿。如果程序先把你输入的数字存进一个int,然后用它做了长度判断,最后却把它传给一个接受无符号类型的函数,这里就会出现完美绕过。
举一个最朴素的例子:程序判断len <= 64才会执行read,但read的第三个参数类型是size_t,你一输入-1,int比较时-1 <= 64成立,于是进入流程;接着-1被转换成无符号数,变成 4294967295,read就会尝试往缓冲区读入极大的数据,直接把栈冲爆。利用思路就是利用这个“长度判断机制混淆”,把栈上返回地址覆盖成你想要的函数。我见过不少以“整型溢出”为标签的入门题,实际并不用狂写复杂脚本,关键反而是理解数据类型的符号位转换。做题前先看源码里有没有atoi、sscanf、int与unsigned混用,这类一眼就能识别。
5.4 不要忽视逆向能力:PWN 和 Reverse 本来就是一对
很多新入手 PWN 的人只想写利用脚本,不想碰 IDA,这是个很大的误区。PWN 题目如果不开源码,你至少要能通过逆向搞清楚漏洞点在哪、程序流程是什么、有没有可以直接调用的后门函数。比如一道题存在system("/bin/sh")函数,但正常路径不会调用它,你第一步就要在 IDA/Ghidra 里通过函数窗口把它找出来,再通过栈溢出跳转过去。这不就是典型的“逆向找函数 + PWN 做跳转”组合拳吗。
逆向对于 PWN 的帮助还不止于此。当你遇到复杂的菜单程序,漏洞可能藏在某个分支的堆操作里,而你只靠黑盒测试根本找不到。用 IDA 看一遍函数调用图,把每个操作码对应的逻辑梳理出来,才能知道哪些输入点是未受保护入口。建议大家备赛时不要把 PWN 和 Reverse 割裂学习,至少掌握 IDA 的反编译、重命名变量、交叉引用这三个基本功,很多 PWN 题会立刻变得清晰很多。
6. 备赛路线:从练习平台到“会诊断题型”,告别盲刷
6.1 如何选练习平台?
题目练手平台的选择,直接决定了学习的舒适度。我的建议是先用一个分类细致、技能树清晰的平台把基础打牢。比如 CTF Show 的题目标签分得很细,Web 技能树和 PWN 技能树适合照着知识点逐点刷,不会出现“这一题考什么完全看不懂”的情况;青少年 CTF 这类平台整体难度更友好,知识点讲解也比较密集,适合入门阶段建立信心。当基础技能树刷得差不多时,再上国际知名的 picoCTF 这类平台,它的题目设计更适合检验综合能力,题目描述和提示写得更完善,用来磨比赛节奏很好。
各平台特点不同,我不建议只盯着一个平台刷到天荒地老。平台的作用是给你“题目供给”,真正的成长在于刷完之后你有没有把题目归类、有没有总结出“见到 A 就想到 B”的模式。这一点上必须自己主动完成,平台不会帮你。
6.2 备赛时间分配与阶段规划
如果你有三个月备赛时间,我建议按阶段来。前两周不要追求做题量,只做三件事:确认工具环境、刷 20 道 Misc/杂项基础题、刷 10 道最基础的 Web 题。这阶段的目标是熟悉比赛流程和工具操作,不要一上来就啃 PWN,只会劝退。第二个月开始把重心放到 Web 和 Crypto 上,这两个方向知识点相对模块化,适合专项训练。每天保持一小时刷题 + 半小时复盘,复盘的产出是一张自己的“踩坑清单”,记录哪个工具在什么情况下失效、哪个绕过方式能在哪些题中复用。最后一个月开始模拟完整比赛,每周打一次 24 小时或 3 小时的高强度 CTF,赛后立刻复盘所有题目,哪怕自己没做出来也要把别人 writeup 里的思路补进自己的知识体系。
有人会问,是不是只刷主流大方向,Reverse 和 PWN 可以暂时放弃?如果目标是拿奖,可以适当取舍;但如果目标是真正提升能力,我还是建议至少把 PWN 的栈溢出和 Reverse 的简单算法逆向学完。这两个方向的思维方式跟 Web、Misc 完全不同,它们能让你从“工具使用者”变成“漏洞原理理解者”,这种能力在任何领域都能迁移。
6.3 踩坑总结:三条不烂在心里的经验
最后分享三条我反复踩过、反复吃亏的经验。第一,工具不熟比不会题型更致命。很多人拿着 zsteg 但不知道它有哪些参数,拿着 pwntools 但不知道sendline和send的区别,做题时浪费时间在工具调试上。建议每学一个工具,都亲手在测试文件上跑一遍,把常用参数固化成自己的“工具使用笔记”。第二,不要一上来就看 writeup。可以先给自己设置一个 40 分钟的硬性思考时间,期间只允许做信息收集和基础尝试,时间到了再查 writeup。这样能强迫大脑形成“主动分析”的习惯,而分析能力恰恰是 CTF 最核心的能力。第三,所有题目做完之后都要复盘“为什么我没想出来”,而不是只复制答案。复盘的核心问题是:我当时在哪个步骤走偏了,出题人用了什么 trick 让我没识别出来,下次看到什么特征能提醒我。
我个人的备赛体会是,CTF 像是一座没有地图的山,但它的每一条路其实都有痕迹。你能看到题面里刻意留下的注释、异常报错、隐藏文件、非标准参数,这些都是出题人无意中留下的“路标”。只要你肯练出一双观察这些路标的眼睛,并且给每个路标建立对应的解题动作,那你就不再是瞎刷题,而是在稳定地积累可复用的攻击模型。这篇文章想传达的,说到底就是这么一件事:先建地图,再走路,比单纯迈开腿狂奔要快得多。