CVE-2023-39137:压缩包文件名欺骗漏洞技术分析
漏洞概述
CVE-2023-39137 是一个存在于 Archive 包(用于 Flutter/Dart 的压缩文件处理库)v3.3.7 及更早版本中的安全漏洞。该漏洞被评定为 高危 级别,CVSS 3.1 基础评分为 7.8。
该漏洞的核心是 ZIP文件名欺骗。攻击者可以精心构造一个恶意ZIP文件,使其在局部文件头和中央目录条目中存储不同的文件名。由于Archive包在解析时仅从局部文件头读取文件名,而大多数其他ZIP解析器(如系统工具zipinfo)则优先使用中央目录条目中的文件名,这种不一致性可被利用,导致文件在提取前后的“身份”发生改变。
技术细节:ZIP文件结构与漏洞原理
ZIP文件基本结构
一个标准的ZIP文件主要包含三部分:
- 局部文件头:位于每个被压缩文件的数据之前,包含该文件的即时信息,如文件名、压缩方法、CRC校验和等。
- 中央目录:位于ZIP文件的末尾附近,作为整个存档的“索引”,其中每个“中央目录文件头”也包含文件名、大小等信息。
- 中央目录结束记录:标记中央目录的结束。
漏洞成因
在正常情况下,同一文件在局部文件头和中央目录条目中的文件名应该一致。然而,ZIP文件格式规范并未强制要求两者必须相同。
Archive包(v3.3.7)的 ZipFileHeader 构造函数在解析文件头时,仅从输入流中读取了中央目录条目中的文件名(对应于代码中的filename字段),但在实际提取文件时,其内部逻辑可能依赖于其他部分或未正确处理这种不一致性,导致了文件名解析的歧义。
关键代码片段(展示解析逻辑):
|
|
漏洞利用与影响
攻击场景(Proof of Concept)
攻击者可以制作一个ZIP文件,其中某个条目的局部文件头中的文件名为evil.apk,而中央目录中记录的文件名却是evil.txt。
- 当使用系统命令
zipinfo查看此ZIP包时,显示的文件名为evil.txt(取自中央目录)。 - 当使用存在漏洞的Archive包(
extractFileToDisk函数)解压此ZIP包时,提取出的文件名称却是evil.apk。
这可能导致多种危害:
- 绕过安全检查:安全扫描工具或用户肉眼检查
zipinfo输出时看到的是无害的.txt文件,但实际释放出的却是恶意的.apk可执行文件。 - 钓鱼攻击:将可执行文件伪装成文档、图片等。
- 引发后续攻击:与路径遍历等漏洞结合,扩大影响。
概念验证代码(Python)
以下Python脚本演示了如何构造一个文件名不一致的ZIP文件:
|
|
关联漏洞与同类威胁
该漏洞并非孤立现象,它是ZIP文件名欺骗这一类安全问题的具体实例。早在2009年,类似漏洞(如影响WinRAR的漏洞)已被公开披露并用于实际攻击。
同一安全研究(Ostorlab)在审计中还发现了Archive包中与之相关的另一个高危漏洞:CVE-2023-39139(ZIP符号链接路径遍历)。该漏洞允许ZIP包中的符号链接指向提取目录之外的目标文件,结合文件名欺骗,可构成更复杂的攻击链。
修复方案与缓解措施
- 官方修复:Archive包在 v3.3.8 版本中已修复此漏洞。用户应立即升级到该版本或更高版本。
- 修复逻辑:修复方案的核心是确保文件名解析的一致性。补丁可能强制要求在解压时,验证或统一使用单一可信来源(如中央目录)的文件名,并忽略或拒绝局部文件头中不一致的命名。
- 最佳实践:
- 在解压ZIP文件前,使用可信的库进行完整性检查和结构验证。
- 对解压出的文件实施严格的命名白名单策略,特别是对可执行文件。
- 在安全敏感的环境中使用解压功能时,将文件提取到隔离的沙箱环境中。
总结
CVE-2023-39137揭示了文件格式解析器中一个看似细微却危害巨大的逻辑缺陷——对同一数据实体的多源信息缺乏一致性校验。对于处理复杂、历史悠久的文件格式(如ZIP)的库,开发人员必须深入理解其规范的所有细节和潜在歧义,并采取防御性编程策略。用户则应及时关注依赖库的安全更新,避免将自身暴露于已知风险之中。