abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · proftpd-rewrite-utf8trans
技术分析文章:https://abraxaslabs.tech/research/proftpd-rewrite-utf8trans
类别: 崩溃 可达性: 远程
ProFTPD 1.3.9d(f59f248)- ProFTPD (proftpd.org)
contrib 模块 mod_rewrite 提供了 RewriteMap int:utf8trans。该内置映射会将客户端 FTP 参数(最大为 CommandBufferSize,即 512 KiB)复制到两个 1024 槽位的 BSS 缓冲区中,且没有目标容量上限。一个较长的 ASCII STOR 文件名会触发 ASan 的 global-buffer-overflow,即大小为 8 的 WRITE。会话子进程中止。守护进程保持运行。类别为崩溃。并非 RCE。
| ID | 暂无 CVE |
| 类别 | 崩溃 |
| 可达性 | 远程(FTP 参数被送入 int:utf8trans) |
| CWE | CWE-120 |
| CVSS | 高危:7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H(前提是 RewriteRule 为预认证)。实验环境使用的是登录后的 STOR,因此该次运行如实采用 PR:L(AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H)。 |
| 产品 | ProFTPD |
| 受影响版本 | 1.3.9d(f59f248e26bdfa514443e42bf72a145641df635d)contrib mod_rewrite |
| 认证 | 实验环境为已认证的 STOR。若在 USER 或类似命令上配置预认证 RewriteRule,则为 PR:N。 |
| 许可证 | GNU Affero GPL v3.0 |
| 实验环境 | 仅 127.0.0.1 |
RewriteEngine 在配置之前处于关闭状态。文档中给出的模式是 RewriteRule (.*) ${map:$1}。一旦 RewriteRule 将客户端参数送入 int:utf8trans,长度超过 1024 字节的键就会溢出会话子进程中的两个静态缓冲区。
| 方法 | 汇聚点 | 权限 |
|---|---|---|
| FTP 命令,其参数为 utf8trans 映射键,长度 > 1024 | rewrite_utf8_to_ucs4 然后 utf8_val[i] = ucs4_longs[i] | 可用性(实验已证实): 使会话子进程崩溃。ASan:global-buffer-overflow WRITE of size 8,随后 ABORTING。Prefork 模式下:新的登录仍可正常工作;守护进程保持运行。200 个 ASCII 字节的短 STOR 可正常通过。相邻 rewrite BSS 的完整性为推断结论,且取决于编译器布局。 |
| RIP / 代码执行 | 未声称 | 已排除。 无载荷。类别为崩溃。并非 RCE。 |
通过 .ftpaccess 植入 RewriteMap | CONF_DYNDIR | 已排除。 .ftpaccess 中不允许使用 RewriteMap。 |
prg: shell | 无此映射类型 | 已排除。 FIFO 为行 I/O。 |
实验已证实与推断: ASan 大小为 8 的 WRITE、会话子进程中止、短参数对照存活,以及触发后仍可登录,均为实验已证实。未声称 RIP/RCE。
Issue 2173 在此版本上修复了 int:unescape 的单字节越界。本遗留问题属于 int:utf8trans。不同的内置映射。不同的缺陷。
我固定了 proftpd/proftpd 的标签 v1.3.9d。2026 年的 CVE 批次以及仍存在于该 tarball 中的公开 GitHub issue(2170、2173、2175、2180、2095、2256、2286、2319、2330、2301)构成了跳过清单。使用示例 basic.conf 的默认核心 FTP 并未给我带来未公开的严重/高危问题。contrib 的 rewrite 模块则带来了。
rewrite_map_int_utf8trans(contrib/mod_rewrite.c)具有:
static unsigned char utf8_val[PR_TUNABLE_BUFFER_SIZE]; /* 1024 */
static unsigned long ucs4_longs[PR_TUNABLE_BUFFER_SIZE]; /* 1024 */
ucs4strlen = rewrite_utf8_to_ucs4(ucs4_longs, strlen(key), (unsigned char *) key);
rewrite_utf8_to_ucs4 为每个 ASCII 字节写入一个 unsigned long,且没有上限。PR_TUNABLE_CMD_BUFFER_SIZE 为 512 KiB。Issue 2173 已经修复了 unescape。这个映射不在那次修复中。
错误方向:把 2173 当作这个 bug;因为 ASan 报告 WRITE of size 8 就声称 RIP;指望 .ftpaccess 能植入 RewriteMap。第一个是另一个函数。第二个仍然是 Crash。第三个是 CONF_DYNDIR。
ASan 加上原版 libcrypt 会在 PASS 阶段、到达 rewrite 汇聚点之前触发 SIGSEGV。实验环境预加载了一个极小的 crypt(3) 桩,以便登录能够工作。那个桩不是漏洞利用。
python3 proftpd-rewrite-utf8trans-Abraxas-Labs.py
或:
cd lab
./run.sh
回环 127.0.0.1:18740 以及被动端口 18741-18750。Compose 项目 proftpd-rewrite-utf8trans。见证 PROFTPD-REWRITE-UTF8TRANS-WITNESS。镜像为 1.3.9d mod_rewrite 的 ASan 构建。控制 STOR 200 个 ASCII 字节成功。STOR 2048 个 ASCII 字节触发 ASan global-buffer-overflow,WRITE 大小为 8,会话子进程中止。触发后重新登录仍然可用。
SUCCESS PROFTPD-REWRITE-UTF8TRANS asan=global-buffer-overflow write=yes child-dead=yes PROFTPD-REWRITE-UTF8TRANS-WITNESS
将 rewrite_utf8_to_ucs4 的目标长度限制为 PR_TUNABLE_BUFFER_SIZE-1。停止写入超出 ucs4_longs / utf8_val 的位置。拒绝或截断无法容纳的映射键。
f59f248e26bdfa514443e42bf72a145641df635d)contrib/mod_rewrite.c rewrite_utf8_to_ucs4 / rewrite_map_int_utf8transint:unescapeGNU Affero GPL v3.0。参见 LICENSE。仅限回环实验环境。不提供任何担保。