三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

DES加密与ZLIB压缩流量分析实战

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)典型应用场景
GZIP0x1F 0x8BHTTP传输压缩
ZLIB0x78 0x9CPDF/PNG文件
LZ40x04 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

典型处理流程应为:

  1. HEX解码获取二进制数据
  2. 识别并剥离可能的头部(如HTTP头)
  3. 尝试不同解压算法
  4. 对解压结果进行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 -c

Python解压方案(需安装lz4包):

import lz4.frame with lz4.frame.open('compressed.lz4', mode='r') as f: print(f.read())

5. 完整解题路径还原

5.1 分步操作记录

  1. 从pcap提取TCP负载:

    editcap -C 12:34 input.pcap stripped.pcap # 去除以太网头 tshark -r stripped.pcap -T fields -e data > hex_data.txt
  2. 转换HEX到二进制:

    import binascii with open('hex_data.txt') as f: open('raw.bin', 'wb').write(binascii.unhexlify(f.read().strip()))
  3. 识别出ZLIB压缩数据:

    file raw.bin # 显示"zlib compressed data"
  4. 解压后得到DES密文:

    import zlib open('decrypted.des', 'wb').write(zlib.decompress(open('raw.bin','rb').read()))
  5. 通过已知弱密钥解密:

    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 data

6.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 endmodule

7. 防御视角的思考

从蓝队角度,这类题目反映出几个安全实践要点:

  1. 深度包检测(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; )
  2. 加密流量分析技巧

    • 检测DES等弱加密的使用
    • 监控异常大小的TCP段(压缩数据通常有固定块大小)
  3. 日志记录建议

    • 记录所有Content-Encoding头
    • 对解压失败请求生成告警

在实际业务系统中,应该避免:

  • 使用DES等过时加密算法
  • 将压缩和加密顺序设计为可逆(应先压缩后加密)
  • 传输未校验的压缩数据
← 返回列表