abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · vsftpd-ssl-data-any-ticket
类别: 权限残留 可达性: 远程
vsftpd 3.0.5(Chris Evans)—— 官方 tarball SHA-256 26b602ae454b0ba6d99ef44a09b6b9e0dfa7f67228106736df1f278c70bc91d3。发行版 FTPS 编译时启用 #define VSF_BUILD_SSL(原版 tarball 为 #undef),运维人员设置 ssl_enable=YES。独立模式 listen=YES 是编译时和示例的默认值。
ssl_accept(ssl.c:494-501)是数据通道的绑定点。它只检查 SSL_session_reused()。没有与控制通道 SSL 进行 SSL_SESSION 比较。数据 SSL 没有 FTP USER/PASS。独立模式 ssl_init 在 fork 之前于监听器中运行(main.c:147-150),因此子进程继承同一个 SSL_CTX。SSL_CTX_set_timeout(INT_MAX)(ssl.c:182-186)。没有 SSL_OP_NO_TICKET。SSL_session_reused()==1 意味着此 ClientHello 携带了本进程能解密的 ticket,而不是说它是 Alice 的控制会话。
require_ssl_reuse 的手册页说,复用证明与主控通道拥有相同的 master secret。但 C 代码并非如此。这与 3.0.3 中 Tim Kosse 的复用失败即终止(ftpdataio.c:184-187)不同,后者仍会对全新握手返回 522,且无法阻止 Mallory 恢复一个在不同控制通道上签发的 ticket。
此残留仅涉及一次 FTPS 传输。它不是 USER/PASS 跳过,不是 shell,也不是 chroot 逃逸。
| ID | 暂无 CVE |
| 类别 | 权限残留(FTPS 数据通道接受任意恢复的 ticket) |
| 可达性 | 远程(同 IP PASV;共享 NAT 为 AC:H) |
| CWE | CWE-345, CWE-287 |
| CVSS | 高危:7.4 CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N |
| 产品 | vsftpd(Chris Evans) |
| 受影响版本 | 3.0.5,启用 VSF_BUILD_SSL 且 ssl_enable=YES。require_ssl_reuse=YES(默认)。require_cert=NO(默认) |
| 认证 | Mallory:仅 AUTH TLS(无 USER/PASS)。Alice:匿名 PBSZ/PROT P |
| 许可证 | GNU Affero GPL v3.0 |
| 实验环境 | 127.0.0.1:18700 控制通道,PASV 18701-18708。Compose vsftpd-ssl-data-any-ticket |
谁:另一个 FTPS 客户端(或路径上的攻击者),与 Alice 共享源 IP。PASV accept 仍要求控制对端 IP(privops.c:212-218),除非设置 pasv_promiscuous。共享 NAT 是 FTPS 的常见场景,require_ssl_reuse 正是为此而添加。Mallory 从不登录。
| 方法 + 目标 | 权限 |
|---|---|
Mallory 仅 AUTH TLS,TLS 1.2 ALPN ftp,保留来自监听器 SSL_CTX 的会话 ticket。Alice 匿名 PBSZ/PROT P、PASV、RETR secret.txt 在 get_remote_transfer_fd 中阻塞等待 accept。Mallory 同 IP PASV,恢复他的 ticket(session_reused=True) | 解密那一次 RETR。实验:数据套接字 35 字节 VSFTPD-SSL-DATA-ANY-TICKET-WITNESS。Alice 收到 150 然后 226。控制通道 TLS 和密码仍属于 Alice。除该次传输外无目录遍历。 |
ssl_accept 门控推断;实验为 RETR 窃取)| 方法 + 目标 | 权限 |
|---|---|
在 Alice STOR / APPE 期间恢复同一 ticket | Alice 指定的文件被 Mallory 的 TLS 明文写入,以 Alice 的 uid / 匿名 ftp uid 身份,在现有 chroot 内 |
| 方法 + 目标 | 权限 |
|---|---|
全新数据握手(reused=False) | 522 session reuse required(3.0.3 终止)。该传输失败。控制通道仍属于 Alice |
privops.c:212-218)require_cert=YES 加上出示的证书会绑定 SHA-256 摘要PROT C(force_local_data_ssl 默认 YES)ssl_init 继承)ftp 外的 ALPN(vsftpd 会 FATAL)我固定使用官方 vsftpd 3.0.5 tarball,而非 GitHub 镜像或 Debian/Fedora 源码树。进行了十九次源码搜寻。SSL 搜寻在 ssl_accept 处停止:复用是一个布尔值,而非绑定到此控制通道 SSL_SESSION。监听器 SSL_CTX 加上 INT_MAX 的 ticket 生命周期是其余部分。
弯路:ALPN 必须是 ftp,否则 vsftpd 会 FATAL(3.0.4 的 ALPACA 残留已被关闭)。Arm64 链接需要显式 -lpam -lcap;原版 vsf_findlibs.sh 只探测 x86_64 路径。将 3.0.3 的 Tim Kosse 终止视为本漏洞:它会对 Alice 数据 fd 上的全新握手返回 522,且无法阻止在不同控制通道上签发的 ticket。
cd lab
./run.sh
官方 3.0.5 启用 #define VSF_BUILD_SSL。配置:ssl_enable=YES、allow_anon_ssl=YES、force_anon_logins_ssl=YES、force_anon_data_ssl=YES、require_ssl_reuse=YES、require_cert=NO。回环 Docker。两个同 IP 客户端。TLS 1.2 ticket。ALPN ftp。控制通道 127.0.0.1:18700,PASV 18701-18708。Compose vsftpd-ssl-data-any-ticket。见证 VSFTPD-SSL-DATA-ANY-TICKET-WITNESS。最后一行:
SUCCESS vsftpd-ssl-data-any-ticket reused-ticket=yes fresh-handshake=522 VSFTPD-SSL-DATA-ANY-TICKET-WITNESS
将数据通道 SSL_SESSION 绑定到控制通道 SSL_SESSION(比较会话 ID / master secret)。将 ticket 生命周期限制为控制连接的生命周期。或者使用 SSL_OP_NO_TICKET 加上以控制通道为键的会话缓存。ProFTPD 1.3.9d 会比较会话。
厂商接收邮箱为 [email protected](security.appspot.com/vsftpd.html)。请勿在任何 vsftpd 镜像上公开提交 GitHub issue。
Abraxas Labs - abraxaslabs.tech - github.com/abraxas - @abraxas_null - [email protected]