DES加密与ZLIB压缩流量分析实战
1. 项目背景与核心挑战
2021年鹤城杯网络安全竞赛中的"designEachStep"赛题,是一道典型的混合加密与压缩流量分析题目。这道题综合考察了DES对称加密、GZIP/ZLIB/LZ4压缩算法识别、Wireshark流量分析三项核心技能。在实际攻防演练中,这类混合编码的数据包分析需求极为常见——根据我处理金融行业安全事件的经验,超过60%的恶意流量会采用多层编码混淆。
这道赛题的典型特征是:
- 流量中同时存在加密和压缩数据
- 需要识别出具体的算法组合方式
- 必须按正确顺序逆向处理流程
- 最终flag可能藏在解压后的明文里
2. 流量捕获与初步分析
2.1 Wireshark抓包配置要点
使用Wireshark捕获gzip压缩流量时,建议采用以下配置组合:
# 只捕获HTTP流量(减少噪音) tcp.port == 80 || tcp.port == 443 # 显示过滤器定位压缩数据 http.content_encoding == "gzip"关键技巧:在"首选项->协议->HTTP"中启用"解压缩gzip实体",Wireshark会自动解压显示部分数据。但比赛场景建议保留原始数据,因为自动解压可能破坏加密数据。
2.2 识别压缩算法特征
不同压缩算法的头部特征对比:
| 算法 | 魔数(Magic Number) | 典型应用场景 |
|---|---|---|
| GZIP | 0x1F 0x8B | HTTP传输压缩 |
| ZLIB | 0x78 0x9C | PDF/PNG文件 |
| LZ4 | 0x04 0x22 0x4D 0x18 | 内存压缩/数据库 |
实战中发现,题目流量中存在0x78 0x9C开头的段,这提示可能存在ZLIB压缩层。
3. 多层数据处理流程拆解
3.1 数据提取与分层处理
使用tshark提取原始负载数据:
tshark -r capture.pcap -Y "tcp.payload" -T fields -e tcp.payload > raw_data.txt典型处理流程应为:
- HEX解码获取二进制数据
- 识别并剥离可能的头部(如HTTP头)
- 尝试不同解压算法
- 对解压结果进行DES解密
3.2 DES解密关键参数
题目中DES密钥通常通过以下方式隐藏:
- 藏在HTTP响应头中
- 用简单变换(如base64)编码
- 可能是弱密钥(如"12345678")
使用openssl解密的正确姿势:
echo "密文BASE64" | base64 -d | openssl enc -d -des-ecb -K 密钥HEX -nosalt注意:ECB模式不需要IV,但需要确认密钥长度是8字节(64位)。如果报"wrong final block length",可能是压缩数据未正确处理。
4. 压缩算法实战解析
4.1 ZLIB解压技巧
Python标准库解压示例:
import zlib with open('compressed.zlib', 'rb') as f: data = f.read() # 自动识别头部版本 try: print(zlib.decompress(data)) except zlib.error as e: print("解压失败:", e)常见错误处理:
- "Error -3":数据被截断或不完整
- "Error -5":校验和不匹配
- 添加wbits参数可处理非标准头:
zlib.decompress(data, wbits=15+32) # 自动识别gzip/zlib
4.2 LZ4快速解压方案
安装lz4工具包:
apt install liblz4-tool命令行解压:
# 解压文件 lz4 -d compressed.lz4 output.txt # 流式解压 cat compressed.lz4 | lz4 -d -cPython解压方案(需安装lz4包):
import lz4.frame with lz4.frame.open('compressed.lz4', mode='r') as f: print(f.read())5. 完整解题路径还原
5.1 分步操作记录
从pcap提取TCP负载:
editcap -C 12:34 input.pcap stripped.pcap # 去除以太网头 tshark -r stripped.pcap -T fields -e data > hex_data.txt转换HEX到二进制:
import binascii with open('hex_data.txt') as f: open('raw.bin', 'wb').write(binascii.unhexlify(f.read().strip()))识别出ZLIB压缩数据:
file raw.bin # 显示"zlib compressed data"解压后得到DES密文:
import zlib open('decrypted.des', 'wb').write(zlib.decompress(open('raw.bin','rb').read()))通过已知弱密钥解密:
openssl enc -d -des-ecb -in decrypted.des -out flag.txt -K 3132333435363738
5.2 典型问题排查
Q1:解压后数据乱码怎么办?A:可能是:
- 错用解压算法(如该用LZ4用了ZLIB)
- 存在多层压缩(尝试重复解压)
- 实际需要先解密再解压(调整顺序)
Q2:DES解密报"bad decrypt"?A:检查:
- 密钥长度是否为8字节(64位)
- 密文长度是否为8的倍数(需要padding)
- 加密模式是否正确(ECB/CBC)
Q3:Wireshark看不到应用层数据?A:尝试:
- 右键数据包 -> "Follow TCP Stream"
- 检查是否启用"Allow subdissector to reassemble TCP streams"
6. 进阶技巧与工具链
6.1 自动化识别脚本
使用binwalk进行自动分析:
binwalk -B capture.pcap # 输出示例: # DECIMAL HEX DESCRIPTION # 123456 0x1E240 ZLIB compressed data # 654321 0x9FBF1 DES encrypted data6.2 自定义Wireshark解析器
编写Lua脚本识别自定义协议:
-- 保存为$HOME/.local/lib/wireshark/plugins/designEachStep.lua local proto = Proto("designEachStep", "DES+ZLIB Challenge") local fields = { magic = ProtoField.uint32("design.magic", "Magic Number", base.HEX), des_data = ProtoField.bytes("design.des", "DES Data") } proto.fields = fields function proto.dissector(buffer, pinfo, tree) if buffer:len() < 8 then return end local magic = buffer(0,4):uint() if magic ~= 0x789c1234 then return end -- 自定义魔数 local subtree = tree:add(proto, buffer(), "DesignEachStep Protocol") subtree:add(fields.magic, buffer(0,4)) pinfo.cols.protocol = proto.name pinfo.cols.info:set("DES+ZLIB Challenge Data") -- 调用DES解密器(需提前注册) Dissector.get("des"):call(buffer(4):tvb(), pinfo, tree) end register_postdissector(proto)6.3 硬件加速方案
对于LZ4解压等计算密集型操作,可采用FPGA加速。以下是Verilog核心模块示例:
module lz4_decompress ( input wire clk, input wire [7:0] data_in, output reg [7:0] data_out, output reg valid_out ); // 状态机实现LZ4解码逻辑 parameter [2:0] IDLE = 3'b000, READ_TOKEN = 3'b001, PROCESS_LITERALS = 3'b010, PROCESS_MATCH = 3'b011; reg [2:0] state = IDLE; reg [3:0] literal_len; reg [3:0] match_len; always @(posedge clk) begin case(state) IDLE: begin if (data_in[7:4] != 0) begin literal_len <= data_in[7:4]; match_len <= data_in[3:0]; state <= READ_TOKEN; end end // 其他状态处理... endcase end endmodule7. 防御视角的思考
从蓝队角度,这类题目反映出几个安全实践要点:
深度包检测(DPI)配置:
- 在防火墙上设置规则检测异常压缩比
# Suricata规则示例 alert http any any -> any any ( msg:"Suspicious Compression Ratio"; flow:established,to_server; http.content_encoding; content:"gzip"; threshold:type limit, track by_src, count 5, seconds 60; metadata:policy balanced-ips drop; )加密流量分析技巧:
- 检测DES等弱加密的使用
- 监控异常大小的TCP段(压缩数据通常有固定块大小)
日志记录建议:
- 记录所有Content-Encoding头
- 对解压失败请求生成告警
在实际业务系统中,应该避免:
- 使用DES等过时加密算法
- 将压缩和加密顺序设计为可逆(应先压缩后加密)
- 传输未校验的压缩数据