FlawOpen

flawopen.com/Teardowns/cve-2015-3306-proftpd-mod-copy-unauthenticated-file-copy

● CVE-2015-3306 · CVSS 10.0 · 严重
安全研究 · FlawOpen

CVE-2015-3306:ProFTPD mod_copy 未认证文件复制漏洞

CVE-2015-3306 允许未认证客户端使用 ProFTPD mod_copy 命令在服务器上复制文件。上游修复在 SITE CPFR 和 SITE CPTO 两个处理程序中检查认证状态;CISA 于 2026-10-08 将该漏洞加入 KEV。 FBI、CISA、NSA及合作机构于2026年10月8日发布的联合公告,将CVE-2015-3306列入从MicroScan脚本中恢复出的成功利用CVE清单;公告未指出该CVE对应的受害者或事件日期。[1], [2], [5], [6]

💡 通俗易懂的原理解析 (ELI5)

想象档案室员工接受任何人的两种要求:“复制这个文件”和“把副本放到这里”。只检查其中一个请求还不够;源文件和目标位置两个步骤都必须属于已认证会话。若门口没有核对身份,任何来访者都可能让员工在其权限范围内移动文件。[3]

核心概念与专有名词

SITE CPFR / SITE CPTO
ProFTPD mod_copy 命令,用于选择服务器端文件复制的源和目标。[3], [5]
mod_copy
ProFTPD 的可选模块,提供服务器端文件复制命令。[3], [5]
CWE-284
访问控制不当:未满足策略要求的授权即可访问受保护操作。[1]

框架映射

根本原因剖析 (Root Cause)

在受影响的 ProFTPD 1.3.5 部署中,如果 mod_copy 可用且已启用,copy_cpfr() 和 copy_cpto() 会接受 SITE CPFR/SITE CPTO 命令路径,而不要求会话已认证。上游 PR #109 在两个处理程序中都加入认证状态检查,并在进行基本命令分派检查之后、验证最少参数数量以及处理源/目标路径和执行复制之前进行检查;未认证时返回 FTP 530 / EPERM。该模块仍受 ProFTPD 进程的操作系统权限限制,因此文件影响取决于这些权限和具体配置。Debian 将任意代码执行描述为“可能”,而非必然;还需要部署特定条件,例如可写路径随后被应用程序当作代码处理。[3], [5], [4]

运维矩阵:暴露条件与修复包核验

部署状态来源确认的情况防护措施
ProFTPD 1.3.5,mod_copy 可用且已启用Ubuntu 记录说明可通过 SITE CPFR 和 SITE CPTO 远程读写文件;NVD 将 ProFTPD 1.3.5 列为受影响版本。核实确切的软件包构建、模块加载状态和命令暴露情况;升级到发行版提供的修复包。
上游修复:PR #109 / commit 35b65aa补丁在复制操作前为 copy_cpfr() 和 copy_cpto() 都加入了身份验证检查。确认两个命令都会拒绝未认证会话;将文件系统权限作为单独的安全边界评估。
Debian wheezy / jessie / stretch 与 sidDebian 分别在 1.3.4a-5+deb7u3、1.3.5-1.1+deb8u1 和 1.3.5-2 修复了这些分支。将已安装的 Debian 软件包修订版与对应修复版本比较;不要只依赖上游版本号。
支持 CopyEngine offPR #109 添加了此指令;模块文档注明从 1.3.6rc1 开始兼容。若安装版本支持且不需要此功能,可使用 CopyEngine off;否则移除模块或升级。

攻击执行流程分解

步骤 1

未认证会话到达 mod_copy

当受影响模块存在且复制命令对外可用时,系统会受到影响。[5], [1]

步骤 2

复制命令缺少认证门槛

修复前,CPFR 和 CPTO 可以在不检查会话认证状态的情况下继续。[3]

步骤 3

服务器在自身权限范围内复制

请求可能暴露或修改服务账户可访问的文件;代码执行还取决于其他条件。[5], [4]

步骤 4

补丁保护两个操作

上游更改在每个处理程序的复制逻辑之前返回认证错误。[3]

源代码对比:漏洞与安全实现

易受攻击的代码片段中,copy_cpfr() 缺少认证检查;加固后的片段在参数检查和状态更改之前加入上游会话状态校验。PR #109 也为 copy_cpto() 添加了相同保护。这是源代码片段,不是独立程序。[3]

存在漏洞的实现
/* copy_cpfr() 在上游 PR #109 之前的精简片段。 */
if (cmd->argc < 3 ||
    strncasecmp(cmd->argv[1], "CPFR", 5) != 0) {
    return PR_DECLINED(cmd);
}
CHECK_CMD_MIN_ARGS(cmd, 3);
/* 源路径处理会在未进行身份验证的情况下继续。 */
加固后的安全修复
/* copy_cpfr() 上游修复(PR #109)的精简片段。 */
unsigned char *authenticated = NULL;
if (cmd->argc < 3 ||
    strncasecmp(cmd->argv[1], "CPFR", 5) != 0) {
    return PR_DECLINED(cmd);
}
authenticated = get_param_ptr(cmd->server->conf, "authenticated", FALSE);
if (authenticated == NULL || *authenticated == FALSE) {
    pr_response_add_err(R_530, _("Please login with USER and PASS"));
    pr_cmd_set_errno(cmd, EPERM);
    errno = EPERM;
    return PR_ERROR(cmd);
}
CHECK_CMD_MIN_ARGS(cmd, 3);

工程与系统安全加固清单

参考来源