一套题怎么刷
先广度后深度、分治、工具链——CTF 的解题节奏,比具体 payload 更值得记。
节奏比技巧重要
一场比赛四小时,八道题。新手常见的错误是死磕一道,磕到结束。
有效的节奏是三段:
第一段,半小时,全部过一遍。每道题打开看一眼,判断类型、看有没有明显突破口、估难度。不求解出来,求「知道这八道题分别是什么」。
第二段,按易到难。先把能快速拿下的拿掉。分数是累加的,拿三道简单题的收益,通常高于啃一道难题。
第三段,回头啃。剩下时间给最难的那道,这时候心里没有「别的题还没看」的压力。
这个节奏在真实项目里也适用:先摸清全部暴露面,再按价值排序,别在第一个入口上耗一整天。
分治
一道题卡住,通常是因为问题太大。拆开:
- Web 题:「怎么拿到后台」拆成「后台在哪」「怎么进」「进去之后干什么」。
- Reverse 题:「这个程序在干什么」拆成「输入在哪读」「比较在哪做」「怎么绕过比较」。
- Crypto:「怎么解这个密文」拆成「这是什么算法」「密钥有什么弱点」「能不能绕过算法本身」。
拆到每一步都能动手,就不会卡。
Web 类题目的常见套路
CTF 的 Web 题和真实站点不一样:它们是故意留了洞的,而且通常只留一个。所以思路不是「广撒网」,是「找那个洞」。
高频的几类:
SSTI。输入被拼进模板。Flask/Jinja2 用 {{7*7}} 试探,回显 49 就中。Twig 类似。之后是找可利用的类链。
文件包含。PHP 伪协议是标配:php://filter 读源码,php://input 写内容,data:// 直接执行。日志包含、/proc/self/environ 是老套路但还有题在用。
反序列化。PHP 的 __wakeup / __destruct 魔术方法,Java 的 CommonsCollections 链,Python 的 pickle。看到 serialize、unserialize、ObjectInputStream 就警觉。
JWT。alg: none、弱密钥爆破(hashcat -m 16500)、kid 注入。
XXE。XML 解析没禁用外部实体。<!ENTITY xxe SYSTEM "file:///etc/passwd"> 起步,然后 OOB 带外。
SSRF。让服务器替你发请求。打内网、读云元数据(169.254.169.254)、gopher 打 Redis。
这几类的共同点:都是「功能被滥用」,不是「代码写错了」。理解功能的设计意图,就知道怎么滥用。
复盘
刷完题不复盘,等于白刷。
复盘只做三件事:
- 记下卡在哪。不是「这题不会」,是「我知道是 SSTI,但不知道
__subclasses__之后怎么找可利用的类」。 - 补那一个点。卡在哪补哪,不要从头再看一遍教程。
- 写一句判断。下次遇到同类题,第一个动作是什么。
第三件事最难,也最有用。比如「看到 {{7*7}} 回显 49,先确认模板引擎是 Jinja2 还是 Twig,因为两者的类链完全不同」——这种一句话,比一篇教程管用。
参考
- 《CTF 选手必藏的 50 个实战解题思路》,公众号 HACK之道
- 《BUUCTF-MRCTF2020》,CSDN 存档