
简介这是一份面向CTF入门与进阶选手的题型梳理文档围绕网络安全竞赛中常见的Web、密码学、逆向、PWN与杂项五大方向系统整理了解题思路与关键知识点。内容涵盖基础爆破、SQL注入与报错注入、文件上传与包含、代码审计以及替换与置换密码、Base64等编码、RSA非对称加密、散列函数并延伸至脱壳反编译、栈溢出与格式化字符串、隐写术与流量日志分析等实战要点。资源包内含1个docx文档约18KB体量轻便适合作为赛前速查与知识框架搭建的参考笔记。目前已有2057人学习下载读者可借此快速建立CTF题型全景认知对照各方向要点查漏补缺理解常见漏洞的触发条件与利用路径为刷题和复盘提供清晰的索引。1. CTF常见题型全景从一道签到题到完整夺旗链路很多人第一次打开 CTF 题目页面时看到的是一个输入框、一张图片或者一段乱码完全不知道从哪里下手。这不是能力问题而是缺少一张「题型地图」。CTF 夺旗赛的题目看似千变万化但落到解题层面绝大多数都能归入 Web 渗透、逆向工程、密码学、杂项取证、Pwn 二进制利用这几大类。每一类的入口信号、常用工具链和解题节奏都不一样用错方向就会在一条死路上耗掉几个小时。这篇文章面向的是刚接触 CTF 想系统入门的人以及打过几场比赛但解题全靠碰运气、想建立稳定方法论的选手。我会按题型拆开讲每类题怎么识别、用什么工具、参数怎么设、常见的坑在哪。中间会给出可直接复现的命令和脚本也会说清楚哪些操作在比赛环境里能用、哪些会翻车。读完你至少能做到拿到一道题先判断它属于哪类再按对应流程推进而不是对着屏幕发呆。2. Web 题从源码泄露到命令执行递进2.1 Web 题的入口信号与信息收集顺序Web 类题目在 CTF 中占比最高也是新手最容易上手的类型。题目通常给一个 URL 或者一份源码包flag 藏在数据库、文件系统或某个环境变量里。解题的核心思路是先摸清目标的技术栈和暴露面再找注入点或逻辑漏洞最后读取 flag。信息收集的顺序很关键。我一般按这个流程走先看页面源码和响应头确认服务器类型、框架版本、有没有注释泄露再扫目录找备份文件、配置文件、后台入口然后测参数看有没有 SQL 注入、文件包含、命令执行。这个顺序不能乱跳过信息收集直接怼参数大概率会漏掉最简单的入口。# 第一步查看响应头和页面基本信息 curl -I http://target-ip:port/ curl -s http://target-ip:port/ | head -100 # 第二步目录扫描找敏感文件 # 常见做法是用 dirsearch 或 gobuster gobuster dir -u http://target-ip:port/ -w /usr/share/wordlists/dirb/common.txt -x php,html,bak,zip,tar.gz # 第三步检查常见泄露点 curl -s http://target-ip:port/robots.txt curl -s http://target-ip:port/.git/config curl -s http://target-ip:port/www.zip -o www.zip上面这段命令的逻辑是层层递进的。curl -I拿响应头重点看Server、X-Powered-By、Set-Cookie这几个字段能快速判断是 PHP 还是 Java 还是 Python 应用。gobuster扫目录时-x参数指定扩展名bak 和 zip 是备份文件的高频后缀很多题目会把源码打包放在根目录下忘了删。robots.txt和.git/config是经典泄露点前者可能暴露隐藏路径后者如果存在说明整个 Git 仓库可能可以拉下来。参数方面gobuster的线程数默认 10比赛环境里可以调到 30 到 50 加速但别超过 100否则容易被 WAF 封 IP。字典选择上common.txt大约 4600 条适合快速扫一遍如果没结果再换directory-list-2.3-medium.txt但那个字典有 22 万条扫完要很久建议只在确认有隐藏目录时用。2.2 命令执行与绕过passthru 类题目的实战参数命令执行是 Web 题里的高频考点。PHP 的system、exec、passthru、shell_exec这几个函数只要参数可控就能直接执行系统命令。但出题人不会让你轻松执行cat /flag通常会加过滤禁用某些函数、过滤关键字、限制长度。先看一个最基础的命令执行 payload?php // 假设源码是这样的 $cmd $_GET[cmd]; passthru($cmd); ?这种情况下直接传?cmdcat /flag就行。但实际题目里更常见的是加了过滤比如?php $cmd $_GET[cmd]; if (preg_match(/cat|flag|system|exec/i, $cmd)) { die(no hack); } passthru($cmd); ?绕过思路有几种。第一种是命令拼接用;、|、、||连接多条命令只要有一条不含过滤词就能执行。第二种是变量拼接比如afl;bag;cat $a$b。第三种是用通配符cat /fla?或者cat /fl*。第四种是编码绕过用$(printf \x63\x61\x74)构造 cat。# 变量拼接绕过关键字过滤 ?cmdafl;bag;cat /$a$b # 通配符绕过 ?cmdcat /fla? # 反斜杠绕过 ?cmdcat /fl\ag # 内联执行绕过 ?cmdecho Y2F0IC9mbGFn | base64 -d | bash这里要重点说passthru和system的区别。system会直接输出命令结果并返回最后一行的输出passthru是原样输出二进制数据适合执行会产生二进制输出的命令。exec只返回最后一行shell_exec返回完整输出但需要 echo。很多新手用exec发现没回显就是因为没有 echo 返回值。注意命令执行题里如果目标没有回显可以尝试写文件到 Web 目录再用浏览器访问或者用 DNS 外带数据。但外带需要你有可控的域名或服务器比赛环境里不一定允许。2.3 SQL 注入的自动化与手工判断分界线SQL 注入是 Web 题的另一大支柱。新手容易犯的错误是一上来就 sqlmap 梭哈结果被 WAF 拦了或者跑半天没结果。我的习惯是先手工判断注入类型和过滤规则确认有注入点再用工具。手工判断的步骤先加单引号看报错再试and 11和and 12看页面差异然后判断是联合注入还是盲注。联合注入用order by猜列数盲注用时间延迟或布尔条件。-- 判断列数 order by 3 -- order by 4 -- -- 联合注入读数据 union select 1,2,database() -- union select 1,2,group_concat(table_name) from information_schema.tables where table_schemadatabase() -- -- 盲注布尔判断 and substr((select flag from flag),1,1)f --参数说明order by后面的数字是列数从 1 开始递增直到页面报错说明列数就是前一个数字。group_concat把多行结果拼成一行方便一次读出所有表名。盲注里substr的第二个参数是起始位置第三个参数是长度逐个字符猜。sqlmap 的使用时机是在手工确认注入点之后用--technique指定注入技术--dbms指定数据库类型--tamper指定绕过脚本。不要一上来就sqlmap -u url --batch那样跑得慢还容易被封。# 确认注入点后用 sqlmap 加速 sqlmap -u http://target/page?id1 --dbmsmysql --techniqueU --dump -T flag --batch # 如果有 WAF加 tamper 脚本 sqlmap -u http://target/page?id1 --tamperspace2comment --batch--techniqueU表示只用联合注入速度最快。--dump -T flag直接导出 flag 表的数据。--tamperspace2comment把空格替换成注释绕过简单的空格过滤。3. 逆向与密码学从静态分析到脚本解密3.1 逆向题的工具选择与静态分析流程逆向题给的是一个可执行文件或者一段字节码flag 藏在程序的判断逻辑里。新手看到汇编就头大但其实大部分 CTF 逆向题的逻辑并不复杂用对工具能省很多时间。工具选择上Windows 平台用 IDA Free 或者 GhidraLinux 平台用 radare2 或者 objdump。Ghidra 是免费的反编译效果也不错适合入门。IDA 的 F5 反编译更成熟但正版很贵Free 版不支持 x64 反编译。# 先用 file 看文件类型 file challenge # 如果是 ELF用 strings 找可疑字符串 strings challenge | grep -i flag strings challenge | grep -i correct\|wrong\|input # 用 objdump 看反汇编 objdump -d challenge | head -200 # 用 radare2 分析 r2 -A challenge # 进入后输入 afl 列出函数pdf main 查看主函数反汇编file命令确认文件架构是 x86 还是 x64是 ELF 还是 PE。strings是最快的突破口很多题目的 flag 直接以明文形式存在二进制里或者有提示性字符串。objdump -d反汇编整个文件但输出很长建议配合grep过滤关键函数。radare2 的-A参数表示自动分析afl列出所有函数pdf main反编译主函数。如果字符串里没有直接线索就需要看主函数的逻辑。常见模式是程序读取输入经过一系列变换然后和硬编码的字符串比较。你需要逆向这个变换过程写出对应的解密脚本。3.2 密码学题的识别与脚本编写密码学题通常给一段密文和加密脚本或者只给密文让你猜加密方式。识别加密方式是第一步看密文长度、字符集、是否有规律。常见特征Base64 结尾有字符集是 A-Za-z0-9/MD5 是 32 位十六进制SHA1 是 40 位十六进制RSA 会给公钥和密文凯撒密码是字母偏移维吉尼亚密码需要密钥。# Base64 解码 import base64 cipher ZmxhZ3t0aGlzX2lzX2FfZmxhZ30 print(base64.b64decode(cipher).decode()) # 凯撒密码暴力破解 def caesar_bruteforce(cipher): for shift in range(26): result for char in cipher: if char.isalpha(): base ord(a) if char.islower() else ord(A) result chr((ord(char) - base - shift) % 26 base) else: result char print(fshift{shift}: {result}) caesar_bruteforce(flag{this_is_a_flag}) # RSA 解密已知 p, q, e, c from Crypto.Util.number import inverse, long_to_bytes p 0x1234 q 0x5678 e 65537 c 0xabcdef n p * q phi (p - 1) * (q - 1) d inverse(e, phi) m pow(c, d, n) print(long_to_bytes(m))Base64 解码直接调库注意补全填充。凯撒密码暴力破解遍历 26 个偏移量输出所有可能结果人工找有意义的那个。RSA 解密需要知道 p 和 q如果题目只给 n 和 e就需要先分解 n小 n 可以用 factordb 或者 yafu 分解大 n 就需要找其他漏洞比如共模攻击、低加密指数攻击。参数说明inverse(e, phi)求 e 关于 phi 的模逆即私钥 d。pow(c, d, n)是模幂运算得到明文 m。long_to_bytes把整数转成字节串再解码成字符串。注意密码学题里如果给了加密脚本一定要先读懂脚本再动手。很多题目会在脚本里留后门或者用非常规参数直接套公式会算错。4. 杂项与取证文件分析、隐写与流量包4.1 文件类型识别与隐写提取杂项题是 CTF 里最杂的一类可能给一张图片、一个压缩包、一段流量包或者一个内存镜像。解题的关键是识别文件真实类型然后找隐藏信息。文件类型识别不能只看扩展名要用file命令或者看文件头。常见的文件头PNG 是89 50 4E 47JPEG 是FF D8 FFZIP 是50 4B 03 04PDF 是25 50 44 46。如果扩展名和文件头不一致说明文件被改了后缀改回来再打开。# 查看文件真实类型 file suspicious.jpg # 查看文件头十六进制 xxd suspicious.jpg | head -5 # 图片隐写常用工具 # steghide 提取隐藏文件 steghide extract -sf image.jpg -p password # binwalk 分析固件或图片中的嵌入文件 binwalk -e image.png # zsteg 分析 PNG 的 LSB 隐写 zsteg image.png # exiftool 查看元数据 exiftool image.jpgfile命令输出会告诉你真实格式。xxd看十六进制确认文件头。steghide需要密码如果题目没给密码就试空密码或者常见弱密码。binwalk -e自动提取嵌入的文件很多题目会把压缩包藏在图片末尾。zsteg专门检测 PNG 的 LSB 隐写能直接读出隐藏的字符串。exiftool看 EXIF 元数据有时候 flag 就写在注释或者作者字段里。4.2 流量包分析与数据提取流量包题给一个 pcap 或 pcapng 文件flag 藏在网络通信数据里。用 Wireshark 打开先看协议分层统计再过滤关键协议。# 用 tshark 命令行分析Wireshark 的命令行版 # 查看协议统计 tshark -r capture.pcap -q -z io,phs # 过滤 HTTP 请求 tshark -r capture.pcap -Y http.request -T fields -e http.host -e http.request.uri # 导出 HTTP 对象 tshark -r capture.pcap --export-objects http,output_dir # 过滤 DNS 查询 tshark -r capture.pcap -Y dns.qry.name -T fields -e dns.qry.name-z io,phs输出协议分层统计快速了解流量里有哪些协议。-Y是显示过滤器语法和 Wireshark 一样。--export-objects把 HTTP 传输的文件全部导出来图片、压缩包、可执行文件都能提取。DNS 查询过滤能发现数据外带有些题目把 flag 编码在域名里逐个查询带出去。参数说明-r指定读取的文件-T fields -e指定输出字段适合批量提取。如果流量包很大先用-Y过滤再分析不要直接打开几 GB 的文件。注意流量包题里如果看到大量 DNS 查询或者 ICMP 包优先怀疑数据外带。把查询名或 payload 提取出来按顺序拼接往往就是 flag。5. 避坑与排查CTF 解题中常见的五个翻车点5.1 环境差异导致的命令失效现象在本地测试成功的命令放到题目环境里执行没反应或者报错。原因题目环境可能是精简版 Linux没有安装某些工具或者 shell 类型不同sh 和 bash 行为有差异或者目标架构是 ARM 而本地是 x86。解决先执行id和uname -a确认权限和系统信息。命令用绝对路径比如/bin/cat而不是cat。如果目标没有 bash用sh -c包裹命令。架构不同就用交叉编译或者找对应架构的静态编译工具。5.2 编码问题导致 payload 被截断现象构造的 payload 在本地能用发送到目标后只执行了一部分。原因URL 编码、HTML 实体编码、Base64 编码混用或者特殊字符被 WAF 拦截。解决用 Burp Suite 的 Repeater 模块逐字节检查请求确认哪些字符被过滤。URL 编码用%xx格式空格用%20或。如果 WAF 拦截关键字尝试大小写混合、双写、注释拼接。5.3 逆向题反编译结果与源码逻辑不一致现象Ghidra 反编译出来的代码逻辑混乱变量名都是local_xx看不出原始逻辑。原因二进制被混淆过或者编译器优化级别高或者使用了不常见的调用约定。解决先看汇编不要完全依赖反编译。关注函数调用和比较指令cmp、test、jz、jnz这些是判断逻辑的核心。如果混淆严重尝试用动态调试在关键比较处下断点看寄存器的实际值。5.4 密码学题参数抄错导致解密失败现象按照题目给的参数写脚本运行报错或者结果乱码。原因参数是十六进制但当成十进制用了或者 p 和 q 的顺序搞反了或者密文是 Base64 编码的需要先解码。解决确认所有参数的进制十六进制加0x前缀。RSA 里 p 和 q 的顺序不影响 n但计算 phi 时要用(p-1)*(q-1)。密文如果是一串 Base64 字符先base64.b64decode再转整数。5.5 杂项题文件提取不完整现象binwalk 提取出多个文件但打开都报错或者不完整。原因文件被分片存储或者提取偏移量不对或者需要手动修复文件头。解决用binwalk -e提取后检查每个文件的文件头是否正确。如果文件头损坏用十六进制编辑器手动修复。分片文件需要按顺序拼接用cat part1 part2 full合并。压缩包如果加密先尝试空密码和常见弱密码再用fcrackzip暴力破解。6. 进阶技巧用脚本串联解题流程与验证结果打到一定阶段后你会发现很多题目的解题步骤是重复的信息收集、漏洞利用、数据提取、解码。把这些步骤脚本化能大幅提升效率。我一般会维护一个自己的工具脚本库按题型分类每场比赛前更新一遍。以 Web 题为例我写了一个自动化信息收集脚本输入目标 URL自动完成响应头检查、目录扫描、常见泄露点探测输出一份报告。这样拿到题目后先跑一遍脚本几分钟内就能摸清大致情况。import requests import sys from concurrent.futures import ThreadPoolExecutor def check_path(base_url, path): url f{base_url.rstrip(/)}/{path.lstrip(/)} try: r requests.get(url, timeout5, allow_redirectsFalse) if r.status_code in [200, 301, 302, 403]: return f[{r.status_code}] {url} (len{len(r.content)}) except: pass return None def scan(base_url): # 常见敏感路径字典 paths [ robots.txt, .git/config, www.zip, backup.zip, admin/, login.php, config.php, flag.php, index.php.bak, .env, phpinfo.php, test.php ] results [] with ThreadPoolExecutor(max_workers10) as executor: futures [executor.submit(check_path, base_url, p) for p in paths] for f in futures: res f.result() if res: results.append(res) return results if __name__ __main__: target sys.argv[1] print(fScanning {target}...) for line in scan(target): print(line)这段脚本的逻辑很直接维护一个常见敏感路径列表用线程池并发请求把返回状态码 200、301、302、403 的路径打印出来。allow_redirectsFalse是为了看到 302 跳转本身有时候跳转目标就是后台入口。timeout5防止某个请求卡死整个扫描。参数调整max_workers控制并发数比赛环境里可以调到 20 到 30但注意别把目标打挂。路径字典可以根据题目类型增删比如 Java 题加WEB-INF/web.xmlPython 题加app.py、requirements.txt。验证结果时不要只看脚本输出就下结论。脚本报 200 的路径手动访问确认一下内容有些服务器对所有路径都返回 200 但内容是自定义 404 页面。脚本报 403 的路径尝试用不同 User-Agent 或者加X-Forwarded-For头绕过。我自己的习惯是每道题做完后把解题过程写成简短的笔记记录用了什么工具、什么参数、卡在哪里、怎么解决的。积累几十道题之后你会发现很多套路是重复的下次遇到类似题目直接翻笔记就行。CTF 解题能力的提升靠的不是天赋而是这种笨功夫的积累。希望帮到你。本文还有配套的精品资源点击获取