☰
CTF实战套路:从信息收集到Shell提权的骚操作全解析
2026/10/20 23:24:54 网站建设 项目流程

CTF里总有那么一类题,你说它难吧,考点可能一点都不深;你说它简单吧,比赛现场就是想不到。这篇文章想聊的,就是这些被老手们称作“骚操作”的常见套路——它们不一定在每场比赛里都会出现,可一旦出现,对知道的人来说就是送分题,对不知道的人来说就是卡到结束的拦路虎。

我入CTF这个坑也有几年了,从Web到杂项,从逆向到密码,基本都打过一轮。我自己的体会是,真正拉开选手差距的,往往不是谁掌握的高深算法更多,而是谁能在最短时间里想到“这题原来还能这么看”。很多看上去花里胡哨的“骚操作”,本质都只是基础工具的非常规使用,或者是对漏洞原理的多一层推理。但你如果没有提前把它们整理进自己的工具箱,赛场上就很难凭空想出来。

这篇文章就按信息收集、隐写、Web、密码、拿Shell之后这几个方向,把我在比赛里自己用过、也见过别人用得行云流水的招数拆开讲清楚。每条我都会说清楚三个问题:它解决什么问题、原理是什么、实际比赛里怎么用。

1. 开局先捞信息:三个命令打天下

很多题目的第一步不是解题,而是“认东西”。出题人经常把一个文件改个后缀、套个压缩、藏段数据就丢给你,你不知道它是什么,后面所有操作都无从谈起。这时候最能救命的就是三个基础命令:file、strings、binwalk。

1.1 先用 file 确认文件真实类型

我见过太多新手拿到一个没有后缀的文件就开始用十六进制编辑器硬看,其实一条命令就能解决问题。file命令的原理是读取文件的头部特征,也就是所谓的 magic bytes,比如 JPEG 的开头是FF D8 FF,PNG 是89 50 4E 47,ZIP 是50 4B 03 04。你给它一个文件,它告诉你这个文件真实的格式是什么。

比赛里最常见的场景就是“图片”实际上是个压缩包,或者“压缩包”其实是个磁盘镜像。拿到一个叫flag.jpg的文件,别急着用图片查看器打开,先跑一遍file flag.jpg,可能输出直接就是Zip archive data。这种题往往就是为了卡那些一上来就双击打开文件的人。

还要注意一种情况:有些文件会故意在头部伪造另一种格式的特征,让file误判。这种反套路不算多,但如果file的输出和题目描述、文件内容明显矛盾,你就得手工用xxd看头部几个字节,再做判断。综合判断永远比单一工具可靠。

1.2 strings 不等于只找 flag

strings命令用来提取文件里的可打印字符串,看似基础,但用法上有几个容易被忽略的细节。第一,它默认只扫描文件里的一定长度以上的连续可打印字符,所以短字符串有可能漏掉;第二,很多隐写题把关键数据藏在二进制文件的末尾,直接搜字符串又不够精确。

实操里我的习惯是组合使用:

strings -n 6 -a flag.png | head -50 strings -n 6 -a flag.png | grep -iE "flag|ctf|key|secret"

-n 6表示只显示长度大于等于6的字符串,-a表示扫描整个文件而不仅是数据段。这样能过滤掉大量垃圾信息,把注意力集中在可能含有flag、key、secret这类关键词的内容上。

不过得提醒一句:strings只能帮你“看到”线索,不能帮你“拿到”线索。有时候字符串里给出的只是一个文件名、一段URL、一段看似Base64的东西,你还得顺着它继续挖。把strings的输出和grep、base64、hexdump配合起来,才是完整的用法。

1.3 binwalk 不只是解固件

很多人认识binwalk是从路由器固件解包开始的,但它在CTF杂项题里出场频率也极高。它做的事情是扫描一个文件中是否嵌入其他文件,原理是识别文件内部的 magic bytes,然后切分出各个独立的数据块。

最常见的用法:

binwalk -e flag.png

-e是 extract 的缩写,会把识别出来的文件自动解开到目录里。比赛里常见的是一个 PNG 文件里嵌着一个 ZIP,或者一个 JPG 里藏着另一张图,binwalk -e一键搞定。

foremost也是一个同类工具,甚至在某些场景下比binwalk更稳,它专门按文件签名提取,输出到png/、zip/这样的分类目录。我自己遇到binwalk提不出来但确认有隐藏数据的情况,就会切到foremost再试一次。这两个工具互为补充,谁也别嫌弃谁。

2. 隐写题的通用套路:从像素到文件尾

隐写术题目在CTF里属于杂项大类,但其实套路非常固定。新手拿到图片第一反应是“用眼睛找”,但实际上人眼能直接看出来的隐写少之又少。大多数情况下,答案藏在像素的低位、文件的附加区域、或者EXIF信息里。

2.1 LSB隐写和它的变形

LSB 全称 Least Significant Bit,也就是最低有效位。一张图片的每个像素点包含红绿蓝三个颜色通道,每个通道通常占8比特。把每个通道最低的那一个比特抽出来拼在一起,就可能还原出一段隐藏的文本或另一张图片。人眼看不出这种变化,因为最低位的改动对颜色影响微乎其微。

比赛里判断一道题是不是 LSB 隐写,最直接的方式是看图片色调有没有轻微异常,或者题目文件名/描述里有没有暗示二进制、比特、通道之类的词。工具方面我推荐按顺序尝试:

  • zsteg:专门检测 PNG/BMP 的 LSB 隐写,支持逐通道、逐比特位测试,输出里直接能看到隐藏信息
  • stegsolve:Java 写的小工具,能看图片的各个位平面,适合做更细的bit-plane分析
  • cloacked-pixel:Python 实现,对 LSB 提取比较友好

实操步骤通常是拿到图片先用zsteg -a扫一遍,如果没有结果再用stegsolve手动翻位平面。很多新手会忽略的是:LSB 不一定只藏在 RGB 三个通道,Alpha 通道也可能藏数据。zsteg默认会扫 Alpha 通道,但其他工具不一定,务必留意。

2.2 文件尾部和EXIF信息最容易被白送

另一种极其常见的隐写是把秘密直接追加在图片文件末尾。基本原理是,图片查看器读取到某个标记位之后就不再解析后面的数据了,所以就算你在一张完整图片后面追加一个 ZIP、一段文本甚至一个可执行文件,图片在视觉上依旧正常显示,但十六进制编辑器里能看到多出来的内容。

用strings扫到文件尾出现PK或者IHDR之类不该出现的东西,恭喜,这题送分。直接binwalk -e或者手动从偏移量切分数据提取。

EXIF 信息也不该忽略,很多新手容易把注意力放在像素上,忘记了图片的元数据可以藏东西。exiftool一条命令就能列出所有元数据,注释字段、作者字段、GPS 信息都可能是线索。我印象里有一道题把 flag 拆成了几段,分别藏在不同图片的 EXIF 版权字段里,如果不看元数据,光找像素能找一天。

2.3 不只是图片:音频和文件里也有戏

音频隐写也是隐写题的重要分支。常见思路有:把数据藏在音频的频谱图里(用 Audacity 查看频谱图就能看到文字)、用摩斯电码编进杂音里、或者在音频末尾追加一段二进制数据。

遇到音频文件,我建议流程是:先听一遍能不能听见明显规律的声音,再用 Audacity 打开看波形和频谱图,最后用binwalk扫一遍文件里有没有嵌入其他东西。千万别上来就用单纯的理论去推,隐写题很多凭的是“看异常”的直觉。

还有一种更隐蔽的套路是把文件放在另一个文件的“间隙”里,比如 PDF 文件内部的结构块之间插入数据。这种就需要更精细的文件结构分析,但比赛里很少见,真遇到了可以用pdf-parser这类工具慢慢翻。

3. Web题里的过滤器绕过:几个歪招很管用

Web 题依然是CTF的主流方向,而过滤器的存在让很多看起来最简单的注入变得麻烦。很多新手看一眼目标过滤了select、union、空格就觉得没法做,其实绕过技巧的本质就一句话:服务器过滤的只是字符串,不是代码语义。

3.1 参数污染和数组键名的歪招

当后端代码从 GET/POST 参数里取值,却没处理好重复键和数组类型时,就容易出现参数污染。最典型的场景:

?id=1&id=2

有些后端会取第一个,有些取第二个,WAF 可能只检查其中一个而放行另一个。你在参数值里塞进攻击载荷,只要那一层“被检查的参数”是安全的,另一层就等于裸奔了。

数组传参也是常见盲区。PHP 风格的代码里,?id[]=xxx会把id变成一个数组,而如果你传入的是数组,很多字符串过滤函数会直接报错或者跳过,最终拼接 SQL 时却因为强制类型转换或者其他漏洞被利用。遇到这种题,不要只试常规引号和注释符,多想想“参数的其他可能形态”。

3.2 SQL注入里的通配和注释

SQL 注入绕过过滤器的思路,除了编码,还有语义替代。一个很实用的技巧:用/**/代替空格。MySQL 里注释符/* ... */在绝大多数位置都可以当作空格使用,所以:

select * from users where id=1

如果过滤了空格,可以改写成:

select/**/*/**/from/**/users/**/where/**/id=1

如果过滤了select,可以尝试大小写变体、在关键字内部插入注释,例如sel/**/ect。MySQL 解析器会忽略注释片段,最终执行的还是select。这个技巧看似简单,实战里命中率极高。

比较高级的绕过还有利用反引号、利用十六进制字符串替代明文字段值、利用like代替=等。但核心判断标准是:先搞清楚过滤规则匹配的是哪一层。如果过滤器只做了简单的黑名单匹配,而没有任何语义分析,你总有办法通过变体来绕过。

3.3 命令注入的管道与变量拼接

Web 里的命令注入,一般代码会拼出一个 shell 命令字符串,如果没做充分过滤就执行,你就可以通过;、|、||、&等符号插入额外命令。但很多题会过滤cat、flag、空格这些关键内容。

绕过手法里最容易上手的是变量拼接:

c''at /fl''ag c\at /fl\ag

或者利用 shell 的展开机制:

cat /f* cat /???/????

?通配符能匹配任意单个字符,*能匹配任意字符串,这在不知道具体路径或文件名时非常有用。被过滤关键词时,还能用环境变量截取拼凑,比如用${PATH:0:1}取到/字符。这些手法机械地记住了,比现场想来得快得多。

但也要提醒一句:命令注入题的过滤器往往是有层级的,有时候只过滤了cat,没过滤tac、less、more、head、tail。先问自己“它还剩下了哪些能用”,比硬钻被过滤的那几个词更有效。

4. 密码题里快速落地的“偏方”

密码学是CTF里最劝退、也最容易“多做多错”的板块。但好消息是,绝大多数题目考的不是数学推导,而是对已知攻击模型的识别能力。只要你能从题目给出的参数里辨认出“这个场景适合上哪组攻击”,剩下的基本就是调工具跑结果。

4.1 哈希长度扩展攻击:知道什么时候用就够了

哈希长度扩展攻击的前提很明确:服务端使用MD5(secret + message)或SHA1(secret + message)这样的方式来生成校验值,secret 的长度你知道或能猜到,最终校验值就暴露给你了。

这类题目通常长这样:你有一个message,有一个服务端返回的签名sig,你希望伪造一个新的message2,同时算出一个合法的签名。因为 MD5/SHA1 的构造方式决定了它天然存在“长度扩展”性质,所以签名其实可以继续往后接数据。

工具上我常用hash_extender,用法是:

hash_extender --data <原始数据> --secret-length <未知长度> --append <扩展数据> --signature <签名> --format md5

它会输出一个新的数据和新的签名,把这两样东西提交给服务端,就能通过校验。难点永远只在“猜对 secret 长度”,一般从几位到几十位,多试几个长度即可。如果你只知道签名和 secret 前缀长度,不知道原始数据,也可以结合 Padding 的规则推出来,只是手工计算量大了点,建议自动化脚本处理。

4.2 RSA小指数和共模攻击:识别参数比会推导重要

RSA 相关题目的经典攻击模型其实就那么几种:小公钥指数、低解密指数、模数分解、共模攻击。

小公钥指数攻击的特点是公钥指数 e 很小(比如 3),而明文 m 的 e 次方远小于模数 n。这时候密文 c 直接对整数开 e 次方就能还原 m。实操里拿到题目先看一眼e,只要e是 3、7 这种小数字,优先尝试:

python3 -c "from gmpy2 import iroot; print(int(iroot(c, 3)[0]))"

共模攻击的特点则是两条信息共享同一个模数 n,公钥指数分别是两个互质的数。只要密文对应同一明文,就能用扩展欧几里得算法还原明文。这个识别起来非常快:题目里如果反复出现同一个n,又有两组不同的e和c,基本就是共模。

这类题我最大的感触是:不需要记住完整的数学推导过程,但要能一眼认出攻击模型。密码题目大多数不会让你从零发明攻击方法,它们考的就是“你是否知道存在这样一个攻击”以及“你是否会用现成工具”。所以准备阶段,把每种攻击配一个脚本模板存好,比赛里直接改参数跑,比临时推导高效太多。

4.3 别忽略编码层:Base64、Hex、进制混用

很多所谓密码题,终点其实藏在编码层。明文先转成十六进制,再 Base64,再 URL 编码,叠个三四层,看起来就像个密文,其实只需要逐层解码。

我自己的经验是,遇到一串不确定的字符串,先别急着上 AES、RSA,而是按顺序试探:

Base64 -> Hex -> URL编码 -> ASCII码值 -> 反序

尤其 Base64 的特征很容易判断:只包含大小写字母、数字、+、/、=,长度是4的倍数。Hex 的特征是只含0-9a-f,长度必然是偶数。先做这些快速尝试,能筛掉一大批假密码。

5. 拿到Shell之后,怎么翻出更多东西

CTF里的 Web 题,很多并不是以拿到 Shell 为终点,而是以拿到 Shell 为起点。你辛辛苦苦上传了一个一句话木马,或者利用命令注入进到了目标服务器,但 flag 放在某个高层级权限才能读的文件里。这时候怎么横向翻找,也是有固定技巧的。

5.1 环境变量和 /proc 里的信息量很大

拿到执行权限后,第一件事不是急着翻/etc/passwd,而是先看看当前环境里有哪些变量。很多比赛环境里,flag 或关键路径直接写在了环境变量里,甚至是通过 Docker 的-e参数注入进去的。

env

一条命令就能看到全部环境变量。如果 flag 不在环境中,再看进程列表:

ps aux

有时候其他进程的命令行参数里就含着数据库密码、另一台服务器的连接信息,甚至是已经解密出来的缓存结果。

/proc文件系统是Linux下的信息宝库。/proc/1/environ能看到最初进程的环境变量,/proc/1/cmdline能看到启动命令。如果目标环境用的是容器,宿主机进程有时也能通过/proc泄露一些线索。很多比赛中,题目容器里跑的进程不止一个,其中一个就是专门用来存放flag的,你如果用普通方式找不到,多翻翻进程和文件描述符,可能会有意外收获。

5.2 历史命令、临时文件、Shell别名都是线索

Bash 的历史命令文件.bash_history和临时目录/tmp是另外两个高价值区域。如果上一个用户或者出题人在这里运行过某些命令,历史记录里可能直接留下路径或密钥。临时目录里的残留文件也经常被忽略,但里面很可能就是解题入口。

另一个容易被忽视的是 Shell 别名。如果管理员或出题人配置了alias ls="ls -la | grep ..."这类东西,执行ls时看到的结果可能已经是被过滤过的。反过来,如果题目要求你执行某个命令但被拦截,先检查有没有相关别名在捣乱,用unalias绕过。

还有一个小技巧是查找所有可写可执行的目录和文件。拿到低权限 Shell 后,你可以用find / -writable 2>/dev/null找到当前用户有写权限的位置,有时候服务器上的某个服务正好可以读取这些位置,触发二次利用。

5.3 出网受限时的应急思路

拿到 Shell 后经常面对的问题是:服务器不能访问外网,你想下载一个工具传不上去。这时候就得用更原始的手段——直接在目标机上手工编写脚本,或者把工具通过 Base64 编码后放到命令里执行。

我现场常用的一招是:在本机把需要的脚本或二进制做 Base64,然后通过百来行字符串的方式传到目标机上,再在目标机上用base64 -d还原:

echo '大段Base64字符串' | base64 -d > /tmp/tool.py

要注意传输的数据量不能太大,有些平台限制单次命令长度,那就分段传。这个技巧看着笨,但在很多网络隔离场景下是最可靠的。

6. 把这些“骚操作”沉淀成自己的工具箱

我在很多次比赛复盘时发现,真正让我卡住的,往往不是思路没打开,而是“明明知道某种技巧,却因为现场太紧张没有第一时间调出来”。所以这些年我养成了一个习惯:把所有经常用到的单行命令、常见攻击脚本、关键参数变更点,都整理到一个软性的工具箱里。

6.1 常用单行命令速查

下面这些几乎每场比赛都用得上,建议直接复制存起来,需要时改参数就行:

# 文件类型与字符串提取 file 目标文件 strings -n 6 -a 目标文件 | grep -iE "flag|ctf|key" # 隐藏文件提取 binwalk -e 目标文件 foremost 目标文件 -o 输出目录 # 查看元数据 exiftool 目标文件 # 常见编码快速尝试 echo "string" | base64 -d echo "string" | xxd -r -p echo "string" | tr 'A-Za-z' 'N-ZA-Mn-za-m' # ROT13 # 网络信息收集 nc -zv 目标IP 端口 curl -v 目标URL

6.2 从失败的比赛中积累“触发条件”

光有命令还不够,你得知道自己什么时候该调用它。我的做法是给每个技巧记一个“触发条件”,比如:

  • 看到e=3→ 小公钥指数攻击
  • 看到校验值生成方式是 MD5(secret+message) → 哈希长度扩展
  • 图片打不开但文件大小异常大 → binwalk/foremost 提取
  • Web 过滤了空格和关键字 → 注释替代和变量拼接
  • 拿到低权限 Shell → env、ps aux、/proc、.bash_history 全套走一遍

这个“条件反射”列表,比任何高深理论都更有用。比赛场上时间有限,你能在5秒内判断出该往哪个方向试,就已经赢过大多数人了。

6.3 自己制造机会做实验

工具用熟了才会在关键时刻想起来。我强烈建议找一个本地漏洞环境,或者在自己电脑上搭一套 DVWA、SQLi-Labs 之类的靶场,把上面提到的这些招数逐条演练一遍。不需要多么完整,只要让每条技巧都经过你的手敲一遍,赛场上你才会对它有着肌肉记忆一般的反应速度。

我自己的经验是:第一次看这些“骚操作”觉得花里胡哨,但真正动手复现并跑通之后,再遇到类似题目,就不再觉得它们玩法奇特,只会觉得这就是常规解法的一部分。

CTF打到后面,比的还真不是谁掌握的知识冷门,而是谁的“普通操作”更扎实、更像条件反射。希望这些整理出来的套路,能帮你在下一场比赛里少一次卡壳,多一分从容。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询