
MISCELLANEOUS — CTF 最佳入门方向
Misc 是英文 Miscellaneous 的前四个字母,杂项、混合体、大杂烩的意思。Misc 在国外的比赛中其实又被具体划分为各个小块:
在国内的比赛中,被统一划分入 Misc 领域,有时 Crypto(尤其是古典密码)也被划入其中。CTF Wiki 从以下几个方面介绍:
Misc 是切入 CTF 竞赛领域、培养兴趣的最佳入口。Misc 考察基本知识,对安全技能的各个层面都有不同程度的涉及,可以在很大程度上启发思维。想学网安又不知道从哪开始?就从 Misc 开始。
A-Z / a-z 对应 1-26 或 0-25。例如 15 14 3 即 NUC(13 空格?实际 15=N,14=O,3=C —— NOC)。出现「纯数字、范围 1~26」要想到字母表。
我们一般使用的 ASCII 编码采用的都是可见字符,而且主要是如下字符:
变形 1 · 二进制编码:把 ASCII 码对应的数字换成二进制表示,只有 0 和 1,不超过 8 位。
变形 2 · 十六进制编码:换成十六进制,如 A-Z → 0x41~0x5A、a-z → 0x61~0x7A。
# Python 快速转换
s = "01001000 01100101 01101100 01101100 01101111" # 二进制
print("".join(chr(int(x, 2)) for x in s.split())) # Hello
h = "48656C6C6F" # 十六进制
print(bytes.fromhex(h)) # b'Hello'
base xx 中的 xx 表示的是采用多少个字符进行编码。比如 base64 采用 64 个字符(A-Z、a-z、0-9、+、/),由于 2 的 6 次方等于 64,所以每 6 个比特为一个单元,对应某个可打印字符。3 个字节有 24 个比特,对应 4 个 Base64 单元。
= 号,但最多 2 个== 的 hex 是 3Dimport base64
print(base64.b64encode(b"flag")) # b'ZmxhZw=='
print(base64.b64decode("ZmxhZw==")) # b'flag'
# base32 / base16 同理:base64.b32encode / b16encode
XXencode 将输入文本以每三个字节为单位进行编码,以 6bit 为单位分为 4 个组,用位置字符代替。特点:只有数字、大小写字母、+ 号、- 号。在线工具:web.chacuo.net/charsetxxencode。
也叫百分号编码,特点:大量的百分号,如 %66%6C%61%67(flag)。%20 是空格、%27 是单引号。CTF 中常与注入绕过结合。
注意它有四种表现形式(源文本 The):
The( [Hex])The( [Decimal])\U0054\U0068\U0065(\U)\U+0054\U+0068\U+0065(\U+)这些属于「现实世界中常用的编码」:摩斯(. - 组合)、二维码(QR 直接扫)、培根密码(5 位 0/1 或 a/b 组合)。看到「点横」「黑白格子」「两个字符的序列」就往这些方向想。
隐写取证是 Misc 中最为重要的一块,包括文件分析、隐写、内存镜像分析和流量抓包分析等。CTF 中 Misc 与现实取证不同:现实取证多为恢复残损文件、挖掘硬盘痕迹;而 CTF 中更多是巧妙的编码、隐藏数据、层层嵌套的文件。
http / ftp / dns 等过滤器缩小范围flag、Base64 串、上传的文件| 工具 | 用途 |
|---|---|
| 010 Editor / WinHex | 十六进制编辑器,看/改文件头 |
| binwalk | 分析文件内嵌的其他文件 |
| StegSolve | 图片隐写分析(通道查看、LSB) |
| zsteg / stegsolve | LSB 隐写提取 |
| Wireshark | 流量包分析 |
| Audacity | 音频分析(频谱) |
| ARCHPR | 压缩包密码破解 |
| Volatility | 内存取证(进阶) |
| Python + PIL | 写脚本拆帧、改像素、转编码 |
场景:下载「大白」图片(附件在 BUUCTF 题目页下载),打开发现图片显示不全,flag 藏在被裁掉的部分。
import struct
data = open('dabai.png', 'rb').read()
w = struct.unpack('>I', data[16:20])[0] # 宽度
print('width =', hex(w))
data = data[:20] + struct.pack('>I', w) + data[24:] # 高度改为宽度
open('dabai_fixed.png', 'wb').write(data)
💡 「图片长宽不符 = 改宽高」是 Misc 最经典套路之一。
场景:一个 gif 有很多帧,每帧是黑白小图。
from PIL import Image
im = Image.open('gif.gif')
bits, frame = '', 0
while True:
try:
im.seek(frame)
px = im.convert('L').getpixel((0, 0))
bits += '0' if px < 128 else '1' # 若乱码则交换 0/1
frame += 1
except EOFError:
break
print("".join(chr(int(bits[i:i+8], 2)) for i in range(0, len(bits), 8)))
💡 同类套路:二维码、LSB、字符画,本质都是「信息藏在视觉冗余里」。