很多新手问我,CTF到底该怎么入门,为什么别人一看题目就有思路,自己拿到题却不知道从哪下手。我自己的经历是:一开始到处翻题解,看到什么学什么,折腾三个月还是零散状态,后来才意识到,问题出在没把CTF常见的“六大题型”先看清楚。CTF(Capture The Flag,夺旗赛)本质上就是一场安全实战演练,平台会放出各种带有安全漏洞或加密逻辑的题目,选手通过分析、破解拿到一串特定格式的字符串(也就是flag),提交后得分。而这六大题型——Web、逆向、Pwn、密码学、杂项、取证——正好对应了安全领域的不同能力方向。
这篇文章想把我在CTF入门阶段的经验和踩坑记录下来:六大题型分别考什么、面对一道题该怎么拆、有哪些通用的做题套路、新手常卡在哪些地方。不管你以后是打算走安全研究、渗透测试还是二进制方向,先把这些基础盘清楚,后面刷题效率会高很多。
1. 先别急着刷题,把“夺旗”这件事看明白
1.1 一场CTF比赛到底在干什么
CTF的玩法可以理解成“解谜闯关”:主办方在服务器上部署好一套带漏洞的应用、一段加密数据或者一个二进制程序,参赛者拿到题目附件或远程地址后,通过分析代码、构造请求、破解密码、利用漏洞,最终拿到隐藏在里面的flag。flag通常是一段有固定格式的字符串,比如flag{...}或者ctf{...},交上去就能得分。
这个机制决定了CTF其实很“结果导向”——不管你是通过精妙的代码审计拿到的,还是通过笨办法枚举出来的,只要提交了正确的flag,题目就算解出来了。也正因如此,新手做题时很容易陷入“不择手段”的状态,这本身没问题,但如果连题型特征都没搞清,就会像没看地图就出门的人一样,绕很多远路。
我见过不少新手的共同状态:看到Web题就先拿扫描器扫,看到逆向题就拖进IDA盯着看,看到密码题就一个个在线工具试。这种“全凭感觉”的做法不能说完全无效,但效率极低。六大题型的存在,本质上是帮你快速建立解题的“第一反应”:拿到题目后,先判断这是什么类型,再按这个类型对应的思路去拆,而不是从零开始瞎猜。
1.2 为什么要花时间了解六大题型
你可能会想,我就是想入个门,有必要先把题型研究那么透吗?我的体会是,非常有必要。原因有几个:
第一,六大题型的知识栈几乎是分开的。Web题需要懂HTTP协议、前端后端代码、SQL注入、XSS等;逆向题需要懂汇编、PE/ELF格式、反调试;Pwn题需要懂内存布局、栈溢出、堆利用;密码题需要懂数论、常见密码算法;杂项题考的是信息搜集和隐写;取证题则是从磁盘镜像、流量包里找线索。这些方向虽然有交叉,但准备方式完全不同。抱着“一套教程吃遍所有题”的想法,基本走不通。
第二,了解题型也是了解自己的兴趣点。很多人一开始不知道自己适合做哪类题,只有把各种题型都接触一遍,才发现自己更擅长逻辑分析还是代码审计。这种“自我定位”越早完成越好,因为CTF的精进路径通常是“先广后专”——先知道大概,再选择一个方向深挖。
第三,比赛时策略也需要。团队赛里每个人都会分配不同题型,如果你连题型都分不清,就没办法跟队友配合。就算打个人赛,了解题型也能让你合理安排时间:简单题快速收割,难题留到最后,而不是在某一道题上耗到比赛结束。
2. 六大题型全景:先建立一张认知地图
2.1 用“攻防”和“分析”两个大类来理解
如果只靠死记硬背,六大题型很容易混。我习惯把它们分成两组来理解。
一组是“攻防型”:Web、逆向、Pwn。这类题目都有一个明确的对象(网站、程序、服务),你要做的就是找到它的弱点并突破它。Web是攻击跑在服务器上的应用,逆向是分析程序内部逻辑,Pwn则是直接利用程序的漏洞拿到远程shell或敏感数据。这三者都偏“主动攻击”,代码能力要求高。
另一组是“分析型”:密码学、杂项、取证。这类题目更像侦探工作,东西已经在你手里了,你需要从加密数据、图片、流量包、磁盘镜像里提取出隐藏信息。它们对“脑洞”和信息敏感度的要求更高,有时候一个base64字符串、一张图片的隐写信息,就是整道题的突破口。
这种分类方式还有一个好处:当你拿到题目时,可以第一时间判断自己是“要攻击”还是“要分析”,从而决定下一步行动。如果题目给了你一个网址让你找漏洞,那基本是Web或Pwn的方向;如果题目只是给了你一个文件让你找flag,那更可能属于杂项、取证或密码学。
2.2 六大题型的考察重点和入门门槛
下面这张表是我按照自己的经验整理的,方便新手对照着看:
| 题型 | 考察核心 | 常见出题形式 | 常用工具/语言 | 新手门槛 |
|---|---|---|---|---|
| Web | HTTP协议、Web应用逻辑、注入、认证绕过 | 登录接口、文件上传、命令执行、SQL注入 | Burp Suite、浏览器开发者工具、Python | 中低,适合作为入门首选 |
| 逆向 | 汇编语言、程序逻辑、加壳与反调试 | 桌面程序、App安装包、加密验证算法 | IDA Pro、Ghidra、x64dbg、Python | 较高,需要耐心和代码基础 |
| Pwn | 内存布局、栈溢出、堆利用、系统调用 | 远程服务、二进制程序利用 | pwntools、gdb、checksec | 高,需要系统知识积累 |
| 密码学 | 编码、古典密码、现代密码算法、数学基础 | 替换密码、RSA、AES、哈希长度扩展 | Python、CyberChef、在线密码库 | 中,入门容易精通难 |
| 杂项 | 信息搜集、隐写、编码转换、脑洞 | 图片、音频、压缩包、字符串隐写 | Binwalk、Stegsolve、strings、010 Editor | 中低,适合培养感觉 |
| 取证 | 磁盘/内存/流量分析、日志审计 | 流量包、磁盘镜像、邮件、浏览器记录 | Wireshark、Volatility、Autopsy、tshark | 中,偏数据敏感度 |
这张表只是参考,不是绝对标准。我个人不太建议新手一上来就死磕Pwn,因为涉及底层的知识很多,挫败感会比较强。相比之下,Web和杂项更容易产生正反馈,适合建立信心。但这也不代表你要排斥其他方向,多接触、多尝试,才能找到自己最擅长的那个点。
2.3 怎么判断自己适合先主攻哪个方向
判断方法其实很简单:问自己三个问题。
你平时是不是喜欢摸网站、看接口、改参数?如果有这种感觉,Web方向会比较顺手。你是不是喜欢拆东西、分析程序行为、看代码逻辑?那可以试试逆向。你是不是对数学比较有耐心,喜欢玩解密游戏?密码学方向也许适合你。
如果你现在完全没偏好,我建议按这个顺序入门:Web → 杂项 → 密码学 → 逆向 → 取证 → Pwn。这个顺序的考虑是:Web和杂项容易上手、知识依赖少,能让你先感受CTF的完整流程;密码学补数学和编码基础;逆向和Pwn则需要更多系统知识和耐心,放到后面不会打击积极性。
当然,顺序只是建议。我自己认识的新手里也有直接从逆向起步、后来做得非常出色的,关键是别被“必须先从哪科开始”的框框锁死。你真正要做的是在每个方向都至少做上三五道题,再决定要不要投入更多时间。
3. 六道代表例题手把手拆解
为了让新手更直观地理解每种题型,我用六个虚构的简单例子,把常见的解题思路走一遍。这些题目都经过了简化,主要展示思考路径,而不是追求真实赛题的难度。
3.1 Web题:从一个登录接口到SQL注入
题目场景:某平台给了一个网址,页面上只有一个登录框,请求里提示用户名是admin,但密码不知道。常见做法是思考登录逻辑怎么实现的。
我首先打开浏览器开发者工具,提交一次任意账号密码,观察请求。接着用Burp Suite抓包,把POST请求发送到Repeater。如果后台SQL语句是直接拼接字符串的,比如SELECT * FROM user WHERE name='$name' AND pass='$pass',那么在用户名处输入admin'#就可以注释掉后面的密码校验,实现登录绕过。
具体请求体可能长这样:
POST /login.php HTTP/1.1 Content-Type: application/x-www-form-urlencoded name=admin'#&pass=123如果后台返回了欢迎页面,说明注入点存在。这时候可以在参数后面继续用order by判断字段数,再通过联合查询把flag查出来。整个过程的核心是“把用户输入变成SQL代码的一部分”,所以看参数、看报错、测试闭合方式,就是Web题的基本功。
这里给新手一个建议:遇到Web题,第一步永远是“看请求和响应”,而不是急着上扫描器。很多漏洞就藏在参数名、Cookie、响应头这些细节里,手动分析比无脑扫描靠谱得多。
3.2 逆向题:从“校验函数”到写脚本爆破
题目场景:拿到一个exe文件,双击后发现要输入一个序列号,输错了就提示错误。逆向题的基本思路是把程序拖进反汇编工具,找到它校验输入的那段逻辑。
我用Ghidra打开这个exe,先看字符串窗口,搜索提示信息,比如“Wrong”所在的位置。双击字符串,交叉引用到调用它的函数,很快能看到类似这样的伪代码:
int check(char *input) { int sum = 0; for (int i = 0; input[i] != '\0'; i++) { sum += input[i]; } return sum == 1234; }逻辑很清楚:只要输入的所有字符ASCII码加起来等于1234,就能通过校验。于是我们就不需要手动猜了,直接写Python脚本枚举:
import itertools import string for length in range(1, 6): for seq in itertools.product(string.ascii_letters, repeat=length): if sum(ord(c) for c in seq) == 1234: print(''.join(seq)) exit()搜索到一组满足条件的字符串后,在程序里输入,就能拿到flag。这个例子告诉我们,逆向题并不一定要求你从头到尾读懂整个程序,关键是把校验逻辑提取出来,然后用代码去“对话”。
新手容易踩的坑是:一上来就整个程序傻看。正确做法是先找关键字符串、关键函数、关键比较,再用交叉引用顺藤摸瓜。工具方面,Ghidra免费且适合新手,IDA Pro功能更强但需要一定学习成本。
3.3 Pwn题:从“溢出”思路说起
Pwn题一般会给一个远程地址和一个二进制文件。入门阶段最常见的漏洞类型就是栈溢出。题目场景:程序接收一段输入,然后直接strcpy到一个局部缓冲区里,这个缓冲区只有16字节,但程序没有限制输入长度。
我先用checksec检查二进制开启了哪些保护:
checksec --file=./pwn_demo如果发现NX开了但没开PIE,那思路就是“覆盖返回地址,跳到后门函数”。假设程序里已经有一个打印flag的函数win(),我可以这样计算偏移:
from pwn import * # 本地调试时,需要用cyclic生成模式串,找到偏移 io = process('./pwn_demo') io.sendline(cyclic(100)) io.wait() # 用gdb或pwndbg查看崩溃位置,得到偏移假设偏移为20,那就构造payload:
payload = b'A' * 20 + p64(win_addr)发送给远程服务后,程序就会执行win函数,把flag打印出来。用pwntools一条命令就能完成交互和发送。
新手做Pwn题,最重要的是别被底层细节劝退。第一阶段只需要理解“调用栈”“返回地址”“覆盖”这几个概念,配合现成工具,就能解决很多入门题。到了中后期,再慢慢深入堆利用、格式化字符串等高级主题。
3.4 密码题:从古典密码到现代密码
密码题是六大题型里最“烧脑”的一种,但入门题往往比较友好。题目场景:给了一段密文和一个加密脚本,脚本里用了一个自定义的替换表,类似凯撒加密,但偏移未知。
看到这种题,我的习惯是先试在线工具或CyberChef,把常见编码过一遍,比如base64、十六进制、URL编码。如果不行,再分析加密脚本。假设加密脚本是这样的:
def encrypt(plain, key): cipher = '' for c in plain: if c.isalpha(): shift = ord(key) % 26 cipher += chr((ord(c) - ord('a') + shift) % 26 + ord('a')) else: cipher += c return cipher这里的key是个字符,加密本质就是凯撒移位。我根据题目提示知道原文是英文句子,于是用频率分析或直接枚举26个key:
cipher = '...' for k in range(26): plain = '' for c in cipher: if c.isalpha(): plain += chr((ord(c) - ord('a') - k) % 26 + ord('a')) else: plain += c if 'flag' in plain: print(k, plain)跑出来原文里包含flag,收工。密码题的核心就是“读懂加密算法,逆推明文或密钥”。不要怕数学,很多题目只需要初中数学就能解决,真正难的那部分更多出现在高分段。
3.5 杂项题:从图片尾部和隐写里找线索
杂项题是最考验“信息敏感度”的题型。题目场景:给了一张风景图,没有其他说明。我的处理流程非常固定:
第一步,看文件头。用file和strings先跑一遍:
file mystery.png strings mystery.png | grep -i flag如果strings直接搜到flag,那是最简单的送分题。如果没搜到,再用binwalk看看图片是否内嵌了其他文件:
binwalk mystery.png如果分离出一个RAR压缩包,再想办法破解。另一个常见手法是LSB隐写,也就是把信息隐藏在图片像素的最低位,这时可以用zsteg或 Stegsolve 查看通道信息。
新手做杂项题最容易漏的是“常识类信息”,比如图片名、EXIF信息、文件末尾的追加数据。我会建议养成一个习惯:拿到文件先看大小,再看文件头,再用strings扫一遍,最后才考虑是否动用binwalk和隐写工具。顺序不要乱,乱就容易把时间浪费在复杂工具上。
3.6 取证题:从流量包里还原敏感信息
取证题和杂项题很像,但更强调“基于线索还原事件”。最典型的题目就是给你一个pcap包,问某个时间段内传输了什么文件、谁的账号密码是多少。
我习惯用tshark先概览一下:
tshark -r capture.pcap --statistics-conversations发现大量HTTP流量,就筛选HTTP请求:
tshark -r capture.pcap -Y "http.request.method==POST" -T fields -e http.host -e http.uri如果流量里包含文件上传,可以尝试用Wireshark的“导出对象”功能,把传输的文件从pcap里导出。如果题目问的是邮箱、聊天记录,则多半要分析协议内容或者提取字符串。
最难的一种是内存取证,比如给一个内存镜像,需要用Volatility取进程列表、命令记录、剪切板内容等。新手可以先不碰内存取证,等把流量分析和磁盘分析练熟再深入。
4. 拿到一道题,我一般按这个流程走
4.1 先判断题型,再决定用什么武器
很多新手拿到题直接开始乱试,结果花了不少时间。我自己的做法是,前两分钟先“侦察”:看题面描述,看附件列表,看远程地址的类型。如果是网址,优先考虑Web;如果给了下载的二进制、apk、exe,优先逆向或Pwn;如果给了图片、压缩包、音频,优先杂项或取证;如果给了一大段字符串或加密脚本,优先密码学。
这一步看着简单,但能帮你迅速定位要用的工具包。哪怕是同一个附件,不同题型的处理思路也完全不同。比如一个ELF文件,如果是Pwn题你会研究它的漏洞交互,如果是逆向题你会研究它的验证逻辑,如果是杂项题你可能先跑strings。判断错了方向,后面就是白忙活。
4.2 培养“侦察敏感度”:每步都在找什么
我总结了每个题型最需要找的四样东西,新手可以照着这个清单来:
- Web题:找输入点、参数点、报错信息、认证逻辑。
- 逆向题:找关键字符串、关键比较函数、加密算法、反调试。
- Pwn题:找漏洞函数、缓冲区大小、保护机制、后门函数。
- 密码题:找算法名称、密钥格式、加密模式、已知明文。
- 杂项题:找文件头、附加数据、隐藏信息、编码特征。
- 取证题:找异常流量、文件传输、日志痕迹、进程行为。
这四样东西一旦定位,题目的主线就出来了。很多时候新手卡住,不是因为不会某个技术,而是不知道现在该找什么。所以每次做题前,你可以先写下来:“我要找什么”,比直接乱翻高效得多。
4.3 从提交flag到复盘:别忽略最后的格式细节
很多新手解到99%却拿不到分,原因出在flag格式上。常见情况包括:手多了空格、大小写不对、把提示词当成flag内容、flag里的字符被某个工具自动换行截断。
我的经验是,直接复制不要手打,提交前检查三遍。如果题目要求的是flag{...},那就别把ctf{...}交上去。有些平台还区分是否包含换行符,用python接收输出后可以先strip()再打印。
一个更重要的习惯是:解完题后立刻复盘。我当时是怎么想到思路的?哪里卡住浪费时间了?下次类似题能不能1分钟定位?把复盘写进笔记里,比多做十道题都值。我自己的笔记就是一个markdown文件,按题型分节,每道题记录“题眼、工具、payload、教训”,三个月后回头看,起点已经在慢慢变高了。
5. 新手最容易踩的坑,能避一个是一个
5.1 思路跑偏:在一个点死磕太久
最常见的坑是“钻牛角尖”。比如Web题里某个参数看起来能注入,试了很久都不行,后来才发现真正的考点在另一个文件的源码注释里。所以我会给自己定个时间限制:一道题,正常思路试20分钟没有进展,就停下来重新找线索,而不是继续在一个假设上加深。
做题不是比谁更有耐心,CTF的题眼往往藏在反直觉的地方。比如题目给了个网址,但真正的附件却藏在另一个端口上;题目看起来是加密算法题,实际上只需要观察脚本里的随机数种子。这种“反直觉”正是出题人想考你的信息搜集能力。
5.2 环境问题:工具版本、依赖和路径坑
CTF里很大一部分时间耗在环境配置上。我遇到过的情况包括:python库版本对不上导致pwntools跑起来报错、ghidra打开文件卡死、binwalk没安装依赖导致分离失败。新手面对这些问题很容易崩溃,但大部分都能解决。
建议大一新生或者刚入门的朋友,把所有常用工具集中放在一个环境里,比如用Linux虚拟机,统一管理。pwntools、gdb、binwalk、tshark都装好,避免每天换一台机器重新配环境。遇到报错,先看报错信息最后一行,绝大多数问题网上有现成答案,不要自己闷着头改。
5.3 不爱用脚本:什么题都想手算碰运气
我见过很多新手看到密码题,第一反应是打开在线工具,看到逆向题第一反应是想手动猜测输入。这种心态可以理解,但要尽早改掉。CTF里很多题目一旦看清逻辑,就是一个写脚本的事。手算不仅慢,而且容易算错。
我用Python最多,因为写起来快。比如看到一个循环加密逻辑,直接用脚本模拟、枚举、爆破,比在脑内推理快得多。新人不用等自己“会了编程”再做题,而是通过做题倒逼自己学会写脚本。做十道CTF题,你的脚本能力会有明显进步。
5.4 工具不会用:典型问题速查表
新手在工具使用上遇到的高频问题,我整理了一张速查表:
| 问题 | 原因 | 解决方向 |
|---|---|---|
strings搜不到flag | flag被编码或压缩 | 考虑base64、十六进制、隐写 |
| binwalk分离不出东西 | 文件没问题,是思路问题 | 检查文件头、追加数据、LSB隐写 |
| pwntools连接不上 | 地址或端口写错、没有交互提示 | 先nc测试连通性,打印收发内容 |
| IDA打不开程序 | 文件损坏、架构不认识 | 用file确认格式,换Ghidra或x64dbg |
| Wireshark看的是乱码 | 显示设置或解码不对 | 检查传输层协议,尝试导出原始字节 |
| python脚本报编码错误 | 输入输出编码问题 | 统一使用.encode()/.decode()处理字节数据 |
这个表没法覆盖所有问题,但核心思路是:先确认输入输出格式,再考虑工具参数,最后才想到重装或换工具。别一报错就换平台,那样往往解决不了问题。
6. 给新手的备赛路线和一些大实话
6.1 三个月入门路线可以参考
如果现在你是一个几乎零基础的新手,可以参考我建议的三个月路线:
第一个月,以Web和杂项为主。把HTTP协议、常用工具、信息搜集这些基本功打牢,目标是能独立做出大多数一星、二星题。这个阶段重点是“建立解题手感”,不要追求难题。
第二个月,加入密码学和逆向。密码学先学常见编码、古典密码、基础RSA;逆向学ELF分析、关键函数查找、简单爆破。目标是对每个题型都能说出基本流程。
第三个月,尝试Pwn入门和综合训练。先做最简单的栈溢出,理解ret2text;同时参加一些线上新人赛,在比赛里检验自己的节奏和临场应对。三个月后,你会发现自己至少能在一场入门赛中稳定解出两三道题。
6.2 做题之外的几项必修课
新手往往只盯着刷题数量,但我觉得复盘、写writeup、看别人的writeup同样重要。每场比赛结束后,把每道题重新做一遍,写一份自己的writeup,哪怕很简单也要写。这个过程会逼你把思路整理清楚,也方便以后复习。
另外,建议加入一个学习圈子,不管是校内社团还是线上社区。一个人单打独斗容易钻牛角尖,几个朋友一起互相讲题,进步速度完全不一样。我在入门阶段经常是给别人讲题的时候才真正把问题想透的。
6.3 最后的大实话:放弃横向追逐,专注纵向积累
最后想以我个人的体会收个尾。我刚开始学CTF时最大的毛病是贪多,六大题型都想练,看到高分大佬什么都懂就焦虑,结果哪个方向都是半吊子。后来我逐渐明白,CTF不是“每道题都要马上解出来”的游戏,而是一个不断积累“模式识别”能力的过程。
我现在给新人的建议是:选定一个主线方向,比如说Web或者Pwn,把这个方向练到能在比赛中稳定得分,再慢慢扩展其他题型。前期可以平均用力找兴趣,中期开始做减法,后期把精力集中在优势方向。这个问题我踩了半年才想明白,如果早有人提醒我,能省很多时间。希望这篇内容能让你少走一点弯路。