The vault door has a mail slot that only accepts empty envelopes
This finding maps to CVE-2017-15906 in sftp-server.c. When sftp-server is launched with the read-only flag (-R), the process_open() function passes the wrong open(2) flags to the kernel, allowing an already-authenticated SFTP user to create zero-length files even though the server claims to be read-only. No file *contents* can be written, no existing file can be truncated with data, and no directory traversal is granted. Affects every OpenSSH release from 5.5 through 7.5; fixed in OpenSSH 7.6 (September 2017) and backported by every mainstream distro shortly after.
Vendor labels it MEDIUM (CVSS 5.3) on the strength of AV:N/AC:L/PR:N. That vector is generous — PR:N is wrong in practice because you must be an authenticated SSH/SFTP user to reach process_open() at all, and the -R flag is a niche deployment mode most sites never enable. Real-world impact is closer to *filesystem clutter* than *integrity compromise*. Vendor severity overstates this by at least one bucket.
4 steps from start to impact.
Authenticate to SSH/SFTP
sftp-server runs after sshd has already authorized the session.- Valid user credentials or SSH key
- Network reachability to port 22
- Requires an existing account — no pre-auth angle
- MFA / bastion / jump host workflows gate most enterprise SSH
sshd auth logs; nothing CVE-specific to detect at this stageLand in a read-only sftp-server session
sftp-server was invoked with the -R (read-only) flag, typically via a forced command in authorized_keys or Match block in sshd_config. If the server is running in normal read/write mode there is no vulnerability — the user can already create files legitimately.sftp-server -Rin force- User's session is constrained to that subsystem
- Read-only SFTP is a minority deployment pattern — most
Subsystem sftplines have no-R - Chrooted upload-only shares are more common and unaffected
sshd_config and authorized_keys for sftp-server -R; audit which sessions actually hit itIssue SSH_FXP_OPEN with SSH_FXF_CREAT
SSH_FXP_OPEN packet with the SSH_FXF_CREAT flag. Due to the wrong open(2) flags, the file is created with size zero. Any subsequent write attempt is still refused, so the file remains empty. Weaponization is a one-liner in paramiko or a raw sftp client.- Write path exists on filesystem the SFTP user can reach
chrootorChrootDirectorystill restricts *where* files can appear- Filesystem quotas cap the impact
auditd watch on the SFTP root) will catch unexpected file creationsImpact: nuisance, at best inode exhaustion
- Follow-on process trusts filename presence without checking size/content
- Almost no production application treats a zero-byte file as authoritative
- Disk-usage and inode monitoring catches spray abuse quickly
The supporting signals.
| CVE | CVE-2017-15906 |
|---|---|
| In-the-wild status | No known exploitation. Not on CISA KEV. No public campaigns reference this bug. |
| Public PoC | Trivial one-liner using paramiko or sftp client — no dedicated exploit repo needed; documented in the OpenSSH commit message |
| EPSS | ~0.05% (bottom decile) — negligible predicted exploitation |
| KEV listing | Not listed |
| CVSS | Vendor 5.3 MEDIUM — CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N. PR:N is misleading — SFTP requires prior SSH auth. |
| Affected versions | OpenSSH 5.5 through 7.5 with sftp-server -R in use |
| Fixed version | OpenSSH 7.6 (2017-10-03). Backported: RHEL7 via RHSA-2018:0980, Debian 4.7p1-1, Ubuntu USN-3809-1, SUSE openssh-7.2p2-74.10.1 |
| Exposure data | Shodan shows ~2M SSH banners advertising OpenSSH <7.6, dominated by legacy RHEL7/CentOS7 with backported fixes — *banner ≠ vulnerable* |
| Disclosure | 2017-10-03 in the OpenSSH 7.6 release announcement; credited to Michal Zalewski (Google) |
noisgate verdict.
Downgraded because the single decisive factor is *impact ceiling*: an authenticated SFTP user can create zero-byte files in a read-only server — no confidentiality loss, no code execution, no privilege escalation. The PR:N in the vendor vector is factually wrong and the affected code path (sftp-server -R) is a minority deployment pattern.
Why this verdict
- Auth required, not
PR:N. The bug lives insidesftp-server, which never runs untilsshdhas completed authentication. The CVSS vector'sPR:Nis analytically wrong. - Niche precondition. The vulnerable code path only fires when
sftp-serverwas launched with-R. The defaultSubsystem sftp /usr/lib/openssh/sftp-serverline has no-R, so most enterprise fleets are simply not vulnerable regardless of banner version. - Impact ceiling is zero-byte file creation. No write, no read, no exec, no escalation. Worst realistic abuse is inode exhaustion — a capacity problem, not a security incident.
- Role multiplier — general Linux server / jump host: Chain succeeds only in creating empty files inside the user's SFTP chroot. Blast radius = the SFTP share. No lateral movement.
- Role multiplier — file-transfer gateway (MFT / vendor drop-box): Chain succeeds where
-Ris used to enforce download-only distribution. Blast radius = adversary can plant empty filenames that might collide with expected artifacts. Still no data compromise; degrades to an integrity nuisance that any downstream checksum validation catches. - Role multiplier — bastion / identity plane / hypervisor management: These do not expose
sftp-server -Rat all. No amplification. - Banner-based finding. Tenable 103781 relies on the SSH banner and does *not* verify the backport patch level. On RHEL7/CentOS7/Ubuntu 16.04/18.04 the banner still reads pre-7.6 while the actual binary is patched — a huge fraction of these findings are false positives.
Why not higher?
MEDIUM would require either a realistic path to data or code impact, or a common default deployment pattern. Neither holds — the bug caps at empty-file creation and requires the non-default -R flag plus an authenticated session. There is no KEV listing, no EPSS signal, and no known exploitation.
Why not lower?
IGNORE would be wrong for two reasons: (1) on an actual unpatched sftp-server -R file-transfer gateway there is a genuine integrity-nuisance angle that a compliance auditor will flag, and (2) the fix is trivial — a package upgrade — so leaving a known-buggy sshd in the fleet is bad hygiene even if the risk is minimal.
What to do — in priority order.
- Verify backport status before touching anything — On RHEL/CentOS/Ubuntu/SUSE the banner lies. Run
rpm -q --changelog openssh-server | grep -i CVE-2017-15906(RPM) orapt changelog openssh-server | grep -i 15906(Debian/Ubuntu). If the distro fix is already in, close the ticket as false positive. This is the single highest-leverage action and should be your first pass — no SLA needed, it's a data-quality fix. - Inventory
sftp-server -Rusage — Grep/etc/ssh/sshd_config, allsshd_config.d/*fragments, and~/.ssh/authorized_keys(all users) forsftp-server -Rorinternal-sftp -R. Only these hosts are actually exposed. This is MEDIUM verdict = no mitigation SLA; fold into the 365-day remediation window. - Upgrade OpenSSH to a patched build — For the true-positive hosts, apply the vendor package update or bump to OpenSSH 7.6+. LOW verdict = no mitigation SLA; treat as backlog hygiene inside the standard patch cadence.
- Enable filesystem quotas + inode monitoring on SFTP chroots — Blocks the only realistic abuse pattern (inode exhaustion via empty-file spray). Cheap, generic, useful regardless of this CVE.
- Blocking port 22 at the perimeter — irrelevant; the bug requires *authenticated* SFTP, which by definition means the user is already inside SSH.
- Forcing key-based auth / disabling passwords — does not change the outcome. A legitimate key-authenticated user is exactly who triggers this bug.
- Adding
ChrootDirectory— helpful hygiene but doesn't fix the flag bug; the user can still create empty files inside the chroot. - IDS/IPS signatures — the SFTP protocol traffic is inside the encrypted SSH channel; no in-line inspection is possible.
Crowdsourced verification payload.
Run on the target Linux host as root (or with sudo). Invoke as sudo bash check_cve_2017_15906.sh. The script checks both the OpenSSH version *and* whether sftp-server -R is actually configured, because a banner-only check produces massive false-positive rates on distro-backported builds.
#!/usr/bin/env bash
# check_cve_2017_15906.sh — CVE-2017-15906 / OpenSSH < 7.6 sftp-server -R zero-byte file creation
# Exit codes: 0 PATCHED, 1 VULNERABLE, 2 UNKNOWN
set -u
verdict() { echo "$1"; exit "$2"; }
SSHD=$(command -v sshd || echo /usr/sbin/sshd)
if [ ! -x "$SSHD" ]; then
verdict "UNKNOWN: sshd binary not found" 2
fi
VER_RAW=$($SSHD -V 2>&1 | head -n1)
VER=$(echo "$VER_RAW" | grep -oE 'OpenSSH_[0-9]+\.[0-9]+' | head -n1 | sed 's/OpenSSH_//')
if [ -z "$VER" ]; then
verdict "UNKNOWN: could not parse OpenSSH version from: $VER_RAW" 2
fi
MAJOR=${VER%%.*}
MINOR=${VER##*.}
# Version >= 7.6 means upstream-patched
UPSTREAM_FIXED=1
if [ "$MAJOR" -lt 7 ]; then UPSTREAM_FIXED=0; fi
if [ "$MAJOR" -eq 7 ] && [ "$MINOR" -lt 6 ]; then UPSTREAM_FIXED=0; fi
# Check distro backport if pre-7.6 banner
BACKPORTED=0
if [ "$UPSTREAM_FIXED" -eq 0 ]; then
if command -v rpm >/dev/null 2>&1; then
if rpm -q --changelog openssh-server 2>/dev/null | grep -qi 'CVE-2017-15906'; then
BACKPORTED=1
fi
elif command -v dpkg >/dev/null 2>&1; then
if zgrep -qi 'CVE-2017-15906' /usr/share/doc/openssh-server/changelog* 2>/dev/null; then
BACKPORTED=1
fi
fi
fi
# Check whether -R is actually configured anywhere
USES_R=0
for f in /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf; do
[ -r "$f" ] || continue
if grep -Eq '(sftp-server|internal-sftp)[[:space:]]+-R' "$f"; then USES_R=1; fi
done
for akf in /root/.ssh/authorized_keys /home/*/.ssh/authorized_keys; do
[ -r "$akf" ] || continue
if grep -Eq '(sftp-server|internal-sftp)[[:space:]]+-R' "$akf"; then USES_R=1; fi
done
if [ "$UPSTREAM_FIXED" -eq 1 ] || [ "$BACKPORTED" -eq 1 ]; then
verdict "PATCHED: OpenSSH $VER (upstream_fixed=$UPSTREAM_FIXED backport=$BACKPORTED)" 0
fi
if [ "$USES_R" -eq 0 ]; then
verdict "PATCHED (not exploitable): OpenSSH $VER is pre-7.6 but sftp-server -R is not configured" 0
fi
verdict "VULNERABLE: OpenSSH $VER < 7.6, no backport detected, and sftp-server -R is configured" 1
If you remember one thing.
sftp-server -R (a minority deployment); everything else is not exploitable. Third, fold the genuine true positives into your standard OpenSSH patch cadence. Per the noisgate mitigation SLA for LOW: *no mitigation SLA* — this is backlog hygiene, not an incident. Per the noisgate remediation SLA for LOW: patch on your normal maintenance window, no fire drill needed. If your tooling can suppress banner-only pre-7.6 findings on distros that backport, do that now and reclaim the analyst hours.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.