CISCN初赛,全称全国大学生信息安全竞赛,每年都会吸引大量学生队伍参加,也是很多CTF选手一年里必打的硬仗。作为一个从大二开始跟着队伍打比赛的老人,这几年从Misc看到Crypto,从Re啃到Pwn,也算把初赛的套路摸了个七七八八。这篇文章想把我在CISCN初赛里积累的实战经验完整拆一遍,按Misc、Re、Pwn、Web、Crypto五个方向逐个讲清楚,每一类题该怎么入手、常考什么东西、用什么工具、踩过哪些坑,全部写成可以直接操作的内容。不管你今年是第一次参赛的新队伍,还是有一定基础想冲更高排名的选手,这篇文章都希望能帮你少走点弯路。
1. 赛前准备与整体策略
1.1 赛制理解与目标设定
CISCN初赛通常是线上解题模式(Jeopardy),一队三到四个人,在限定时间内解一系列分属不同方向的题目,每道题根据难度对应不同的分值。初赛成绩会直接决定能不能进线下决赛,所以第一步不是急着刷题,而是想明白一件事:这个比赛拼的是总分,不是拼谁解出最难的那道题。
我见过太多队伍一上来就扎进Pwn里死磕一两个小时,结果Misc和Web送分题都没来得及看。这种策略在CTF里是最大的坑。CISCN初赛的几个方向里,Misc和Web往往存在大量“基础分”,Crypto和Re次之,Pwn通常是区分度最高的部分。合理的目标应该是:确保Misc和Web拿全该拿的分,Crypto和Re尽量解出常规题,Pwn能做出一道保底题就算成功。
1.2 团队分工与环境清单
队伍里一般三个人比较理想,一个人主攻Web和Misc,一个人主攻Re和Crypto,另一个人主攻Pwn。但初赛题目多、时间紧,真正高效的分工是“一主一辅”:比如主攻Web的选手还要顺便把Misc的流量分析题接过去,主攻Pwn的选手也要会基本的逆向分析,因为很多Pwn题先用IDA看看伪代码能节省大量时间。
赛前环境准备这一步,很多队栽过跟头。建议至少提前三天把所有人的虚拟机环境统一好:
- 系统:推荐Ubuntu 22.04或Kali,避免有人Windows有人Linux导致动态库不一致。
- 常见工具链:IDA、Ghidra、gdb、pwntools、Wireshark、Burp Suite、binwalk、strings、file、CyberChef。
- Python环境:装好python3-pip,确保numpy、z3、pycryptodome、requests这些常用库能直接跑。
注意:比赛当天网络环境不稳定是常态,所有工具、脚本、字典、插件必须提前下载好并本地测试通过,不要指望现场临时拉依赖。这个坑我连续踩过两年,后来学乖了,专门把常用工具打包成一个离线目录。
1.3 做题顺序与时间管理
CISCN初赛时长通常是8小时左右,我会把时间切成三段:
- 前1到1.5小时:集中扫Misc和Web的签到题、基础题,这类题往往看完描述就有思路,属于白给分。
- 中间2到3小时:做Crypto和Re的常规题,遇到卡住的地方先放一放,不要恋战。
- 最后2小时:留给Pwn和还在卡着的题目,把已经做出来的题目再复查一遍,确认flag格式、交卷流程无误。
这个顺序不是固定的,但思路很明确:把确定性高的分先拿到手,再去搏那些需要长时间思考的高分题。另外建议队伍里有人专门负责“盯榜”,看着自己队伍排名变化的同时,也看看哪些题被解出来的队伍数量特别多。一道题如果解出人数突然飙升,说明它可能并不难,值得立刻投入人手。
2. Misc方向:最容易白给的隐藏分
2.1 初赛Misc的出题套路
Misc(杂项)在CISCN里地位很特殊,它是观赏性最低但得分率最容易拉满的方向。初赛里的Misc常见考点就那么几类:文件类型识别与分离、图片隐写、流量包分析、压缩包处理、编码转换。出题人通常不会考特别偏门的隐写算法,更多是把几个基础知识点组合在一起,形成一道多步骤的题。
很多新手有个误区,觉得Misc就是“碰运气”,拿个StegSolve到处点一点。实际上Misc题同样有清晰的解题链路,最关键的是先回答三个问题:这个文件是什么?文件里有没有藏着其他东西?藏的东西经过了什么处理?
2.2 图片隐写实操记录
图片类隐写是Misc最高频的考点。拿到一张图片,我的固定流程是这样的:
- 先跑file命令确认真实文件类型,因为题目经常把文件名后缀改掉,或者直接把一个zip文件伪装成png图片。
- 再用strings提取可见字符串,优先找尾部有没有base64特征或者可疑的注释内容。
- 用binwalk扫描文件里是否有嵌入的其他文件或zip头。
- 最后才上StegSolve等隐写工具查看LSB通道、不同通道组合、图片有没有像素层面的异常。
记得初赛时遇到一道PNG图片题,file和binwalk都没发现问题,StegSolve翻了一遍RGB通道也看不出异常。后来我把图片放大看了左下角,发现有几个像素的颜色和周围明显不一样,提取出来是一串十六进制,转ASCII后发现是压缩包的密码。密码解开后是一个文本文件,里面内容看起来像乱码,再拉去CyberChef尝试多种编码,最终确认是rot13。这种题不复杂,但每一步都需要耐心和细心。
图片隐写容易遗漏的细节包括:Exif信息里的注释、图片尾部附加的数据、GIF每一帧之间的差异、PNG的IDAT块是否存在异常。只要把这些点都覆盖到,大部分图片题都能解出来。
2.3 流量包分析实操记录
流量分析题基本人手一个Wireshark。CISCN的流量包一般不会让你费劲去解码复杂协议,最常见的是HTTP流量和DNS流量。
处理HTTP流量,我习惯先用过滤表达式把http包列出来,看大致有哪些请求和响应,然后按文件大小排序,找那些响应体明显很大的包,跟踪TCP流直接看原始数据。很多题目会把一个压缩包或者脚本放在HTTP响应里,文件头被转成了base64或者十六进制文本,稍微还原就能拿到后续线索。
DNS流量则更多用来隐藏信息,比如查询的域名子域名部分拼起来是一段经过编码的数据。遇到这种情况,我会先导出所有DNS查询的name字段,按顺序排列,去掉常见的解析前缀,然后连起来统一解码。
经验心得:流量包题最忌从头到尾漫无目的地看包。正确做法是先看“标注了关键字的包”,在Wireshark里直接搜索flag、passwd、admin等关键词,常常一两秒就能直接定位到关键位置。如果题目里明确说“上传了一个文件”,那就直接用“文件→导出对象→HTTP”把所有传输的文件导出来,比自己一个包一个包翻高效得多。
2.4 Misc避坑清单
- 不要一上来就套解密脚本。先判断数据到底是什么编码,避免把hex当成base64、把base64当成换表,解码顺序错一步全盘皆输。
- 压缩包有密码时,优先看压缩包里的文件名有没有注释,密码经常就藏在文件名、文件属性、图片Exif里,而不是非得去爆破。
- 想要爆破时,先试试5位以内的纯数字,CISCN这类比赛很少用12位随机密码为难选手。
- 文档类文件(docx、xlsx)本质是zip,解压后直接看xml和media目录,可能存在隐藏内容。
3. Web方向:信息收集决定分数上限
3.1 初赛Web的常见入口
Web方向在CISCN初赛里基本上是必考的,而且题目数量多、分值分布广。Web题的共性规律是:信息收集决定上限。一个站点如果连源码都泄露了,那这道题基本就是白送;如果找不到源码,就只能通过黑盒测试去猜逻辑漏洞。
信息收集阶段我会按这个顺序来:先看首页和响应头,再扫描目录和备份文件,然后看有没有版本信息泄露,最后才考虑具体的注入或者上传漏洞。响应头里经常出现很关键的信息,比如X-Powered-By暴露了后端语言,或者Server字段里的版本号直接对应某个已知漏洞。CISCN初赛特别喜欢出“源码泄露类”题目,常见的有.git目录泄露、.svn目录泄露、备份文件(.bak、.zip、.swp)、编辑器临时文件等。用dirsearch或者gobuster扫一遍,往往立刻就能看到源码文件。
3.2 注入类题目的判别与利用
SQL注入在Web题里是老面孔。CISCN初赛里的SQL注入题通常不会让你手工盲注几个小时,更多是把注入点放在一个比较容易触发的场景里,比如登录框、搜索框、排序参数。
标准做法是先判断注入类型。输入一个单引号看报错情况,用order by测列数,再用union select构造联合查询。如果页面不显示任何错误信息,就要考虑盲注:用substr配合ASCII函数逐字符提取数据,写一个Python脚本循环请求。
举一个常见场景:某个排序参数sort=id,尝试sort=1,2,3看排序结果是否变化,确认存在数字型注入。再用sort=(select if(1=1,id,title))测试布尔条件是否生效。如果生效,就可以写脚本用二分法逐字符提取数据库里的表名和字段名,最终拿到flag。这里有个小技巧,很多新手不知道的:CISCN这类比赛的flag通常就放在当前数据库的第一张表里,字段名一般叫flag或者fl4g,不用费劲去枚举所有表。
3.3 文件上传与命令执行的绕过思路
文件上传题考察的是对服务端校验规则的绕过能力。常见防线有三层:前端JS校验、后端MIME校验、后端内容校验。前两层非常好绕,用Burp Suite改请求包即可,关键是第三层。
初赛中比较常见的绕过手段有这么几种:
- 后缀名大小写混淆:.png改成.PNG,Windows和部分Linux解析时可能不区分。
- 可解析后缀:.php3、.phtml、.php5等老版本环境可能解析。
- 图片马:在图片后面拼接PHP代码,配合文件包含漏洞触发。
- 空格与点绕过:Windows系统会自动去除文件名末尾的空格和点,如shell.php. 或者shell.php空格。
- 双写绕过:如果过滤规则只是把php字符串替换成空,那直接写pphphp就能绕过。
命令执行题则是另一个高频考点。题目可能会给你一个ping参数或者一个传入系统命令的接口,同时过滤了空格、分号、管道符等关键字。绕过空格可以用$IFS$9或者tab字符,比如cat$IFS$9/flag。绕过关键字可以用拼接或者base64编码后执行,例如echo base64字符串 | base64 -d | bash。
3.4 Web实战复盘与请求细节
拿我打过的一场初赛举例,有一道Web题打开是一个登录页,默认账号密码进不去,扫描目录发现存在index.php.bak源码文件。源码里看到登录逻辑,SQL语句直接拼接了用户名,但密码用了md5()处理。这意味着用户名处存在注入点,而密码处因为做了哈希处理无法直接注入。于是我用用户名注入,构造了一个恒真条件,同时密码随便填一个MD5值,成功登录后台。后台里有个功能点可以读取服务器上的文件,参数直接用相对路径拼接,读取时需要绕过路径限制,最终利用../逐层穿越到根目录拿到了flag。
这道题本身不难,但需要按部就班走完“信息收集→源码审计→构造注入→读文件”整条链路。很多队伍卡在第一步源码泄露上,因为他们没有扫目录的习惯,直接在登录页死磕万能密码,白白浪费大量时间。
做Web题的时候,多留意请求包的细节也很重要。有时候flag就藏在隐藏的响应头、cookie、注释里。比如某题登录成功后页面显示“欢迎您”,查看响应头发现Set-Cookie里带了一段奇怪字符串,解码后就是一半flag,另一半在页面源码注释里。这种把flag拆开藏的做法,在初赛里我已经见过不止一次。
4. Pwn方向:栈漏洞依然是主力
4.1 拿到Pwn题的标准流程
Pwn是很多队伍最害怕的部分,但它其实是最能靠熟练度拿分的。CISCN初赛的Pwn题往往不给废话,拿到题目后先跑两条命令:file看架构和位数,checksec看保护机制。
checksec的输出决定后续所有利用策略。如果看到NX开启,就不能直接在栈上执行shellcode;看到Canary开启,就得想办法绕过栈保护;看到PIE开启,说明地址是随机的,需要先泄露地址才能计算偏移。这些保护机制在初赛里不会全部同时开启,通常只会开NX和Canary,最多加个Partial RELRO。
然后是逆向分析。用IDA打开二进制文件,找到main函数,再看哪些函数里有危险的输入函数,比如gets、strcpy、read、scanf等。CISCN初赛的Pwn题通常漏洞点非常明显,不会绕弯子让你逆半天,基本就是某个函数直接往里读数据没限制长度。
4.2 栈溢出利用实例:ret2text全流程
最容易拿分的Pwn题型就是ret2text。逻辑很简单:程序里已经存在包含system("/bin/sh")或者直接读flag的函数,你只需要通过栈溢出覆盖函数返回地址,让程序跳过去。
第一步算偏移量。用pwntools的cyclic工具生成一串随机字符,作为输入发给程序,程序崩溃后查看gdb里的RIP值。再用cyclic -l反查偏移量,或者直接用gdb的pattern search命令。这个偏移量就是你的payload里从输入开始到返回地址之间的长度。
第二步构造payload:
from pwn import * io = process('./pwn') payload = b'A' * offset + p64(backdoor_addr) io.sendline(payload) io.interactive()这是最基础的写法,但注意两个细节:一是backdoor_addr需要是函数真实地址,如果程序开了PIE,需要先通过泄露地址算出基址再加偏移;二是如果程序是64位,还要检查是否有栈对齐问题。栈对齐这个坑让我卡过很久,有时system("/bin/sh")在调用时会因为栈未按16字节对齐而直接崩溃,解决办法是在返回地址后面再补一个ret指令的地址,相当于多跳一次。
4.3 保护机制理解与绕过要点
初赛里出现频率更高的其实是ret2libc,因为如果真有一个现成的backdoor函数,这题就太简单了,出题人通常会把这个“后门”藏得更深一点。ret2libc的核心思路是通过栈溢出调用libc里的system函数,同时把"/bin/sh"字符串作为参数传进去。
前提是泄露libc地址。最常见的手法是用PLT/GOT表:printf或puts函数在程序里已经被调用过,它的真实地址存储在GOT表里。我们通过栈溢出调用puts@plt,参数是某个函数的GOT地址,这样puts就会把该函数在内存里的真实地址打印出来。拿到真实地址后,减去本机libc中这个函数的偏移,就能得到libc基址,进而算出system和"/bin/sh"的地址,最后再构造一次调用即可getshell。
Canary则是另一道坎。当程序开启了栈Canary保护后,缓冲区溢出时如果覆盖到了Canary值,程序会直接终止并报错。绕过思路不外乎两种:一是利用格式化字符串漏洞把Canary值泄露出来,因为它位于栈上固定的位置;二是通过逐字节爆破,因为Canary最低位是0x00,实际有效的爆破工作量可控。前者更常见,很多CISCN初赛题会把格式化字符串和栈溢出放在一起考,先让你格式化字符串泄露地址,再正常溢出。
4.4 Pwn调试小技巧
调试Pwn题非常依赖gdb,但原生gdb用起来效率太低,我建议装好pwndbg或GEF插件。它会在断点处自动显示寄存器、栈内容、反汇编指令,节省大量输入命令的时间。
常用的调试习惯是:先用IDA看静态逻辑确定漏洞位置,再用gdb在漏洞函数附近下断点,用cyclic生成输入运行,观察崩溃时的寄存器状态来确认偏移。格式化字符串利用过程中,用gdb看栈布局,可以快速确认格式化参数对应的栈偏移是多少,避免反复猜测。
注意:写Pwn利用脚本时一定要先远程验证再大规模跑,不要等到比赛最后才来调试脚本。我记得有一次在一个格式化字符串漏洞上卡了很久,最后发现是printf的参数位置算错了一位,这种错误在紧张状态下特别容易出现。建议平时就准备一个标准模板脚本,把process流程、偏移计算、地址拼接都写成函数,现场直接套用。
5. Re方向:从入口点开始逆推算法
5.1 初步静态分析思路
Re(逆向工程)方向考察的是分析二进制程序逻辑、还原算法、编写注册机的能力。CISCN初赛的Re题难度一般不高,多数是Windows下的小PE文件,偶尔有Linux下的ELF,以及部分安卓APK。拿到题后的第一步永远是查壳和识语言:用Detect It Easy看有没有加壳,用strings看有没有提示性字符串。
如果程序没加壳,直接上IDA。我的分析路径是:找main函数或start函数,顺着字符串引用找关键逻辑。程序里如果有“请输入flag”或者“wrong/right”这类字符串,直接交叉引用到判断逻辑处,那基本就是核心校验代码所在。
看伪代码时,优先关注循环和数组操作。凡是对一个输入字符数组做循环异或、加减、交换的,基本就能确定是在做某种自定义加密变换。把逻辑还原出来之后,最直接的办法就是让程序自己告诉你结果——用动态调试把校验函数的输入直接替换成预期值去看行为,或者更简单粗暴地用IDA的patch功能修改跳转条件,强制程序输出成功。
5.2 动态调试中的常见操作
动态调试通常用gdb或IDA的调试器。CISCN初赛的Re题里,动态调试最常用的场景有两个:一个是在关键比较处下断点,看程序拿什么和输入做比较,直接内存里就能查看那串密文;另一个是修改寄存器和跳转条件,实现“就算输入错误也能显示正确”。
比如常见的if (strcmp(input, key) == 0)结构,在汇编层面对应一个test指令后跟jz/jnz跳转。用调试器在跳转指令处下断点,手动把ZF寄存器改掉或者直接把EIP跳过跳转指令,程序就会走“成功”分支。这种方法适合快速验证思路,但不能用来交题,因为真实比赛要求你提交正确的输入字符串,而不是只让程序显示成功。
有时也会遇到反调试,但初赛基本不搞太复杂的反调试,最多就是检查ptrace调用或者混淆几个关键字符串。遇到这种情况,先尝试把反调试函数patch掉,或者用IDA插件反混淆,正常都能解决。
5.3 算法识别与脚本还原
Re题的另一个重点是识别加密算法。很多程序不是自己发明变换,而是直接调用了常见加密库,比如base64、MD5、AES、RC4。识别方法很简单:查伪代码里有没有明显的常量表。base64的特征是那张包含大小写字母、数字、+和/的索引表;RC4的特征是初始化时对一个256字节的S盒做交换;AES的特征是有固定的S盒和轮常量表;MD5的特征是四个幻数0x67452301、0xEFCDAB89等。
识别到算法后,解题就变成了找密钥和密文。把闭源程序当黑盒,用调试器在加密函数返回处查看输出缓冲区,直接拿到密文。密钥通常也在内存里能找到,或者通过逆推编码逻辑组合出来。最后用Python脚本做逆向运算,把密文变成输入flag即可。
有一个特别实用的技巧:如果输入的flag最终会被换算成一个固定字符串与密文比较,那就别手算,直接用z3求解器。把程序里的加密运算抽象成约束条件,让z3反推未知输入。尤其是那种“输入长度很小、变换过程由加减异或组成”的题,z3几乎是一键解法。
5.4 Re常见误区
- 不要一上来就硬刚算法。先看有没有现成的字符串,比如flag前半段可能就直接出现在程序里。
- 不要只做静态分析。能和动态调试结合的最好都结合,尤其是确定输入长度和内存布局时,动态看比静态猜准得多。
- APK类题目别急着去逆Native层。先解包看dex里的Java代码,用JADX打开直接看逻辑,很多APK题的flag就在Java层写死。
- 还原算法时要小心字节序,特别是处理32位和64位混用的情况,一个小地方搞错整个解密全乱。
6. Crypto方向:套路识别大于硬算
6.1 先判断加密类型再做计算
Crypto(密码学)对数学基础要求比较高,很多选手看到一大串数字就头大。实际上CISCN初赛的Crypto更偏向“识别套路”,真正需要现场推导高级数学定理的题目很少。拿到题第一步是判断这属于哪一类:编码类、古典密码、对称密码、非对称密码、还是哈希相关。
最简单的判断工具是CyberChef。它能把hex、base64、URL编码、栅栏密码、凯撒密码等各种常见编码格式一键转换,界面左侧是编码类型,右侧是输出结果。你只需要把题目给的字符串贴进去,逐个尝试常见编码类型,经常会直接得到明文。
编码类题目考的是基本功。看到一个字符串,先识别字符集特征:全大写小写字母加数字可能是base64;全是十六进制字符可能是hex;由多个0到255之间的数字组成可能是ASCII码数组;出现大量重复字符可能经过了某种置换或者维吉尼亚密码。这些东西不需要死记硬背,做多了自然有直觉。
6.2 初赛高频Crypto考点:RSA
RSA在CISCN Crypto里几乎是必考的,但基础题通常不会让你分解一个大质数,而是考察你对各种特殊参数的敏感度。以下三类出现频率最高:
第一种是低加密指数攻击。题目给的e很小,比如e=3,而c明显小于n,说明m的e次方没有取模,直接对c开e次方就能恢复明文。脚本很直接:
from gmpy2 import iroot from Crypto.Util.number import long_to_bytes c = 开头给出的密文 m, result = iroot(c, 3) print(long_to_bytes(m))第二种是共模攻击。同一个n,两组不同的e和c,且gcd(e1, e2) = 1,就能用扩展欧几里得算法算出明文。这个攻击的原理是:既然两次加密用的是同一个n,那密文和明文之间的关系就有了可推导的空间,通过对两个指数做贝祖等式组合,把明文从密文里解出来。初赛里给出“共模”提示的题非常多,这个套路必须熟练。
第三种是维纳攻击(Wiener Attack)。特征是e特别大,接近n的规模,同时d很小。用连分数展开e/n,逐项尝试作为d,能快速求出私钥。这种题直接调现成脚本就行,但需要看懂脚本里的连分数实现,否则报错时完全不知道问题在哪。
做题时还要注意:给了p或q的近似值、给了dp或dq这类泄露信息,都属于基础RSA的变种。先把RSA常见攻击脚本整理成自己的一个目录,比赛时按特征匹配,能省下一大半推导时间。
6.3 对称密码与哈希的实战应用
对称密码方向的题不像RSA那样有那么多现成攻击脚本,更多是考察对模式的理解。CBC字节翻转攻击是初赛常客,它的核心是:CBC模式下每个密文分组解密后都会与上一组密文异或,所以篡改上一组密文的某一位,就会让下一组明文对应位置被翻转成任意值。这种题出现时,题目通常会给你一个二次输入的选项,利用翻转把管理员权限字段改成true,或者把用户名改成admin。
哈希长度扩展攻击也很经典。如果一个服务器用secret +消息拼接后取MD5作为校验值,而你知道了长度但不是secret的内容,就可以在不知道secret的情况下构造一个合法的校验值,让服务器认为消息没被篡改。这种题需要安装hashpump工具或者调用相关Python库,关键是确认secret长度,通常从1开始逐个尝试,校验成功后就能确定。
6.4 Crypto拿分策略
Crypto题目的难度分布很极端,通常有一道“一眼题”是给你一段密文和一个在线解密网站的提示,解出来就是flag;另一道完全没思路的可能是密码分析题,硬啃很浪费时间。我的策略是:先把容易识别的编码题和基础RSA题全部解决,剩下那道难题放到最后再看,不要因为一道Crypto死磕而影响其他方向的得分。
实际操作中,解Crypto题一定要把过程写清楚。很多题目要求提交的flag是某个中间值,比如解出来的明文、私钥的某一部分、甚至是一个特定函数的返回值。如果脚本里直接把整段明文打印出来但忘了格式化,提交时少个花括号或者多个空格,判断为错误,心态就崩了。建议统一封装一个提交验证函数,自动去除首尾空白后直接复制到答题框。
7. 常见问题与赛后复盘
7.1 赛场中最容易掉的坑
整理几年打CISCN初赛的经验,赛场里丢分最常见的原因不是“不会做”,而是“做出来了没法确认”。以下这些问题几乎每年都会遇到:
- Flag格式错误:CISCN的flag通常是flag{...}格式,但有些题目的flag是纯字母数字不带花括号,甚至有的题目要求提交md5后的值。交的时候先看清楚要求,别盲目提交。
- Python版本不一致:本地写脚本时用的Python3.10特性,赛场的Python3.8跑不起来;或者某些依赖库版本不同导致结果不同。建议平时统一用3.8或3.10,并在脚本里避免使用过于新版的语法。
- 网络波动导致中途掉线:远程容器题目一旦掉线,环境可能重置。做Pwn和Web题时先把payload和脚本备份到本地,再重新连接环境,重新打一遍速度会快很多。
- 误判flag藏在哪:有的题目flag不是一个完整字符串,而是要拼接两半,有些在响应头里,有些在cookie里,有些藏在图片的元数据里。提交前养成习惯,把上下文全部扫一遍再交。
7.2 赛后复盘的正确姿势
比赛结束不是任务的终点,复盘才是真正拉开差距的环节。我要求自己赛后48小时内把每一道题都写出writeup——不管做没做出来。写writeup的过程会强迫你重新梳理思路,尤其是那些卡了很久的题,你会发现当初卡住的原因往往是某个知识点没串起来。
复盘时还要整理“解题工具矩阵”。每个方向的题目,我把解题流程做成一张清单,比如Misc就是“查文件类型→扫字符串→分离→隐写解码→压缩包处理”,Web就是“信息收集→源码审计→漏洞利用→拿flag”。有了这个矩阵,下一场比赛大家分工时就能直接照着流程走,不用每次从零开始思考。
7.3 给下一届选手的建议
如果你还在备赛阶段,有三件事现在就可以做起来:
第一,把CISCN往年题目当成模拟题刷。每道题都自己动手做一遍,不要只看writeup。做不出来的题卡半小时以上再看答案,看完答案后要亲手复现,直到跑通为止。只看不练等于没看。
第二,建立属于自己的脚本库。把RSA攻击脚本、SQL注入脚本、栈溢出模板、Misc编码转换脚本全部汇总到一个目录,配上使用说明。比赛时临时搜索脚本非常浪费时间,自己的脚本库拿到手就能改。
第三,多打线上赛练节奏。CISCN初赛的难度和节奏,和很多线上CTF比赛类似。每周抽一个晚上打一场小型比赛,隐藏目标不是排名,而是训练“几个小时内完成多方向题目”的切换能力。
我的体会是,CISCN初赛更像一场体力和心态的马拉松,比的不是某一道难题的突破,而是团队整体在多方向上的稳定输出。这几年看下来,很多强队未必能把每道题都解出来,但他们的每个方向都有保底分,总分自然就上去了。希望这篇攻略能帮你把五个方向的思路都串起来,备赛时少走弯路,赛场上稳稳拿分。最后再分享一个细节:比赛期间每做出一道题,就立刻录进队伍共享文档,写上关键思路和flag提交格式。这个习惯能帮你的队伍在最混乱的冲刺阶段保持清晰的节奏。