← Back to Feed CACHED · 2026-07-13 09:14:25 · CACHE_KEY tenable:103781
tenable:103781 · CWE-732 · Disclosed 2017-10-03

OpenSSH < 7

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
Do you agree?
01 · The Real Story

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.

"Authenticated SFTP user can touch zero-byte files in read-only mode. That's it. No RCE, no data theft, no privilege gain."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Authenticate to SSH/SFTP

Attacker must present valid credentials or a valid key and complete SSH authentication. Anonymous SFTP is not in scope — sftp-server runs after sshd has already authorized the session.
Conditions required:
  • Valid user credentials or SSH key
  • Network reachability to port 22
Where this breaks in practice:
  • Requires an existing account — no pre-auth angle
  • MFA / bastion / jump host workflows gate most enterprise SSH
Detection/coverage: Standard sshd auth logs; nothing CVE-specific to detect at this stage
STEP 02

Land in a read-only sftp-server session

The bug only triggers when 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.
Conditions required:
  • sftp-server -R in force
  • User's session is constrained to that subsystem
Where this breaks in practice:
  • Read-only SFTP is a minority deployment pattern — most Subsystem sftp lines have no -R
  • Chrooted upload-only shares are more common and unaffected
Detection/coverage: Grep sshd_config and authorized_keys for sftp-server -R; audit which sessions actually hit it
STEP 03

Issue SSH_FXP_OPEN with SSH_FXF_CREAT

Attacker sends an 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.
Conditions required:
  • Write path exists on filesystem the SFTP user can reach
Where this breaks in practice:
  • chroot or ChrootDirectory still restricts *where* files can appear
  • Filesystem quotas cap the impact
Detection/coverage: Filesystem auditing (auditd watch on the SFTP root) will catch unexpected file creations
STEP 04

Impact: nuisance, at best inode exhaustion

The attacker cannot write data, cannot overwrite existing content, cannot escalate, cannot pivot. The only realistic abuse is scripting millions of empty-file creations to burn inodes on a small filesystem or to plant a decoy filename that another process might trust by existence alone (rare). No confidentiality loss.
Conditions required:
  • Follow-on process trusts filename presence without checking size/content
Where this breaks in practice:
  • Almost no production application treats a zero-byte file as authoritative
  • Disk-usage and inode monitoring catches spray abuse quickly
Detection/coverage: Capacity/inode alerts in any competent monitoring stack
03 · Intelligence Metadata

The supporting signals.

CVECVE-2017-15906
In-the-wild statusNo known exploitation. Not on CISA KEV. No public campaigns reference this bug.
Public PoCTrivial 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 listingNot listed
CVSSVendor 5.3 MEDIUMCVSS: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 versionsOpenSSH 5.5 through 7.5 with sftp-server -R in use
Fixed versionOpenSSH 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 dataShodan shows ~2M SSH banners advertising OpenSSH <7.6, dominated by legacy RHEL7/CentOS7 with backported fixes — *banner ≠ vulnerable*
Disclosure2017-10-03 in the OpenSSH 7.6 release announcement; credited to Michal Zalewski (Google)
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to LOW (3.1/10)

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.

HIGH Technical impact assessment (root-caused in the OpenSSH commit)
HIGH Distro backport coverage — most flagged hosts are already patched
MEDIUM Installed-base share of hosts actually running `sftp-server -R`

Why this verdict

  • Auth required, not PR:N. The bug lives inside sftp-server, which never runs until sshd has completed authentication. The CVSS vector's PR:N is analytically wrong.
  • Niche precondition. The vulnerable code path only fires when sftp-server was launched with -R. The default Subsystem sftp /usr/lib/openssh/sftp-server line 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 -R is 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 -R at 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.

05 · Compensating Control

What to do — in priority order.

  1. 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) or apt 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.
  2. Inventory sftp-server -R usage — Grep /etc/ssh/sshd_config, all sshd_config.d/* fragments, and ~/.ssh/authorized_keys (all users) for sftp-server -R or internal-sftp -R. Only these hosts are actually exposed. This is MEDIUM verdict = no mitigation SLA; fold into the 365-day remediation window.
  3. 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.
  4. 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.
What doesn't work
  • 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.
06 · Verification

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.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/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
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning: do not rush to touch this. First, dedupe your Tenable 103781 output against distro backport status — on RHEL7/CentOS7/Ubuntu 16.04/18.04 the majority of these findings are false positives because the banner still reads pre-7.6 while the backport is applied. Second, filter the remaining hosts to those that actually run 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

  1. Tenable plugin 103781
  2. OpenSSH 7.6 release notes
  3. NVD — CVE-2017-15906
  4. Red Hat advisory RHSA-2018:0980
  5. Ubuntu USN-3809-1 (openssh)
  6. Debian security tracker CVE-2017-15906
  7. OpenSSH upstream commit (a6981567e8e2)
  8. FIRST EPSS API — CVE-2017-15906
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.