Detects and extracts hidden data from images, audio, and media files using steganalysis tools like binwalk, zsteg, steghide, ExifTool, and Python scripts. Use for digital forensics when suspecting covert channels.
npx claudepluginhub killvxk/cybersecurity-skills-zhThis skill uses the workspace's default tool permissions.
- 当怀疑图像、音频或视频文件中存在隐蔽数据隐藏时
Detects and extracts hidden data from images, audio, and media using steganalysis tools like zsteg, steghide, binwalk, ExifTool for digital forensics investigations.
Detects and extracts hidden data in images, audio, and media files using steganalysis tools like zsteg, steghide, binwalk, ExifTool for digital forensics.
Explores and reverse engineers binary files and firmware using strings, binwalk, hexdump, xxd, objdump, readelf, and nm to extract text, analyze entropy, and identify structures.
Share bugs, ideas, or general feedback.
# 安装隐写检测工具
sudo apt-get install steghide stegsnow
pip install zsteg
pip install stegoveritas
gem install zsteg # 基于 Ruby 的 PNG/BMP 工具
# 检查文件元数据是否存在异常
exiftool /cases/case-2024-001/media/suspect_image.jpg | tee /cases/case-2024-001/analysis/metadata.txt
# 检查异常文件大小(是否大于分辨率/格式预期)
identify -verbose /cases/case-2024-001/media/suspect_image.jpg | head -30
# 验证文件类型是否与扩展名匹配
file /cases/case-2024-001/media/suspect_image.jpg
# 确认 JPEG 签名与实际内容匹配
# 检查文件尾部后附加的数据
python3 << 'PYEOF'
import os
filepath = '/cases/case-2024-001/media/suspect_image.jpg'
filesize = os.path.getsize(filepath)
with open(filepath, 'rb') as f:
data = f.read()
# JPEG 文件以 FF D9 结尾
jpeg_end = data.rfind(b'\xff\xd9')
if jpeg_end > 0:
trailing_bytes = filesize - jpeg_end - 2
if trailing_bytes > 0:
print(f"警告:JPEG 结束标记后有 {trailing_bytes} 字节数据!")
print(f" 文件大小:{filesize} 字节")
print(f" JPEG 数据:{jpeg_end + 2} 字节")
print(f" 隐藏数据:{trailing_bytes} 字节")
# 提取尾部数据
with open('/cases/case-2024-001/analysis/trailing_data.bin', 'wb') as out:
out.write(data[jpeg_end + 2:])
else:
print("JPEG 结束标记后未检测到尾部数据")
# 检查嵌入的 ZIP/RAR 压缩包
zip_offset = data.find(b'PK\x03\x04')
rar_offset = data.find(b'Rar!\x1a\x07')
if zip_offset > 0:
print(f"在偏移量 {zip_offset} 处发现 ZIP 压缩包")
if rar_offset > 0:
print(f"在偏移量 {rar_offset} 处发现 RAR 压缩包")
PYEOF
# 使用 binwalk 检测嵌入文件和数据
binwalk /cases/case-2024-001/media/suspect_image.jpg | tee /cases/case-2024-001/analysis/binwalk_scan.txt
# 提取嵌入文件
binwalk --extract --directory /cases/case-2024-001/analysis/binwalk_extracted/ \
/cases/case-2024-001/media/suspect_image.jpg
# 使用 zsteg 进行 PNG 和 BMP 分析(LSB 检测)
zsteg /cases/case-2024-001/media/suspect_image.png | tee /cases/case-2024-001/analysis/zsteg_results.txt
# zsteg 全面检查
zsteg -a /cases/case-2024-001/media/suspect_image.png
# 使用 stegoveritas 进行综合分析
stegoveritas /cases/case-2024-001/media/suspect_image.jpg \
-out /cases/case-2024-001/analysis/stegoveritas/
# stegoveritas 执行:
# - 元数据提取
# - LSB 分析(多个位平面)
# - 颜色映射分析
# - 尾部数据检测
# - 嵌入文件提取
# - 图像变换分析
# 使用 steghide 对 JPEG/BMP/WAV/AU 进行提取尝试
# 使用空密码尝试
steghide extract -sf /cases/case-2024-001/media/suspect_image.jpg -p "" \
-xf /cases/case-2024-001/analysis/steghide_extract.bin 2>&1
# 使用常见密码尝试
for pwd in password secret hidden stego test 123456 admin; do
result=$(steghide extract -sf /cases/case-2024-001/media/suspect_image.jpg \
-p "$pwd" -xf "/cases/case-2024-001/analysis/steghide_$pwd.bin" 2>&1)
if echo "$result" | grep -q "extracted"; then
echo "使用密码成功提取:$pwd"
fi
done
# 使用 Python 进行自定义 LSB 分析
python3 << 'PYEOF'
from PIL import Image
import numpy as np
img = Image.open('/cases/case-2024-001/media/suspect_image.png')
pixels = np.array(img)
# 从每个颜色通道提取 LSB
for channel, name in enumerate(['红色', '绿色', '蓝色']):
if channel >= pixels.shape[2]:
break
lsb_data = pixels[:, :, channel] & 1
# 统计分布(自然图像应约为 50/50)
zeros = np.sum(lsb_data == 0)
ones = np.sum(lsb_data == 1)
total = zeros + ones
ratio = ones / total
print(f"{name}通道 LSB:0={zeros}({zeros/total*100:.1f}%),1={ones}({ones/total*100:.1f}%)")
if abs(ratio - 0.5) < 0.01:
print(f" 中性——接近随机(可能是隐写或自然图像)")
elif ratio > 0.55 or ratio < 0.45:
print(f" 异常——与预期分布存在显著偏差")
# 将 LSB 数据提取为字节
lsb_bits = (pixels[:, :, 0] & 1).flatten()
lsb_bytes = np.packbits(lsb_bits)
# 检查提取数据是否有结构
with open('/cases/case-2024-001/analysis/lsb_extracted.bin', 'wb') as f:
f.write(lsb_bytes.tobytes())
# 在提取数据中检查已知文件签名
import struct
header = bytes(lsb_bytes[:16])
print(f"\nLSB 提取头部(十六进制):{header.hex()}")
if header[:4] == b'PK\x03\x04':
print(" 检测到:LSB 数据中存在 ZIP 压缩包!")
elif header[:3] == b'GIF':
print(" 检测到:LSB 数据中存在 GIF 图像!")
elif header[:4] == b'\x89PNG':
print(" 检测到:LSB 数据中存在 PNG 图像!")
elif header[:2] == b'\xff\xd8':
print(" 检测到:LSB 数据中存在 JPEG 图像!")
# 生成 LSB 可视化
lsb_img = Image.fromarray((lsb_data * 255).astype(np.uint8))
lsb_img.save('/cases/case-2024-001/analysis/lsb_visualization.png')
print("\nLSB 可视化已保存至 lsb_visualization.png")
PYEOF
# 对音频文件进行频谱分析
python3 << 'PYEOF'
import wave
import numpy as np
# 分析 WAV 文件中的音频隐写
with wave.open('/cases/case-2024-001/media/suspect_audio.wav', 'r') as wav:
frames = wav.readframes(wav.getnframes())
samples = np.frombuffer(frames, dtype=np.int16)
# 音频样本的 LSB 分析
lsb = samples & 1
zeros = np.sum(lsb == 0)
ones = np.sum(lsb == 1)
total = len(lsb)
print(f"音频 LSB 分析:")
print(f" 样本数:{total}")
print(f" LSB 0:{zeros}({zeros/total*100:.1f}%)")
print(f" LSB 1:{ones}({ones/total*100:.1f}%)")
# 提取 LSB 数据
lsb_bytes = np.packbits(lsb)
with open('/cases/case-2024-001/analysis/audio_lsb.bin', 'wb') as f:
f.write(lsb_bytes.tobytes())
# 卡方检验(Chi-square Test)检验随机性
from scipy import stats
chi2, p_value = stats.chisquare([zeros, ones])
print(f" 卡方:{chi2:.4f},p 值:{p_value:.4f}")
if p_value < 0.05:
print(f" 异常:LSB 分布不随机(可能存在隐写)")
PYEOF
# 对音频文件使用 steghide
steghide info /cases/case-2024-001/media/suspect_audio.wav
# 使用 sonic-visualiser 或 audacity 分析频谱异常
# (检查频谱图是否有在频域中编码的隐藏图像)
# 汇编发现
python3 << 'PYEOF'
import os, json
report = {
"case": "2024-001",
"files_analyzed": [],
"findings": []
}
analysis_dir = '/cases/case-2024-001/analysis/'
for f in os.listdir(analysis_dir):
if f.endswith('.txt'):
with open(os.path.join(analysis_dir, f)) as fh:
content = fh.read()
if 'DETECTED' in content or 'SUCCESS' in content or 'WARNING' in content:
report["findings"].append({
"source": f,
"content": content[:500]
})
with open('/cases/case-2024-001/analysis/steg_report.json', 'w') as f:
json.dump(report, f, indent=2)
print("隐写分析报告已生成")
print(f"发现总数:{len(report['findings'])}")
PYEOF
| 概念 | 定义 |
|---|---|
| LSB(最低有效位,Least Significant Bit) | 将数据嵌入像素或样本值的最低位 |
| DCT 隐写 | 在 JPEG 离散余弦变换(DCT)系数中隐藏数据 |
| 扩频(Spread Spectrum) | 将隐藏数据分布在整个载体信号中 |
| 隐写分析(Steganalysis) | 检测隐藏信息存在性的科学 |
| 卡方攻击(Chi-square Attack) | 检测非随机 LSB 分布的统计测试 |
| 载体媒介(Cover Medium) | 用于携带隐藏数据的原始文件(图像、音频、视频) |
| 隐写媒介(Stego Medium) | 嵌入隐藏数据后生成的文件 |
| 容量(Capacity) | 可以在不产生可见失真的情况下隐藏的最大数据量 |
| 工具 | 用途 |
|---|---|
| steghide | 在 JPEG、BMP、WAV、AU 文件中嵌入/提取数据 |
| zsteg | 检测 PNG 和 BMP 文件中的 LSB 隐写 |
| binwalk | 检测二进制文件中的嵌入文件和数据 |
| stegoveritas | 综合隐写分析工具,支持多种检测方法 |
| StegSolve | 用于图像位平面和滤镜分析的 Java GUI 工具 |
| OpenStego | 开源隐写和水印工具 |
| ExifTool | 媒体文件的元数据提取和分析 |
| stegseek | 快速 steghide 密码破解工具,用于 JPEG 隐写提取 |
场景 1:隐蔽通信调查 检查嫌疑人通过即时通讯平台交换的图像,对所有 PNG/BMP 文件运行 stegoveritas 和 zsteg,对 JPEG 文件尝试使用已知密码进行 steghide 提取,分析 LSB 分布的统计异常,提取并解码任何隐藏消息。
场景 2:通过图像上传进行数据外泄 监控上传到云服务的图像是否存在异常文件大小,比较图像元数据与预期的相机/设备配置文件,运行 binwalk 检测嵌入的压缩包,分析 JPEG 量化表中的 steghide 签名,提取并检查任何隐藏载荷。
场景 3:恶意软件命令与控制 分析恶意软件下载的图像是否包含嵌入命令,检查文件结束标记后附加的数据,检查 DNS 查询响应中 TXT 记录里的 Base64 编码数据,分析 PNG IDAT 块中异常的压缩数据大小。
场景 4:通过音频文件窃取知识产权 分析音频文件 LSB 中是否嵌入文档,检查频谱图是否有在频域中隐藏的视觉模式,将音频文件大小与比特率和时长的预期大小进行比较,提取并分析任何隐藏数据载荷。
隐写分析摘要:
已分析文件:45 个(32 个图像,8 个音频,5 个视频)
检测结果:
suspect_image_03.png:
zsteg:在 R 通道 LSB 中检测到文本
内容:"Meet at location B, Tuesday 1400"
方法:红色通道 LSB 嵌入
suspect_photo_17.jpg:
steghide:使用密码"secret123"提取数据
隐藏文件:confidential_report.pdf(234 KB)
方法:DCT 系数修改
profile_pic.png:
binwalk:在偏移量 45678 处嵌入 ZIP 压缩包
内容:3 个含财务数据的电子表格文件
方法:在 PNG IEND 标记后附加数据
recording_05.wav:
LSB 分析:非随机分布(p < 0.001)
提取:12 KB 二进制载荷(需进一步分析)
方法:音频 LSB 嵌入
干净文件:41 个(无隐写指标)
可疑文件:4 个(已提取数据)
报告:/cases/case-2024-001/analysis/steg_report.json