
ProFTPD 1.3.9d - High - Remote - Privilege leftover / File write - SFTP copy-file skips dest WRITE
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · proftpd-sftp-copy-file-write
Class: Privilege leftover / File write Reach: Remote
ProFTPD 1.3.9d (f59f248) - proftpd.org
contrib mod_sftp advertises copy-file once SFTPEngine is on (SFTP_FXP_EXT_DEFAULT). fxp_handle_ext_copy_file runs dest WRITE plus AllowOverwrite only if pr_fsio_stat(dst) succeeds. A dest that does not exist yet skips that check. pr_fs_copy_file2 then creates the file as the session UID, including under <Limit WRITE> DenyAll.
FTP STOR and SFTP OPEN-write still go through xfer_pre_stor, which always dir_checks WRITE before create. Public Issue 2095 is the inverse: SITE COPY skipped source READ. This leftover is dest WRITE on a new name.
| ID | no CVE yet |
| Class | Privilege leftover / File write |
| Reach | Remote (authenticated SFTP) |
| CWE | CWE-863 |
| CVSS | High: 7.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N |
| Product | ProFTPD |
| Affected | 1.3.9d (f59f248e26bdfa514443e42bf72a145641df635d) contrib mod_sftp |
| Auth | authenticated SFTP (SFTPEngine on) |
| License | GNU Affero GPL v3.0 |
| Lab | 127.0.0.1 only |
I pinned tag v1.3.9d and read fxp_handle_ext_copy_file. It dispatches PRE_CMD of a fake SITE COPY. mod_copy registers copy_copy as CMD, not PRE_CMD, so FTP's dest WRITE check never runs on this path. Source READ is always dir_check'd. Dest WRITE is not, unless the dest already exists. The lab is loopback SFTP on 127.0.0.1:18710.
| Method | Sink | Privilege |
|---|---|---|
SFTP EXTENDED copy-file readable src to a dest name that does not exist yet, under <Directory> with <Limit WRITE> DenyAll | pr_fs_copy_file2 | Integrity (lab-proven): create that file as the session UID. Recon (lab-proven): SFTP READ of the dest returns the source bytes when dest READ is allowed. |
| Same dest already exists | dir_check WRITE + AllowOverwrite | Closed (lab-proven): copy-file overwrite returns permission denied. |
| SFTP OPEN / STOR / SCP upload of the same dest | xfer_pre_stor | Closed (lab-proven): OPEN write/create is SSH_FX_PERMISSION_DENIED (status 3). |
| Unauthenticated copy-file | SFTP auth | Closed. No shell. Unix DAC still applies. |
Lab-proven vs inferred: dest create, dest READ of the witness, OPEN-write deny, and existing-dest overwrite deny are lab-proven. Unauth and Unix DAC remain inferred from the auth/chroot model.
Requires: contrib mod_sftp loaded, SFTPEngine on. Typical distro SFTP vhost. SFTPExtensions -copyFile turns the extension off.
cd lab
./run.sh
Loopback 127.0.0.1:18710 maps container 2222. Compose project proftpd-sftp-copy-file-write. Image tag proftpd-sftp-copy-file-write:1.3.9d. Witness PROFTPD-SFTP-COPY-FILE-WRITE-WITNESS. Last line:
SUCCESS PROFTPD-SFTP-COPY-FILE-WRITE dest-exists=yes open-write=denied copy-file=ok overwrite-denied=yes PROFTPD-SFTP-COPY-FILE-WRITE-WITNESS
dir_check dest WRITE even when the dest does not exist yet, before pr_fs_copy_file2. Or disable the extension: SFTPExtensions -copyFile.
f59f248e26bdfa514443e42bf72a145641df635d)fxp_handle_ext_copy_file in contrib/mod_sftp/fxp.cSFTP_FXP_EXT_DEFAULT includes copy-file