在CTF比赛中,MISC类题目中的压缩包题型是常见且多样化的。以下是详细的解题思路、工具推荐及例题分析:
一、常见压缩包题型及解题思路
1. 伪加密(ZIP/RAR)
· 原理:ZIP文件通过加密标记位(例如全局加密标记 0x09)伪装成加密文件,实际未加密。
· 识别:
· ZIP:使用 zipdetails 或 010 Editor 查看加密标记位(General Purpose Bit Flag)。
· RAR:伪加密较少见,需检查文件头中的加密标记。
· 修复方法:
· 修改ZIP的全局加密标记位为 0x00(例如将 0x09 改为 0x00)。
· 工具:binwalk -e 或手动用 010 Editor 修改。
2. 暴力破解/字典攻击
· 适用场景:已知密码为弱口令(如纯数字、短字符)。
· 工具:
· John the Ripper(跨平台,支持多格式)
· ARCHPR(Windows图形化工具,支持掩码攻击)
· fcrackzip(Linux专用,命令行工具)
· 优化技巧:
· 使用掩码攻击(如已知密码前几位)。
· 结合社会工程学生成字典(如题目相关词汇)。
3. CRC32碰撞
· 原理:已知文件内容的CRC32校验值,可通过穷举生成符合校验值的小文件(如文本、小图片)。
· 工具:
· Python脚本(利用 zlib.crc32 库碰撞)
· crc32-collision(自动化生成碰撞文件)
· 限制:仅适用于未加密的小文件(通常≤10KB)。
4. 明文攻击(Known Plaintext Attack)
· 条件:已知压缩包中某个未加密文件的内容。
· 工具:
· pkcrack(经典工具,支持ZIP)
· bkcrack(更高效,支持ZIP和部分加密算法)
· 步骤:
1. 提取已知文件的明文内容。
2. 生成明文对应的加密文件。
3. 使用工具推导加密密钥,解密目标文件。
5. 隐藏文件/附加数据
· 常见手法:
· 压缩包内嵌套压缩包(递归解压)。
· 利用文件分离工具提取隐藏文件(如binwalk、foremost)。
· 文件末尾附加额外数据(如Base64、Hex编码的字符串)。
· 工具:
· binwalk -e 自动分离文件。
· dd 命令手动切割文件。
6. 文件头修复
· 场景:压缩包文件头被破坏(如缺失、篡改)。
· 修复方法:
· 对比正常文件头修复(如ZIP文件头为 50 4B 03 04)。
· 工具:010 Editor 手动修复。
7. 注释/属性隐藏信息
· 检查位置:
· ZIP文件注释(zipinfo -z 查看)。
· 文件属性中的NTFS流(Windows下用 notepad file.txt:streamname 查看)。
二、工具清单
工具名称用途平台
010 Editor十六进制编辑/修复文件头跨平台
binwalk文件分离/隐藏数据提取Linux
pkcrack/bkcrack明文攻击跨平台
John the Ripper密码暴力破解跨平台
ARCHPR图形化密码爆破(ZIP/RAR)Windows
fcrackzipZIP密码爆破Linux
zipdetails分析ZIP结构Linux
foremost文件分离Linux
三、例题详解
例题1:ZIP伪加密
· 题目:解压时提示需要密码,但实际未加密。
· 步骤:
1. 用 zipdetails flag.zip 查看加密标记:
General Purpose Bit Flag: 0x09 (表示加密)
2. 用 010 Editor 打开ZIP文件,找到加密标记位(如 0x09),修改为 0x00。
3. 直接解压获取flag。
例题2:CRC32碰撞
· 题目:压缩包内有一个4字节的txt文件,已知CRC32值为 DEADBEEF。
· 步骤:
1. 编写Python脚本穷举所有4字节组合:
import zlib
target_crc = 0xDEADBEEF
for i in range(0x1000000):
data = i.to_bytes(4, 'big')
if zlib.crc32(data) == target_crc:
print(data.decode())
break
2. 运行脚本得到明文,输出flag。
例题3:明文攻击
· 题目:压缩包 secret.zip 中包含加密文件 flag.txt 和已知明文文件 readme.txt。
· 步骤:
1. 提取明文文件 readme.txt 的内容。
2. 使用 bkcrack 生成密钥:
bkcrack -C secret.zip -c readme.txt -p readme.txt
3. 用密钥解密目标文件:
bkcrack -C secret.zip -c flag.txt -k
四、常见套娃题型
1. 文件名密码
· 特征:压缩包密码藏在文件名中(如文件名是Base64、Hex、MD5等编码)。
· 示例:
· 文件名:flag_636F6D656F6E.zip → Hex解码为 comeon。
· 文件名:flag_YmFzZTY0.zip → Base64解码为 base64。
2. 数字递增密码
· 特征:密码为连续数字(如0000, 0001, ..., 9999)。
· 示例:压缩包名flag_0001.zip,密码可能是0001,下一层压缩包名flag_0002.zip,密码0002,依此类推。
3. CRC32碰撞套娃
· 特征:每个压缩包内的小文件CRC32值已知,需碰撞出内容作为下一层密码。
· 示例:file1.zip内文件CRC32为DEADBEEF,碰撞出内容1234,作为file2.zip的密码。
4. 伪加密嵌套
· 特征:多层伪加密压缩包,需逐层修复加密标记位。
5. 隐藏文件+流量分析
· 特征:压缩包隐藏在流量文件(如pcap)中,需先提取再处理。
自动化脚本示例
场景1:文件名是Hex/Base64密码
import zipfile
import base64
def decode_filename(filename):
# 示例:文件名是Hex编码的密码
if '_' in filename:
hex_part = filename.split('_')[1].split('.')[0]
return bytes.fromhex(hex_part).decode()
# 或Base64编码
# return base64.b64decode(hex_part).decode()
return None
current_zip = 'flag_636F6D656F6E.zip' # 初始文件名
while True:
password = decode_filename(current_zip)
with zipfile.ZipFile(current_zip, 'r') as zf:
zf.extractall(pwd=password.encode())
next_file = zf.namelist()[0] # 假设只有一个文件
current_zip = next_file
if not current_zip.endswith('.zip'):
break
print("Flag:", open(current_zip).read())
场景2:数字递增密码爆破
import zipfile
current_zip = 'flag.zip'
for i in range(10000):
password = f"{i:04d}" # 生成0000~9999
try:
with zipfile.ZipFile(current_zip, 'r') as zf:
zf.extractall(pwd=password.encode())
print(f"Password found: {password}")
current_zip = zf.namelist()[0] # 进入下一层
if not current_zip.endswith('.zip'):
break
except (RuntimeError, zipfile.BadZipFile):
continue
print("Final file:", current_zip)
场景3:CRC32碰撞生成密码
import zipfile
import zlib
import itertools
def crc32_collision(target_crc, length=4):
chars = b'0123456789abcdef' # 假设密码是十六进制字符
for combo in itertools.product(chars, repeat=length):
data = bytes(combo)
if zlib.crc32(data) == target_crc:
return data.decode()
return None
current_zip = 'file1.zip'
while True:
with zipfile.ZipFile(current_zip, 'r') as zf:
crc = zf.filelist[0].CRC # 获取第一个文件的CRC32
password = crc32_collision(crc)
zf.extractall(pwd=password.encode())
current_zip = zf.namelist()[0]
if not current_zip.endswith('.zip'):
break
print("Flag:", open(current_zip).read())
场景4:自动修复ZIP伪加密
import os
def fix_fake_encryption(filename):
with open(filename, 'rb') as f:
data = bytearray(f.read())
# ZIP伪加密标记位:0x09 -> 0x00
if data[6] == 0x09:
data[6] = 0x00
with open(filename, 'wb') as f:
f.write(data)
print(f"Fixed fake encryption for {filename}")
current_zip = 'fake_encrypted.zip'
while True:
fix_fake_encryption(current_zip)
with zipfile.ZipFile(current_zip, 'r') as zf:
zf.extractall()
next_file = zf.namelist()[0]
os.remove(current_zip) # 清理当前层
current_zip = next_file
if not current_zip.endswith('.zip'):
break
print("Flag:", open(current_zip).read())
实战技巧
1. 文件类型识别:
· 使用 file 命令或 binwalk 检查文件真实类型。
· 隐藏文件可能被重命名为无后缀文件,尝试添加.zip后缀。
2. 流量分析提取压缩包:
· 用 Wireshark 过滤HTTP流量,导出压缩包:
tshark -r traffic.pcapng --export-objects http,output_dir
3. 文件名编码提示:
· 文件名中的=可能是Base64填充符,如flag_Y2F0Y2g=.zip → catch。
4. 超深嵌套处理:
· 递归解压脚本需设置最大层数(如100层),防止无限循环。
五、总结
压缩包题目的核心是分析文件结构和利用已知信息推导未知数据。解题时需注意:
1. 优先检查伪加密、注释、文件属性等简单点。
2. 合理选择攻击方式(如小文件用CRC碰撞,大文件用明文攻击)。
3. 熟练使用工具链(如 binwalk + 010 Editor + bkcrack)
原文始发于微信公众号(小话安全):CTF:杂项类型压缩包题目常见题目类型及解题思路
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论