CTF 隐写术全解析:从图片到音频的 “藏 flag” 技巧
初步检查用file命令确认文件类型(防止文件后缀欺骗,如.jpg实际是zipfile secret.jpg # 输出:secret.jpg: Zip archive data, at least v2.0 to extract元数据与注释用exiftoolexifread读取所有元数据,检查是否有异常字段(如FlagComment文件分离用binwalk -e自动提取嵌入式文件(如图片中的 ZIP
目录
CTF 隐写术全解析:从图片到音频的 “藏 flag” 技巧
3. MP3 ID3 标签:伪装成 “元数据” 的 flag
三、文档与压缩包隐写:从 PDF 到 ZIP 的 “伪装术”
在 CTF 的 Misc 题型中,隐写术(Steganography)是将信息隐藏在普通文件(图片、音频、文档等)中而不被察觉的技术。与密码学通过加密保护信息不同,隐写术的核心是 “隐藏信息的存在”。解题的关键在于 ——找到信息的隐藏位置:可能是图片像素的最低位、音频频谱的间隙、文档的隐藏图层,甚至是压缩包的伪加密标志位。本文将系统梳理 CTF 中主流载体的隐写方法,结合工具使用与实战案例,带你从 “观察异常” 到 “提取数据”,完成隐写术的完整破解流程。
一、图片隐写:像素与文件结构中的 “秘密”
图片是隐写术最常用的载体,PNG、JPG、GIF 等格式因结构特性不同,隐藏信息的方式也大相径庭。
1. PNG 隐写:从 LSB 到 tEXt 块的多层隐藏
PNG 格式因无损压缩、支持透明通道等特性,成为 CTF 隐写的 “常客”。其隐写技巧主要集中在像素最低位(LSB)、图像块(Chunk) 和CRC 校验三个层面。
(1)LSB 隐写:像素的 “最低位密码”
原理:PNG 图像的每个像素由 RGB 三通道组成(如每个通道 8 位,取值 0-255)。修改通道值的最低 1-2 位(LSB)不会影响视觉效果,但可用来存储二进制数据(0/1)。例如,将像素红色通道值从10101101改为10101100,人眼无法分辨,但可记录 1 位信息。
实战步骤:
-
工具选择:用
Stegsolve(图形化工具)或zsteg(命令行工具,支持 PNG/JPG)提取 LSB 数据。Stegsolve操作:
打开图片→Analyze→Data Extract→勾选Red 0(红色通道最低位)、Green 0、Blue 0→观察右侧输出是否出现二进制 / 文本数据。zsteg命令:zsteg -a secret.png # 自动检测所有可能的LSB组合 zsteg secret.png -e b1,r,lsb,xy # 提取指定通道(b1=1位,r=红色通道,lsb=最低位)
-
案例:某 PNG 图片通过 LSB 隐藏 flag,用
zsteg提取:zsteg secret.png | grep "flag" # 过滤含flag的结果 # 输出:b1,g,lsb,xy.. text: "flag{lsb_steganography_is_easy}"
(2)PNG 块隐藏:tEXt 块与附加数据
原理:PNG 文件由多个块(Chunk)组成,包括IHDR(图像头)、IDAT(数据)、IEND(结束)等。除标准块外,可添加tEXt(文本注释)、zTXt(压缩文本)等块隐藏信息,这些块不会影响图片显示。
实战步骤:
- 用
pngcheck分析块结构:pngcheck -v secret.png # 详细输出所有块 # 若出现tEXt块,会显示:tEXt 123 "comment" (contains text data) - 提取 tEXt 块数据:
- 用
foremost分离块数据:foremost secret.png -o output # 在output目录生成png文件和附加数据 - 直接用文本编辑器打开 PNG 文件,搜索
tEXt关键字,其后的 ASCII 数据可能为 flag。
- 用
(3)CRC 校验爆破:修改图片内容后的 “数据修复”
原理:PNG 每个块的CRC字段(4 字节)是对块内容的校验值。若修改图片像素(如隐藏信息)但未更新 CRC,会导致校验失败。通过爆破 CRC 可反推原始像素数据或提取隐藏信息。
案例:某 PNG 图片被修改了 1 个像素,导致 CRC 错误,需爆破原始像素值:
- 用
pngcheck定位错误块:pngcheck secret.png # 输出:secret.png: CRC error in chunk IDAT (computed 0x12345678, expected 0x87654321) - 编写 Python 脚本爆破:
假设错误块为IDAT,修改区域为 1x1 像素(3 字节 RGB),爆破可能的像素值使 CRC 匹配:import zlib import struct # 已知块数据(省略部分字节,仅保留修改区域) block_data = b'\x00\x00\x00...' # 块内容(不含CRC) expected_crc = 0x87654321 # 预期CRC # 爆破RGB值(0-255) for r in range(256): for g in range(256): for b in range(256): modified = block_data[:10] + bytes([r, g, b]) + block_data[13:] crc = zlib.crc32(modified) & 0xFFFFFFFF if crc == expected_crc: print(f"找到原始像素:R={r}, G={g}, B={b}")
爆破得到的像素值可能对应 ASCII 字符(如r=102→'f',g=108→'l'),拼接成 flag。
2. JPG 隐写:DCT 系数与注释中的 “漏洞”
JPG 是有损压缩格式,隐写方式与 PNG 不同,主要利用DCT 系数篡改和注释字段。
(1)JPG 注释与 EXIF 信息
原理:JPG 文件的 EXIF 元数据(如作者、注释、GPS 坐标)可存储文本信息,用exiftool即可读取。
实战命令:
exiftool secret.jpg # 查看所有元数据
exiftool secret.jpg | grep "Comment" # 过滤注释字段
# 示例输出:Comment : flag{exif_comment_here}
(2)DCT 系数隐写:在压缩数据中藏信息
JPG 压缩过程会将图像分成 8x8 像素块,通过离散余弦变换(DCT)将像素值转换为频率系数,再量化压缩。隐写时可修改非关键频率的 DCT 系数(不影响视觉)存储信息。
工具与案例:
- 用
jsteg提取:jsteg reveal secret.jpg # 提取DCT系数中隐藏的数据 - 案例:某 JPG 图片通过 DCT 系数隐藏
flag.zip,提取后解压得到 flag。
3. GIF 隐写:帧动画与透明色的 “陷阱”
GIF 支持多帧动画和透明色,可通过帧间隙藏数据或透明通道隐写。
(1)多帧信息拼接
原理:GIF 的每一帧可隐藏少量数据,将所有帧的隐藏信息拼接即可还原完整 flag。
实战步骤:
- 用
GIMP(图像编辑工具)打开 GIF→Windows→Animation Playback→查看所有帧。 - 用
convert(ImageMagick 工具)提取所有帧:convert secret.gif frame_%d.png # 将GIF拆分为帧图片 - 检查每帧的像素差异,或用
Stegsolve对比帧数据,拼接隐藏的字符。
(2)透明色通道隐写
GIF 的透明色(指定某颜色为透明)可用来标记特殊区域,隐藏二进制数据。例如,透明像素记为 0,非透明记为 1,组合成字节。
二、音频隐写:从频谱到波形的 “声音密码”
音频隐写主要利用频谱图、波形间隙和ID3 标签,常见格式为 WAV(无损)和 MP3(有损)。
1. 频谱图分析:“看得见” 的声音信息
原理:音频的频谱图(横轴时间,纵轴频率)可直观显示不同频率的声音强度。若在特定频率绘制图案(如文字),人耳难以察觉,但频谱图中清晰可见。
实战步骤:
- 工具:用
Audacity(音频编辑工具)查看频谱图。 - 操作:
打开音频→效果→频谱图→频谱图设置(选择 “对数频率”,调整分辨率)→观察频谱图中是否有文字(如flag{...})。
案例:某 WAV 文件在 10kHz 频率处用短脉冲绘制flag{spectrum_hide},频谱图中可直接读取。
2. LSB 隐写:音频采样点的 “最低位”
与图片 LSB 类似,音频的每个采样点(如 16 位采样,取值范围 - 32768~32767)的最低 1-2 位可存储二进制数据。
工具与命令:
- 用
audacity配合Nyquist插件提取,或steghide(支持音频 / 图片):bash
steghide extract -sf secret.wav # 若有密码,需爆破(用stegcracker) stegcracker secret.wav /usr/share/wordlists/rockyou.txt # 字典爆破密码
3. MP3 ID3 标签:伪装成 “元数据” 的 flag
MP3 的 ID3v1/v2 标签可存储标题、歌手、注释等信息,直接用exiftool或id3v2读取:
id3v2 -l secret.mp3 # 列出ID3标签
# 示例输出:COMM: flag{id3_tag_secret}
三、文档与压缩包隐写:从 PDF 到 ZIP 的 “伪装术”
1. PDF 隐写:隐藏图层与注释
PDF 支持多层内容和注释,可通过隐藏图层(设置图层不可见)或注释字段藏数据。
实战步骤:
- 用
pdfinfo查看 PDF 属性:pdfinfo secret.pdf # 检查是否有异常的页数、大小 - 用
pdftk提取元数据和附件:pdftk secret.pdf dump_data # 查看文档元数据 pdftk secret.pdf unpack_files # 提取嵌入的附件(如flag.txt) - 用
Adobe Acrobat打开 PDF→视图→导航面板→图层,勾选隐藏图层查看内容。
2. ZIP 伪加密:修改标志位的 “障眼法”
原理:ZIP 文件头的全局加密标志位(2 字节)若被恶意修改,会导致解压工具误判为加密(需密码),但实际数据未加密。通过修改标志位可去除 “伪加密”。
实战步骤:
- 用
010 Editor(十六进制编辑器)打开 ZIP 文件,定位文件头:- 本地文件头格式:
50 4B 03 04+ 2 字节版本 + 2 字节加密标志位(00 00 = 未加密,01 00 = 加密)。
- 本地文件头格式:
- 将加密标志位从
01 00改为00 00,保存后即可正常解压。 - 自动化工具:用
zipinfo检查加密状态,fcrackzip爆破真加密(伪加密无需爆破):bash
zipinfo secret.zip # 查看是否加密 fcrackzip -u -D -p /usr/share/wordlists/rockyou.txt secret.zip # 真加密时爆破
四、隐写术通用工具与自动化脚本
1. 必备工具清单
| 工具用途 | 工具名称 | 核心功能 |
|---|---|---|
| 图片隐写提取 | Stegsolve | 可视化提取 LSB、对比通道、分析帧数据 |
| 命令行 LSB 分析 | zsteg | 自动检测 PNG/GIF 的 LSB 隐藏数据 |
| 元数据查看 | exiftool | 读取图片、音频的 EXIF/ID3 元数据 |
| 文件分离 | binwalk/foremost | 从文件中提取嵌入式文件(如图片中的 ZIP) |
| 音频频谱分析 | Audacity | 查看音频频谱图,提取可视化信息 |
| 压缩包处理 | pdftk/zipinfo | 处理 PDF 附件、检测 ZIP 伪加密 |
2. 自动化脚本示例
(1)批量提取图片中的隐藏文件
import os
import binwalk
def extract_hidden_files(input_dir):
for file in os.listdir(input_dir):
if file.endswith(('.png', '.jpg', '.gif')):
print(f"Processing {file}...")
binwalk.scan(
os.path.join(input_dir, file),
extract=True, # 自动提取
quiet=True,
outdir=f"extracted_{file}"
)
extract_hidden_files("./images") # 处理images目录下的图片
(2)LSB 手动提取脚本(PNG)
from PIL import Image
def extract_lsb(image_path):
img = Image.open(image_path)
pixels = img.load()
width, height = img.size
data = []
for y in range(height):
for x in range(width):
r, g, b = pixels[x, y]
# 提取每个通道的最低位(共3位/像素)
data.append(str(r & 1))
data.append(str(g & 1))
data.append(str(b & 1))
# 将二进制数据转为字节(每8位一组)
bits = ''.join(data)
bytes_data = bytes([int(bits[i:i+8], 2) for i in range(0, len(bits), 8)])
return bytes_data
# 提取并保存数据
with open("lsb_extracted.bin", "wb") as f:
f.write(extract_lsb("secret.png"))
五、实战总结:隐写术解题 “黄金流程”
-
初步检查:
用file命令确认文件类型(防止文件后缀欺骗,如.jpg实际是zip):file secret.jpg # 输出:secret.jpg: Zip archive data, at least v2.0 to extract -
元数据与注释:
用exiftool、exifread读取所有元数据,检查是否有异常字段(如Flag、Comment)。 -
文件分离:
用binwalk -e自动提取嵌入式文件(如图片中的 ZIP、PDF 中的 TXT)。 -
载体特性分析:
- 图片:用
Stegsolve/zsteg查 LSB,pngcheck分析块结构。 - 音频:用
Audacity看频谱,steghide提取 LSB。 - 压缩包:检查伪加密(改标志位),爆破真加密密码。
- 图片:用
-
人工验证:
对提取的二进制数据尝试转文本(strings命令)、解密(Base64、XOR),或作为压缩包 / 图片打开。
隐写术的核心是 “逆向思维”—— 站在出题者角度思考 “如何隐藏信息而不被发现”,结合工具逐个排除可能的隐藏位置。随着 CTF 难度提升,隐写术常与加密结合(如隐藏的是加密后的 flag,需先找到密钥),但万变不离其宗:先找到信息,再破解信息。下一篇将聚焦 CTF 脚本编写,带你用代码自动化解决复杂题型。
openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐

所有评论(0)