影评周公子 2026-04-11 22:05 采纳率: 98.8%
浏览 1
已采纳

CTF中ZIP真伪加密如何识别并提取明文密码?

在CTF比赛中,常出现“ZIP真伪加密”陷阱:文件看似启用密码保护(如`encrypted.zip`中文件头`0x01`标志置位、`central directory`显示`general purpose bit flag & 0x01 == 1`),但实际未加密——即**伪加密(Fake Encryption)**。其本质是篡改ZIP结构中某两处关键字段:① Local File Header 的 `general purpose bit flag` 被设为0x01(误导解压工具认为已加密);② Central Directory 中对应条目的同一标志位也被同步篡改,但**所有加密相关字段(如`file data`前无PKCS#5填充、无CRC校验绕过、压缩数据未混淆)均保持明文原始形态**。识别关键点:用`binwalk -e`或`xxd`检查`0x01`标志是否孤立存在;比对Local Header与Central Directory的flag一致性;若`file data`可直接`strings`/`hexdump`读出有效文本或常见密码特征(如`flag{...}`、`admin123`),即为伪加密。提取只需用`zip -F`修复或手动清零flag字节(偏移0x6处第2字节),再用`unzip -p`直取明文内容。
  • 写回答

1条回答 默认 最新

  • 祁圆圆 2026-04-11 22:06
    关注
    ```html

    一、ZIP伪加密现象:从表象到本质的认知跃迁

    在CTF逆向与取证类赛题中,“encrypted.zip”常是首个心理陷阱——文件名暗示强加密,但unzip提示“password required”,而strings encrypted.zip | grep -i flag却直接输出flag{z1p_f4k3_3ncr7pt10n_1s_n0t_r34l}。这揭示了ZIP格式设计中的一个关键安全盲区:**标志位可篡改,但加密逻辑不可绕过**。ZIP规范(APPNOTE-6.3.2)明确指出:general purpose bit flag & 0x01 == 1仅表示“使用传统PKWARE加密”,并不强制执行加密流程。攻击者利用该语义漏洞,仅翻转标志位而不加密数据,形成“视觉加密”。

    二、ZIP结构双源一致性校验:Local Header vs Central Directory

    伪加密的判定核心在于两处标志位的同步篡改与数据真实性的割裂:

    • Local File Header:偏移0x06处2字节general purpose bit flag(小端序),第0比特(LSB)置1 → 值为0x010x09等含bit0=1的组合
    • Central Directory Entry:对应文件条目中偏移0x06同样位置,必须与Local Header完全一致

    若二者一致且均为0x01,但file data起始位置(Local Header后filename length + extra field length字节)紧接原始压缩流(如以0x1f 0x8b开头为gzip,或0x50 0x4b 0x03 0x04后直接明文ZIP子项),即构成伪加密铁证。

    三、技术验证四步法:自动化与手工交叉验证

    步骤命令/操作预期现象(伪加密)
    ① 结构扫描binwalk -e encrypted.zip输出DECIMAL HEXADECIMAL DESCRIPTION0 0x0 Zip archive data,且无加密警告
    ② 十六进制定位xxd encrypted.zip | head -20Local Header首4字节50 4b 03 04后,0000000: 504b 0304 0a00 0000 0000 0000 0000 0000 PK............ → 第6字节(0-indexed)为0x0a(即0b00001010,bit0=0)?若为0x0b0b00001011)则bit0=1
    ③ 数据可读性测试dd if=encrypted.zip bs=1 skip=$(($OFFSET+30)) | strings -n 4 | head -5输出大量ASCII文本、base64片段、或flag{...}等CTF特征字符串
    ④ CRC32比对unzip -lv encrypted.zip | grep -E "(Name|CRC)"显示CRC值;用zlib-flate -uncompress解压对应file data后计算CRC,与Central Directory中记录值一致 → 证明未加密

    四、修复与提取:三种生产级解决方案

    针对已确认伪加密的ZIP,提供工业强度修复路径:

    1. zip -F 自动修复zip -F encrypted.zip --out fixed.zip && unzip -p fixed.zip | strings —— 利用Info-ZIP内置逻辑重写标志位
    2. 十六进制手动清零:用hexedit encrypted.zip定位每个Local Header(50 4b 03 04)后第6字节,将其由0x01/0x09/0x11改为0x00/0x08/0x10(保持其他比特不变),再同理修改Central Directory对应位置
    3. Python脚本化批量处理
      import struct
      with open('encrypted.zip','r+b') as f:
      data = f.read()
      for i in range(len(data)-4):
      if data[i:i+4] == b'\x50\x4b\x03\x04':
      # Local Header flag at offset i+6
      if data[i+6] & 0x01:
      f.seek(i+6)
      f.write(bytes([data[i+6] & 0xfe]))

    五、防御视角:如何构造真加密ZIP规避误判

    作为出题人或红队工程师,需理解真加密ZIP的不可绕过特征:

    • 加密后file data前必有12字节PKCS#5 salt + 2字节checksum(0x0000起始)
    • CRC32字段在Central Directory中被置为0x00000000(因加密后无法预计算)
    • 使用7z a -p123456 encrypted.7z payload.txt生成的7z包不具此陷阱,但ZIP标准加密(-P)需zip -P pass file.txt且依赖OpenSSL兼容实现

    六、深度溯源:ZIP规范与工具链信任边界分析

    为何unzip不校验加密真实性?因POSIX unzip实现遵循“最小假设原则”:仅解析标志位即触发密码交互,将解密责任移交用户。而binwalk的熵值分析(-E)可暴露伪加密——真实加密数据熵值≈7.99,而伪加密ZIP中压缩数据熵值仅≈6.2(LZ77冗余残留)。下图展示CTF典型ZIP解析决策流:

    graph TD A[输入ZIP文件] --> B{是否含0x504b0304} B -->|否| C[非ZIP格式] B -->|是| D[定位Local Header] D --> E[读取offset 0x06 flag] E --> F{flag & 0x01 == 1?} F -->|否| G[尝试直接解压] F -->|是| H[启动密码交互] H --> I{用户输入密码} I --> J[调用PKWARE解密引擎] J --> K{解密后CRC校验通过?} K -->|是| L[输出明文] K -->|否| M[报错“invalid password”] M --> N[但实际无需密码:伪加密]
    ```
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已采纳回答 4月12日
  • 创建了问题 4月11日